Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions fp-plugins/mastodon/developer-docs/00-Mental-Model.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ It maps FlatPress objects to Mastodon objects:
| FlatPress tags | Hashtag footer / imported `[tag]` BBCode | Requires the FlatPress Tag companion plugin for tag storage/rendering. |
| Local delete | Remote delete or tombstone/recheck | Deletion sync reconciles missing local and remote objects later. |

Media export has one additional compatibility rule that developers must keep in mind: one Mastodon status may carry multiple images, or exactly one audio/video attachment, but not a mixed audio/video/image set. The plugin therefore collects all local media for change detection and diagnostics, then selects one exportable media family per status before upload: images first, otherwise one audio item, otherwise one video item with its poster sent only as an upload thumbnail.

```mermaid
flowchart LR
FP[FlatPress entries comments media tags]
Expand Down
38 changes: 24 additions & 14 deletions fp-plugins/mastodon/developer-docs/01-Process-Map.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,20 +42,20 @@ flowchart TD

## Process catalog

| ID | Process | Trigger | Core behavior | Primary state | Regression focus |
| --- | ----------------------------------- | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ | -------------------------------------------------------------------- |
| P1 | Scheduled content sync | Frontend `init` hook via `plugin_mastodon_maybe_sync()` | Reads compact scheduler-state first; may call `plugin_mastodon_run_sync(false)`. | scheduler-state.json, sync.guard.json, sync.lock, state.json | Simulation scheduler, cooldown, compact-state and large-state tests. |
| P2 | Manual content sync | Admin actions in `plugin_mastodon_admin_assign()` | Calls `plugin_mastodon_run_sync(true, ...)` and bypasses due window; still respects lock and budgets. | state.json, sync.lock, rate-limit-windows.json | Manual normal/full synchronization tests. |
| P3 | Remote top-level status import | Content sync when `update_local_from_remote` is enabled | Verifies account, pages statuses, filters, converts HTML/media/tags, saves FlatPress entries. | entries, entries_remote, last_remote_status_id, content_stats | Remote import and content-window tests. |
| P4 | Remote reply import | Remote context pass for known imported/exported threads | Fetches context descendants, resolves parent comments, queues rechecks or tombstones. | comments, comments_remote, comment_tombstones, pending_comment_remote_rechecks | Reply tree, self-reply, quote, comment-as-entry tests. |
| P5 | Local entry export/update | Dirty entry or local candidate in manual/full sync | Builds status text, validates media, creates or edits Mastodon status, writes mappings. | dirty_entries, entries, entries_remote, media signatures, content_stats | Local export, URL-budget, media reuse and update tests. |
| P6 | Local comment export/update | Dirty comment or local candidate under a mapped entry/comment | Resolves reply target, builds reply text, creates/edits Mastodon reply, handles pending parents. | dirty_comments, comments, comments_remote, pending flags | Comment export, nested reply and pending parent tests. |
| P7 | Media export | Local entry export/update | Collects image/gallery/audio/video BBCode media, validates against instance limits, uploads/polls/reuses/cleans up. | entry media metadata, rate-limit-windows.json | Media upload, AudioVideo, thumbnail, processing and cleanup tests. |
| P8 | Media import | Remote status/reply import | Downloads media via URL fallback order and builds FlatPress BBCode or AudioVideo tags. | imported entry/comment content, media files, captions | Remote media import tests. |
| P9 | Deletion sync | Scheduled follow-up or admin action | Processes local missing mapped items and remote missing statuses; uses status delete fallback for pre-4.4 servers. | deletions_pending, deletion cursors, tombstones, rechecks, deletion_stats | Deletion sync, legacy delete_media fallback and tombstone tests. |
| P10 | Dirty tracking hooks | FlatPress post-success hooks | Marks local changes unless a plugin-owned remote import/write guard is active. | dirty_entries, dirty_comments, deletions_pending | Dirty tracking, remote-write guard and deletion tests. |
| P11 | OAuth and instance capability setup | Admin registration/authorize/verify or first capability query | Registers app, discovers scopes, exchanges token, caches compact instance document. | options, instance_info_json, oauth_registered_scopes | OAuth, scope discovery, instance cache tests. |
| P12 | Admin diagnostics | Opening plugin admin panel | Reads options, state summaries, companion-plugin status, stats and manual-action results. | options, scheduler-state.json, state.json, sync.log | Admin assignment and diagnostics tests. |
| ID | Process | Trigger | Core behavior | Primary state | Regression focus |
| --- | ----------------------------------- | ------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------ |
| P1 | Scheduled content sync | Frontend `init` hook via `plugin_mastodon_maybe_sync()` | Reads compact scheduler-state first; may call `plugin_mastodon_run_sync(false)`. | scheduler-state.json, sync.guard.json, sync.lock, state.json | Simulation scheduler, cooldown, compact-state and large-state tests. |
| P2 | Manual content sync | Admin actions in `plugin_mastodon_admin_assign()` | Calls `plugin_mastodon_run_sync(true, ...)` and bypasses due window; still respects lock and budgets. | state.json, sync.lock, rate-limit-windows.json | Manual normal/full synchronization tests. |
| P3 | Remote top-level status import | Content sync when `update_local_from_remote` is enabled | Verifies account, pages statuses, filters, converts HTML/media/tags, saves FlatPress entries. | entries, entries_remote, last_remote_status_id, content_stats | Remote import and content-window tests. |
| P4 | Remote reply import | Remote context pass for known imported/exported threads | Fetches context descendants, resolves parent comments, queues rechecks or tombstones. | comments, comments_remote, comment_tombstones, pending_comment_remote_rechecks | Reply tree, self-reply, quote, comment-as-entry tests. |
| P5 | Local entry export/update | Dirty entry or local candidate in manual/full sync | Builds status text, validates media, creates or edits Mastodon status, writes mappings. | dirty_entries, entries, entries_remote, media signatures, content_stats | Local export, URL-budget, media reuse and update tests. |
| P6 | Local comment export/update | Dirty comment or local candidate under a mapped entry/comment | Resolves reply target, builds reply text, creates/edits Mastodon reply, handles pending parents. | dirty_comments, comments, comments_remote, pending flags | Comment export, nested reply and pending parent tests. |
| P7 | Media export | Local entry export/update | Collects image/gallery/audio/video BBCode media, validates files, selects one Mastodon-compatible media family, uploads/polls/reuses/cleans up. | entry media metadata, rate-limit-windows.json | Media upload, AudioVideo, media-family selection, thumbnail, processing and cleanup tests. |
| P8 | Media import | Remote status/reply import | Downloads media via URL fallback order and builds FlatPress BBCode or AudioVideo tags. | imported entry/comment content, media files, captions | Remote media import tests. |
| P9 | Deletion sync | Scheduled follow-up or admin action | Processes local missing mapped items and remote missing statuses; uses status delete fallback for pre-4.4 servers. | deletions_pending, deletion cursors, tombstones, rechecks, deletion_stats | Deletion sync, legacy delete_media fallback and tombstone tests. |
| P10 | Dirty tracking hooks | FlatPress post-success hooks | Marks local changes unless a plugin-owned remote import/write guard is active. | dirty_entries, dirty_comments, deletions_pending | Dirty tracking, remote-write guard and deletion tests. |
| P11 | OAuth and instance capability setup | Admin registration/authorize/verify or first capability query | Registers app, discovers scopes, exchanges token, caches compact instance document. | options, instance_info_json, oauth_registered_scopes | OAuth, scope discovery, instance cache tests. |
| P12 | Admin diagnostics | Opening plugin admin panel | Reads options, state summaries, companion-plugin status, stats and manual-action results. | options, scheduler-state.json, state.json, sync.log | Admin assignment and diagnostics tests. |

## P1/P2 — Scheduled and manual content synchronization

Expand Down Expand Up @@ -153,6 +153,16 @@ flowchart TD

The media plan is one of the most important extension points. It compares attachment signatures and description signatures. If attachments did not change, the plugin can reuse remote media IDs. If only descriptions changed and the instance supports status `media_attributes`, it updates alt text without re-uploading. Otherwise it re-uploads.

Before the media plan computes signatures or uploads anything, it applies the Mastodon status media-family policy:

```text
if images exist: export images only, up to the instance image/media limit
else if audio exists: export exactly one audio attachment
else if video exists: export exactly one video attachment, with poster as thumbnail only
```

This policy belongs in the export planner, not in the raw collector. The collector still finds images, galleries, audio and video so diagnostics and change detection remain transparent. The planner then reduces the collected set to the one media family Mastodon will accept for a single status.

## P9 — Deletion synchronization

```mermaid
Expand Down
20 changes: 11 additions & 9 deletions fp-plugins/mastodon/developer-docs/02-State-Model.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,15 +67,17 @@ flowchart TD

A mapped entry typically carries:

| Key | Meaning |
|-------------------------------|------------------------------------------------------------------|
| `remote_id` | Mastodon status ID for the local entry. |
| `hash` | Content hash used to skip unchanged local entries. |
| `date_key` / timestamps | Used for sync window decisions. |
| `remote_media` | Stored remote media descriptors for reuse and cleanup decisions. |
| `media_attachment_signature` | Signature of local media files/paths/types. |
| `media_description_signature` | Signature of local media descriptions/alt text. |
| `remote_source` flags | Indicates whether a local entry originated from Mastodon. |
| Key | Meaning |
|-------------------------------|-------------------------------------------------------------------------------------------------------------------|
| `remote_id` | Mastodon status ID for the local entry. |
| `hash` | Content hash used to skip unchanged local entries. |
| `date_key` / timestamps | Used for sync window decisions. |
| `remote_media` | Stored remote media descriptors for the effective Mastodon media selection, used for reuse and cleanup decisions. |
| `media_attachment_signature` | Signature of the selected local status media files/paths/types, not every media tag found in the FlatPress entry. |
| `media_description_signature` | Signature of descriptions/alt text for the selected status media set. |
| `remote_source` flags | Indicates whether a local entry originated from Mastodon. |

The media signatures are computed after `plugin_mastodon_select_status_media_items()` has reduced the collected media to one Mastodon-compatible family. For example, if an entry contains images, audio, and video, only the selected image set contributes to the stored media signatures and remote media descriptors. The raw FlatPress content hash still includes the content itself, so ignored media changes can still make the entry dirty, but they do not force an invalid mixed-media Mastodon status.

