Skip to content

Expose --xmp-sidecar flag via config - #946

Open
laforcem wants to merge 6 commits into
boredazfcuk:masterfrom
laforcem:feature/xmp-sidecar-flag
Open

Expose --xmp-sidecar flag via config#946
laforcem wants to merge 6 commits into
boredazfcuk:masterfrom
laforcem:feature/xmp-sidecar-flag

Conversation

@laforcem

@laforcem laforcem commented Jul 2, 2026

Copy link
Copy Markdown

Picks up #775.

Changes

This PR exposes icloud_photos_downloader's --xmp-sidecar flag as a new config variable: xmp_sidecar. The default setting is false.

A sidecar file will look something like this:

<?xml version='1.0' encoding='utf-8'?>
<x:xml_doc xmlns:x="adobe:ns:meta/" x:xmptk="icloudpd 1.32.3+2035bb1">
  <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
    <rdf:Description rdf:about="" xmlns:dc="http://purl.org/dc/elements/1.1/">
      <dc:description>Screenshot</dc:description>
    </rdf:Description>
    <rdf:Description rdf:about="" xmlns:Iptc4xmpExt="http://iptc.org/std/Iptc4xmpExt/2008-02-29/">
      <Iptc4xmpExt:DigitalSourceType>screenCapture</Iptc4xmpExt:DigitalSourceType>
    </rdf:Description>
    <rdf:Description rdf:about="" xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/">
      <photoshop:DateCreated>2026-06-30T12:24:53-0500</photoshop:DateCreated>
    </rdf:Description>
    <rdf:Description rdf:about="" xmlns:tiff="http://ns.adobe.com/tiff/1.0/">
      <tiff:Make>Screenshot</tiff:Make>
    </rdf:Description>
    <rdf:Description rdf:about="" xmlns:xmp="http://ns.adobe.com/xap/1.0/">
      <xmp:CreateDate>2026-06-30T12:24:53-0500</xmp:CreateDate>
    </rdf:Description>
  </rdf:RDF>
</x:xml_doc>

Behavior

Retroactive backfill

If files are already downloaded while the flag is false, then it is later turned to true, .xmp sidecar files will be downloaded for all files already in the library. Critically, this does not re-download assets already downloaded; just the sidecars.

Live Photos

While Live Photos already have two files downloaded for each (.HEIC + .MOV), only one .xmp sidecar is downloaded for one Live Photo. The sidecar counts for both files.

Deletion

When assets are deleted from iCloud, icloudpd will sync those deletions down to the sidecar as well, leaving no orphaned .xmp files.


Let me know if any changes are desired here.

laforcem and others added 6 commits July 2, 2026 12:11
Co-Authored-By: Claude <noreply@anthropic.com>
…onal

The log summary line was nested inside an unrelated if-block during
initial implementation, meaning it would only ever print when
keep_icloud_recent_only was enabled instead of unconditionally, like
every other flag-state summary line in this block.

Co-Authored-By: Claude <noreply@anthropic.com>
Existing users' config files predate this variable and won't contain it
until the config-scaffolding task lands. Without a default, the bare
variable reference expands to empty string under this script's no-nounset
convention, and [ "" != "false" ] is true — silently turning on XMP
sidecar generation for every existing user the moment this commit ships,
with no opt-in. Use the ${var:-false} idiom already established elsewhere
in this file (icloud_china, single_pass, auth_domain) so this commit is
safe to deploy standalone, independent of scaffolding sequencing.

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
@roleme

roleme commented Jul 10, 2026

Copy link
Copy Markdown

Been running this and it works great — thanks for picking it up. With xmp_sidecar=true every photo gets its .xmp alongside it, and importantly the sidecar carries the GPS that Apple keeps catalog-side (so photos with no GPS in the file itself finally get a location downstream). Immich picks the sidecar up automatically, which was exactly what I was after.

One heads-up in case it helps: icloudpd itself crashes if --xmp-sidecar and --only-print-filenames ever run together (it tries to write the .xmp into a folder that print-mode never created → FileNotFoundError in xmp_sidecar.py). This PR is fine because the flag only goes on the sync command, and check_files() builds its own --only-print-filenames command separately. Just worth a one-line comment there so nobody later "tidies up" check_files() to reuse command_line_builder() and accidentally reintroduces the crash. I've filed the underlying bug upstream too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants