Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

add push-exif command to CLI #160

Closed
RhetTbull opened this issue Jun 12, 2020 · 16 comments
Closed

add push-exif command to CLI #160

RhetTbull opened this issue Jun 12, 2020 · 16 comments
Labels
feature request New feature or request

Comments

@RhetTbull
Copy link
Owner

Some people still use photosmeta due to --inplace exif update feature. Add a similar feature to osxphotos to update the metadata of the photos in the actual library without exporting.

@RhetTbull RhetTbull added the feature request New feature or request label Jun 13, 2020
@RhetTbull
Copy link
Owner Author

Ideas for how this could work:

osxphotos inplace --exiftool --person-keyword --photos-keyword "{person}"

This would add "{person}" template as a keyword in Photos and add person name as keyword to exif data using exiftool (against the original and edited images).

Could be used with or without exiftool. Without it, wouldn't modify originals, only the keywords or description in Photos.

Use all the usual query arguments as well as the regular metadata arguments:

  --exiftool
  --person-keyword      
  --album-keyword                 
  --keyword-template 
  --replace-keywords   
  --description-template 
  --finder-tag-template 
  --finder-tag-keywords           
  --xattr-template 

Also add new --photos-keywords and --photos-description to modify the keywords and/or description in Photos.

@RhetTbull RhetTbull changed the title add inplace command to CLI add push-exif command to CLI Aug 23, 2023
@RhetTbull
Copy link
Owner Author

push-exif is probably a better name for this. Some of the functionality envisioned above is now present in osxphotos batch-edit. I think that modifying the Photos metadata (batch-edit) and modifying the EXIF data in the original file (push-exif) should be separate functions.

@RhetTbull
Copy link
Owner Author

osxphotos push-exif

osxphotos push-exif command

Pushes metadata from Photos to the exif data of the original file (and optionally edited) using exiftool.

Specify which metadata gets pushed:

osxphotos push-exif [--push|--compare] [all keywords location faces date title description favorite]

specify all or subset using one or more of:

all keywords faces date title description

e.g. osxphotos push-exif keywords,faces

--dry-run would show which files would be updated

--verbose would show each field that's written

--include-edited : also write EXIF data to edited files
--skip-original-if-edited: similar to export, skips writing EXIF data to original if file is edited.
--skip-edited: would it be better to include this than --include-edited?

What about raw? (can EXIF data be written to raw files?)

When run, first reads the metadata from the file and stores it in an undo database (like batch-edit does). Can then run with --undo to revert to the original. This will slow down the process so could also offer a --no-undo that skips the undo database but prompt the user for this.

--compare: use instead of --push and print out a diff for those fields which are different.
Or maybe if --compare is used, it doesn't push. Only need to specify --compare when wanting to compare otherwise will push.

Undo database would use SqliteKVStore with key of UUID and value of JSON dict from reading with ExifTool.

--report to write report of what was updated. Support CSV, JSON, and SQLite as export does.
--append to append to report
See ReportWriter: https://github.com/RhetTbull/osxphotos/blob/main/osxphotos/cli/report_writer.py

Also support the following exiftool options that export supports

  --exiftool-path EXIFTOOL_PATH   Optionally specify path to exiftool; if not
                                  provided, will look for exiftool in $PATH.
  --exiftool-option OPTION        Optional flag/option to pass to exiftool when
                                  using --exiftool. For example, --exiftool-
                                  option '-m' to ignore minor warnings. Specify
                                  these as you would on the exiftool command
                                  line. See exiftool docs at
                                  https://exiftool.org/exiftool_pod.html for
                                  full list of options. More than one option may
                                  be specified by repeating the option, e.g.
                                  --exiftool-option '-m' --exiftool-option '-F'.
  --exiftool-merge-keywords       Merge any keywords found in the original file
                                  with keywords used for '--exiftool' and '--
                                  sidecar'.
  --exiftool-merge-persons        Merge any persons found in the original file
                                  with persons used for '--exiftool' and '--
                                  sidecar'.
  --favorite-rating               When used with --exiftool or --sidecar, set
                                  XMP:Rating=5 for photos marked as Favorite and
                                  XMP:Rating=0 for non-Favorites. If not
                                  specified, XMP:Rating is not set.
  --ignore-date-modified          If used with --exiftool or --sidecar, will
                                  ignore the photo modification date and set
                                  EXIF:ModifyDate to EXIF:DateTimeOriginal; this
                                  is consistent with how Photos handles the
                                  EXIF:ModifyDate tag.
  --person-keyword                Use person in image as keyword/tag when
                                  exporting metadata.
  --album-keyword                 Use album name as keyword/tag when exporting
                                  metadata.
  --keyword-template TEMPLATE     For use with --exiftool, --sidecar; specify a
                                  template string to use as keyword in the form
                                  '{name,DEFAULT}' This is the same format as
                                  --directory.  For example, if you wanted to
                                  add the full path to the folder and album
                                  photo is contained in as a keyword when
                                  exporting you could specify --keyword-template
                                  "{folder_album}" You may specify more than one
                                  template, for example --keyword-template
                                  "{folder_album}" --keyword-template
                                  "{created.year}". See '--replace-keywords' and
                                  Templating System below.
  --replace-keywords              Replace keywords with any values specified
                                  with --keyword-template. By default,
                                  --keyword-template will add keywords to any
                                  keywords already associated with the photo.
                                  If --replace-keywords is specified, values
                                  from --keyword-template will replace any
                                  existing keywords instead of adding additional
                                  keywords.
  --description-template TEMPLATE
                                  For use with --exiftool, --sidecar; specify a
                                  template string to use as description in the
                                  form '{name,DEFAULT}' This is the same format
                                  as --directory.  For example, if you wanted to
                                  append 'exported with osxphotos on [today's
                                  date]' to the description, you could specify
                                  --description-template "{descr} exported with
                                  osxphotos on {today.date}" See Templating
                                  System below.

