Skip to content

Instantly share code, notes, and snippets.

@iangreenleaf
Last active January 8, 2019 17:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save iangreenleaf/f6288c6d75103ff28c9145f20539d434 to your computer and use it in GitHub Desktop.
Save iangreenleaf/f6288c6d75103ff28c9145f20539d434 to your computer and use it in GitHub Desktop.
Shotwell RAW metadata migrator - rescue your data from Shotwell
#!/bin/bash
# Shotwell RAW metadata migrator
#
# This software is provided WITHOUT WARRANTY OF ANY KIND
#
# Shotwell doesn't write metadata to RAW files. This was a problem when I wished to migrate all my data out of Shotwell.
# This script pulls data out of Shotwell's database and writes it to the files using exiftool.
# This is not elegant, performant, or well-tested. However, it seems to get the job done!
#
# It retrieves and writes title, comment, rating, and tags. These are all written in formats that Digikam recognizes.
#
# This does not do anything with video files. I didn't have enough of these to care.
#
# Shotwell keeps an extracted JPG paired with each RAW file, and also doesn't write metadata to those files.
# This doesn't do anything for the JPG files since I am planning to discard them.
#
# It would be relatively easy to modify the exiftool commands if you want to do something else with the data.
# You're on your own for that one, though!
#
# Shoutout to https://github.com/narcoticfresh/shotwell for a nice project. I didn't use any of the code but
# it was a helpful resource to understand Shotwell's "creative" database structure.
echo "Finding tags…"
sqlite3 ~/.local/share/shotwell/data/photo.db 'select PhotoTable.filename, TagTable.name from PhotoTable join TagTable on (TagTable.photo_id_list LIKE printf("%%thumb%016X%%", PhotoTable.id)) where PhotoTable.file_format = 1;' | while IFS="$(printf '\n')" read LINE; do IFS='|' read PHOTO_FILE TAG_NAME <<< "$LINE"; exiftool -TagsList-="$TAG_NAME" -TagsList+="$TAG_NAME" "$PHOTO_FILE" || echo "Trouble! $PHOTO_FILE += '$TAG_NAME'"; done
echo "Done!"
echo "Finding ratings…"
sqlite3 ~/.local/share/shotwell/data/photo.db 'select filename, rating from PhotoTable where rating > 0 and file_format = 1;' | while IFS="$(printf '\n')" read LINE; do IFS='|' read PHOTO_FILE RATING <<< "$LINE"; exiftool -Rating="$RATING" "$PHOTO_FILE" || echo "Trouble! $PHOTO_FILE = $Rating stars"; done
echo "Done!"
echo "Finding titles and comments…"
sqlite3 ~/.local/share/shotwell/data/photo.db 'select filename, title, comment from PhotoTable where (title is not null or comment is not null) and file_format = 1;' | while IFS="$(printf '\n')" read LINE; do IFS='|' read PHOTO_FILE TITLE COMMENT <<< "$LINE"; exiftool -Title="$TITLE" -Headline="$TITLE" -UserComment="$COMMENT" -Description="$COMMENT" "$PHOTO_FILE" || echo "Trouble! $PHOTO_FILE title/comments"; done
echo "Done!"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment