Shotwell Architecture Overview: Background Metadata Writing
Shotwell 0.8 introduced a feature to write metadata (keywords, titles, ratings, and orientation) to the photo’s master file whenever the metadata is updated in Shotwell. This breaks new ground for Shotwell, as the philosophy has been to never touch the backing file. (With one exception; the Adjust Date / Time dialog allowed for the master file to be written to at the user’s behest.) Because we view the backing file as vital data, this option is off by default and must be enabled by the user in the Preferences dialog.
The MetadataWriter is a client of the central Shotwell data architecture and a good example of how to use its synchronization capabilities for this kind of work. In particular, note that no where in the code (other than the Preferences dialog) is the MetadataWriter referred to directly; instead, it monitors the state of the system from off to one side, performing operations when it detects the kind of change it’s interested in has occurred.
At program startup, MetadataWriter connects to several signals offered by LibraryPhoto.global and Tag.global. These signals inform MetadataWriter when photos have been altered, destroyed, tagged, and imported. From this point on, MetadataWriter operates by responding to these signals.
Additionally, MetadataWriter scans the metadata_dirty flag of every photo in the system. If a photo’s metadata is dirty, it’s immediately scheduled for writing. This allows Shotwell to exit at any time and pick up writing metadata when it’s next launched.
When a photo is altered (any alteration) MetadataWriter examines its Alteration signal and matches it against an internal list of alterations it’s watching for. If there’s a match, the photo’s metadata is marked as dirty and it’s placed on a TimedQueue for writing.
The reason a photo is placed on a TimedQueue and not merely written to right away is to allow many changes to be made to a photo at once. Shotwell waits for a short delay after the last alteration has been made before writing the metadata.
When the photo is ready, it’s dequeued and a BackgroundJob is enqueued on an internal Workers queue. The background thread reads the file’s current metadata and compares it against the metadata in Shotwell’s database. If nothing is different, no write occurs. Otherwise, the new metadata is added to the existing and the file is updated.
When the writing is completed, the MetadataWriter then re-incorporates all the new metadata in the database and clears the metadata-dirty flag on the photo.