To implement, the code from photoexporter.py that handles exiftool should be pulled out into a separate EXIFWriter class that can be used both by PhotoExporter and the new push-exif code.

Create a new ExiftoolOptions option configuration class to pass to the writer. In PhotoExporter this can be created from the ExportOptions with no need to modify the export options code. This options class will also need flags specifying which attributes to write in contrast to PhotoExporter which writes almost all the done with a couple exceptions specified by flags.

def _write_exif_data(self, filepath: str, options: ExportOptions):
"""write exif data to image file at filepath
Args:
filepath: full path to the image file
Returns:
(warning, error) of warning and error strings if exiftool produces warnings or errors
"""
if not os.path.exists(filepath):
raise FileNotFoundError(f"Could not find file {filepath}")
exif_info = self._exiftool_dict(options=options)
with ExifTool(
filepath,
flags=options.exiftool_flags,
exiftool=self.photo._exiftool_path,
) as exiftool:
for exiftag, val in exif_info.items():
if type(val) == list:
for v in val:
exiftool.setvalue(exiftag, v)
else:
exiftool.setvalue(exiftag, val)
return exiftool.warning, exiftool.error

@RhetTbull
Copy link
Owner Author

Implemented in v0.63.0 as osxphotos push-exif

@RhetTbull
Copy link
Owner Author

@all-contributors please add @Jmuccigr for ideas

@allcontributors
Copy link
Contributor

@RhetTbull

I've put up a pull request to add @Jmuccigr! 🎉

@pdewost
Copy link

pdewost commented Apr 18, 2024

Great to see push-exif coming to life as a distant echo to a conversation we had with @RhetTbull in late 2021.
My personal use case is the following : I manage my photo library locally and sync them on a regular basis into my iPhone. They appear on iPhone as a separate "On my Mac" category and it seems they do not retain any of the attributes (person names or tags) that would simplify a search on iPhone.

Wondering whether push-exif would simplify this... Did anybody try already ?

PS: same question about adding the metadata in the Finder tags for each photo in the Photos Library, would this approach make exported photos searchable on the iPhone ?

@RhetTbull
Copy link
Owner Author

@pdewost exporting to iPhone isn't a supported use case for osxphotos so I'm not sure there's a whole lot osxphotos can do. What I would try is to export the metadata to a test image then copy that image to the phone to see if the iOS version of Photos picks up the keywords etc. If you import a photo into the Mac version of Photos that contains embedded keywords these do get added as keywords in Photos. If this does work, then push-exif might be helpful in your use case.

@pdewost
Copy link

pdewost commented Apr 21, 2024

@pdewost exporting to iPhone isn't a supported use case for osxphotos so I'm not sure there's a whole lot osxphotos can do. What I would try is to export the metadata to a test image then copy that image to the phone to see if the iOS version of Photos picks up the keywords etc. If you import a photo into the Mac version of Photos that contains embedded keywords these do get added as keywords in Photos. If this does work, then push-exif might be helpful in your use case.

Thank you @RhetTbull for this quick reply ; last point leaves me puzzled. Imported embedded keywords are passed to Photos yet are they transferred to the iPhone Photos app when you sync using the Finder (on Sonoma) ?

@RhetTbull
Copy link
Owner Author

Imported embedded keywords are passed to Photos yet are they transferred to the iPhone Photos app when you sync using the Finder (on Sonoma)

I'm sorry, I don't understand what you're asking. What I was suggesting is to try an experiment: sync keywords to a single photo using push-exif then copy that photo to the iPhone and see if the iPhone reads the embedded keywords when the photo is copied into the library. The Mac version of Photos does this. I do not know if the iPhone version of Photos does also.

@pdewost
Copy link

pdewost commented Apr 22, 2024

So I exported a photo with osxphotos along with its keywords, person names, including adding those to Finder tags. Then I reimported it in my Mac Photo Library before transferring it to my iPhone with cable sync. The tags do not show yet they are detected with tag search. Same for person names.

So the question becomes : the same operation with push-exif does not result in making the photo searchable on iPhone using tags or person names and I do not understand why...

@RhetTbull
Copy link
Owner Author

