RhetTbull / osxmetadata

Python package to read and write various MacOS extended attribute metadata such as tags/keywords and Finder comments from files. Includes CLI tool for reading/writing metadata.
MIT License
125 stars 4 forks source link

If Spotlight metadata changed outside of OSXMetaData it does not reflect in the current OSXMetaData instance #94

Open RhetTbull opened 1 year ago

RhetTbull commented 1 year ago
          I don't believe this is a bug but rather an artifact of how macOS handles certain types of metadata. If you get/set `kMDItemKeywords` on a regular file, it works as expected (I tested on both Ventura 13.1 and Monterey 12.6):
❯ python
Python 3.11.2 (v3.11.2:878ead1ac1, Feb  7 2023, 10:02:41) [Clang 13.0.0 (clang-1300.0.29.30)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import osxmetadata
>>> from osxmetadata import *
>>> import pathlib
>>> import platform
>>> osxmetadata.__version__
'1.2.2'
>>> platform.platform()
'macOS-13.1-arm64-arm-64bit'
>>> pathlib.Path("test_file").touch()
>>> md = OSXMetaData("test_file")
>>> md.keywords
>>> md.set(kMDItemKeywords, ["Test"])
>>> md.keywords
['Test']
Screenshot 2023-04-16 at 2 06 09 PM

However, with image files (which contain embedded data), the metadata embedded in the image always takes precedent. There's a Spotlight Importer process that reads the EXIF/IPTC/XMP metadata and sets the metadata attributes in the Spotlight database (e.g. kMDItemKeywords) accordingly. Any changes the the attribute don't change the underlying file and the metadata contained in it. The same is likely true for things like audio files which also contain embedded metadata.

However, if we change the underlying EXIF data then it works as expected (with one caveat that while testing this I've uncovered a possible bug in osxmetadata -- namely that the metadata did not refresh after changing the EXIF data until I created a new OSXMetaData instance.

In the example below, I use the ExifTool class of my osxphotos project because I'm familiar with it but there are several other python wrappers for exiftool.

❯ python
Python 3.11.2 (v3.11.2:878ead1ac1, Feb  7 2023, 10:02:41) [Clang 13.0.0 (clang-1300.0.29.30)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from osxmetadata import *
>>> from osxphotos import ExifTool
>>> md = OSXMetaData("test.jpg")
>>> md.keywords
['Test']
>>> md.set(kMDItemKeywords, ["Foo"])
>>> md.keywords
['Test']
>>> exif = ExifTool("test.jpg")
>>> exif.asdict()["IPTC:Keywords"]
'Test'
>>> exif.addvalues("IPTC:Keywords", "Foo")
True
>>> exif.asdict()["IPTC:Keywords"]
['Test', 'Foo']
>>> md.keywords
>>> md.get(kMDItemKeywords)
>>> # ^^^^ these two lines should have returned the metadata but they didn't until I created
>>> # a new OSXMetaData object
>>> # even though the Finder was displaying the new metadata so the Spotlight importer had run
>>> md = OSXMetaData("test.jpg")
>>> md.keywords
['Test', 'Foo']
>>> exif.addvalues("IPTC:Keywords", "Bar")
True
>>> md.keywords
>>> md = OSXMetaData("test.jpg")
>>> md.keywords
['Test', 'Foo', 'Bar']
>>>

So in summary, osxmetadata cannot change metadata associated with a file that has embedded metadata if Spotlight is using the embedded metadata as the Spotlight metadata attributes. I'll add something about this in the documentation. osxmetadata can alter metadata that is not associated with the embedded metadata, for example, Finder tags:

❯ python
Python 3.11.2 (v3.11.2:878ead1ac1, Feb  7 2023, 10:02:41) [Clang 13.0.0 (clang-1300.0.29.30)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from osxmetadata import *
>>> md = OSXMetaData("test.jpg")
>>> md.tags
[]
>>> md.tags = [Tag("Test", 0)]
>>> md.tags
[Tag(name='Test', color=0)]
>>>

Originally posted by @RhetTbull in https://github.com/RhetTbull/osxmetadata/issues/92#issuecomment-1510495840