### Comment metadata in `comments`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ This matrix links implementation functions to the process map. It is intentional
| plugin_mastodon_delete_status | P9/API | Deletes a Mastodon status. | instance_info_json via capability helper | Adds or omits `delete_media`; retries without it for legacy failures. | delete_media fallback tests |
| plugin_mastodon_instance_supports_status_delete_media | P9/API | Capability check for the delete_media parameter. | Cached/stored `/api/v2/instance` version only | Returns true/false/null. | Version-specific delete tests |
| plugin_mastodon_instance_supports_status_media_attributes | P5/P7/API | Capability check for media alt-text update in status edit. | Instance version | Controls reuse+media_attributes vs re-upload. | Media reuse/update tests |
| plugin_mastodon_prepare_entry_media_sync_plan | P5/P7 | Decides none/upload/reuse for local entry media. | Entry media signatures and remote media metadata | May prepare `media_attributes`. | Media signature/reuse tests |
| plugin_mastodon_prepare_entry_media_sync_plan | P5/P7 | Decides none/upload/reuse for the selected local entry media. | Entry media signatures and remote media metadata | Calls media-family selection before comparing signatures. | Media signature/reuse tests |
| plugin_mastodon_select_status_media_items | P7 | Applies Mastodon media-family policy before signatures/uploads. | Selected local media set; skipped-media diagnostics | Chooses images first, otherwise one audio, otherwise one video. | Media-family selection tests |
| plugin_mastodon_upload_media_items | P7/API | Uploads media through `/api/v2/media` and polls if necessary. | rate-limit window, instance limits | Returns media IDs or failure details. | Upload/processing tests |
| plugin_mastodon_cleanup_uploaded_media | P7/API | Deletes uploaded but unattached media after post/update failure. | media IDs from current run | Calls `DELETE /api/v1/media/:id`. | Cleanup tests |
| plugin_mastodon_collect_local_entry_media | P7 | Extracts images/galleries/audio/video from FlatPress content. | FlatPress entry body and companion plugin formats | Builds candidate local media descriptors. | Local media extraction tests |
Expand Down
Loading
Loading