Interesting. I exported an image using --exiftool which applies the same metadata as using push-exif and when I imported that photo into my iPhone (I used AirDrop on the exported image), the phone did index the keywords -- see screenshot below which shows a sample image from the OSXPhotos test library. It took a few minutes before keywords showed up in search.

How are you copying photos to the Phone? Are you doing this from Photos? If so, it's possible Photos is exporting a version of the photo that strips metadata. In this case, it's probably better to export images using osxphotos export --exiftool then drag those into the phone.

IMG_6418

@pdewost
Copy link

pdewost commented Apr 23, 2024

I copy photos to the phone using the synchronization feature that was before in iTunes/Music and now is part of the Finder on macOS Sonoma. I select albums (including smart albums) and then let the sync happen, via a usb-c cable. All copied photos appear in "on my Mac" section of the iOS Photos album view yet they cannot be searched by tags or by face name.

Using osxphotos push-exif keywords,faces,persons,description --favorite-rating --person-keyword --report 'push_exif_{today.date}.csv' --append --push-edited --selected followed by syncing to the iPhone does not result in keyword indexing.

Using osxphotos export /Volumes/Samsung_X5/osxphotos2024-exports --selected --touch-file --finder-tag-keywords --person-keyword --xattr-template findercomment "{title}{title?{descr?{newline},},}{descr}" --exiftool-merge-keywords --exiftool-merge-persons --exiftool --strip --update followed by importing the photos back into macOS Photos app, then followed by syncing to the iPhone does it.

Could it be because of the fact that I do export the keywords and persons in the Finder Tags and that these are "ingested" into macOS Photos at import ?

Would there be an option for push-exif to also write Finder Tags that could make keywords indexing happen on the iPhone ?

@RhetTbull
Copy link
Owner Author

Could it be because of the fact that I do export the keywords and persons in the Finder Tags and that these are "ingested" into macOS Photos at import ?

I would be surprised if that's it. In my test, the iPhone clearly ingested keywords from the EXIF/XMP keywords fields.

I think you need to do some some experiments to isolate certain variables to see exactly what it is. Try an export with only --exiftool, then reimport, then sync. Does that work? Then try an export with only --finder-tag-keywords and reimport then sync. Does that work? In each case, I would start with a "clean" photo so you know exactly what data is being copied. I am unfamiliar with the sync utility so I don't know what it is doing. In my test of using AirDrop of an exported photo, the iPhone clearly read the data from the embedded keywords.

@pdewost
Copy link

pdewost commented Apr 23, 2024

The iPhone ingests for sure when using Airdrop. What I am trying to do is to work directly in the Photos macOS App where I manage 900Gb and 40 years and make sure that I can find the "synced" pictures in my iPhone in an easier manner than just scrolling through albums. Using the iOS Photos search feature would help if only it were capable of finding people (faces) as well as keywords (tags). So the osxphotos export to Mac and then import in iPhone is impractical...

Now I did test the following with just one image :

1/ osxphotos export /Volumes/Samsung_X5/osxphotos2024-exports --selected --touch-file --exiftool --person-keyword --exiftool-merge-keywords --exiftool-merge-persons --update . The exported photo was immediately reimported in macOS photos App along with its tags plus a face tag. After synchronizing with iPhone it can be searched by tags which was not the case of the original photo.

2/ osxphotos export /Volumes/Samsung_X5/osxphotos2024-exports --selected --touch-file --finder-tag-keywords --person-keyword --xattr-template findercomment "{title}{title?{descr?{newline},},}{descr}" --update does not keep tags at reimport.

3/ running osxphotos push-exif keywords,faces,persons,description --favorite-rating --person-keyword --report 'push_exif_{today.date}.csv' --append --push-edited --selected on the same picture and checking afterwards with the --compare option shows that the updated file's metadata has been indeed updated. Yet as the metadata are left unchanged in the macOS Photos App tags, they actually have no reason to be updated. It seems indeed that the Finder's sync method from Mac to iPhone does not transfer the files themselves, letting the iPhone rebuild its database from the EXIF tags, but rather exports the macOS Photos tags and keywords.

This sucks.

Tried a rebuild of the Photos Library work hoping it maybe would update the Mac's keywords and tag system with the EXIF metadata found in the pictures, yet there was no change. Photos synchronized to the iPhone are arbitralily searchable by keywords (some keywords will return 3 photos instead of dozens...) and none by person name.

As my purpose is to make photos search as easy on iPhone than it is on my Mac, I was wondering whether such dysfunctional behavior would change if I were using referenced photos instead of photos that are imported (and buried) in the Photos Library package. Maybe the export to the iPhone would leverage buried push-exif metadata ?

Sorry but this is very confusing to me...

@RhetTbull
Copy link
Owner Author

but rather exports the macOS Photos tags and keywords.

If this is the case, then you can easily use osxphotos batch-edit to set the tags in Photos before the export.

Select one or more photos in Photos then run:

osxphotos batch-edit --keyword "{person}"

This sets the Photos keywords to include the person name.

Are the other settings like title, description, favorite status transferred?

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
feature request New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants