diff options
Diffstat (limited to 'packages/meshbay-common')
| -rw-r--r-- | packages/meshbay-common/src/meshbay_common/__init__.py | 8 | ||||
| -rw-r--r-- | packages/meshbay-common/src/meshbay_common/adminop.py | 5 | ||||
| -rw-r--r-- | packages/meshbay-common/src/meshbay_common/protocol.py | 12 |
3 files changed, 22 insertions, 3 deletions
diff --git a/packages/meshbay-common/src/meshbay_common/__init__.py b/packages/meshbay-common/src/meshbay_common/__init__.py index b37de8e..0ca0005 100644 --- a/packages/meshbay-common/src/meshbay_common/__init__.py +++ b/packages/meshbay-common/src/meshbay_common/__init__.py @@ -43,5 +43,11 @@ __version__ = "0.7.0" # wrong, and Music now requires one before showing/enriching anything, # exactly like Videos. Additive at the protocol level: an older client # never sends the op and never expects the field. -MNP_VERSION = "0.10" +# 0.11: added `taken_at`/`camera` to `IndexEntry` (best-effort, from a photo's +# own EXIF block) and `photo_roots`/`photo_roots_ack`, for the Photos group +# app (docs/photos.md). Unlike `video_root`/`audio_root`, `photo_roots` is a +# *set*, replaced whole in one signed op — a photo library is routinely +# scattered across several folders, not one. Additive: an older client +# never sends the op and never expects either field. +MNP_VERSION = "0.11" MHP_VERSION = "0.1" diff --git a/packages/meshbay-common/src/meshbay_common/adminop.py b/packages/meshbay-common/src/meshbay_common/adminop.py index d09b95e..19dfe8e 100644 --- a/packages/meshbay-common/src/meshbay_common/adminop.py +++ b/packages/meshbay-common/src/meshbay_common/adminop.py @@ -96,6 +96,11 @@ OP_MUSICBRAINZ_ENABLED = "musicbrainz_enabled" # OP_VIDEO_ROOT above, added later once a real messy library showed the # "no root, whole shared tree" simplification didn't hold up. OP_AUDIO_ROOT = "audio_root" +# Which folder(s) are the Photos app's entry points for this group — a +# *set*, unlike OP_VIDEO_ROOT/OP_AUDIO_ROOT above: a photo library is +# routinely scattered across several folders (docs/photos.md §2.1). The +# whole set is signed and replaced in one op, same shape as OP_APPS_ENABLED. +OP_PHOTO_ROOTS = "photo_roots" OP_ROOT_ADD = "root_add" OP_ROOT_REMOVE = "root_remove" OP_GROUP_ATTACH = "group_attach" diff --git a/packages/meshbay-common/src/meshbay_common/protocol.py b/packages/meshbay-common/src/meshbay_common/protocol.py index 24fea8f..dd377e7 100644 --- a/packages/meshbay-common/src/meshbay_common/protocol.py +++ b/packages/meshbay-common/src/meshbay_common/protocol.py @@ -123,6 +123,11 @@ class MNP: # shape as VIDEO_ROOT above. AUDIO_ROOT = "audio_root" # operator → node: which folder is the Music entry point AUDIO_ROOT_ACK = "audio_root_ack" + # Which folder(s) are the Photos app's entry points for this group — a + # *set*, unlike VIDEO_ROOT/AUDIO_ROOT above, since a photo library is + # routinely scattered across several unrelated folders (docs/photos.md §2.1). + PHOTO_ROOTS = "photo_roots" # operator → node: the whole root set, replaced + PHOTO_ROOTS_ACK = "photo_roots_ack" # Device linking. A new device files a request bound to a code it displays; # an already-pinned device of the same account approves it. Neither the hub # nor the node can produce the countersignature. @@ -174,14 +179,16 @@ class IndexEntry: thumb_hash: str | None = None # blake3 of thumbnail uploader_id: str | None = None # user_id of who uploaded (None = pre-existing on disk) uploader_pk: str | None = None # Ed25519 public key of uploader (base64 raw 32 bytes) - width: int | None = None # pixels, video only - height: int | None = None # pixels, video only + width: int | None = None # pixels, video/image + height: int | None = None # pixels, video/image display_title: str | None = None # parsed or cleaned-filename title, Videos app season: int | None = None # parsed season number, Videos app episode: int | None = None # parsed episode number, Videos app artist: str | None = None # tag or parsed, Music app album: str | None = None # tag or parsed, Music app track_no: int | None = None # tag or parsed, Music app + taken_at: int | None = None # unix timestamp, EXIF DateTimeOriginal — Photos app + camera: str | None = None # "Make Model", when both present — Photos app def index_entry_wire(e: IndexEntry) -> dict: @@ -201,6 +208,7 @@ def index_entry_wire(e: IndexEntry) -> dict: "display_title": e.display_title, "season": e.season, "episode": e.episode, "artist": e.artist, "album": e.album, "track_no": e.track_no, + "taken_at": e.taken_at, "camera": e.camera, } |