Open rizwank opened 1 year ago
I'd definitely like to add support for this but will be some time before I have chance to look at this as I'm not yet using the shared library feature.
Glad I held off on setting this up, I'd like to use it soon. @RhetTbull you can test it easily by just making a very small shared library and adding just a few photos to it.
Also randomly, howdy @rizwank ... long time! https://eecue.com/tags/view/rizwan
@RhetTbull anything I could provide from my system (a query against a sql db) that'd help conceptualizing?
@eecue HIIIIIIII . Almost two decades and multiple press interviews and commercials, and your pictures of me are still pretty highly rated for me on Google; so I think of you pretty often =)
@rizwank yes, thanks! In the attached zip is a python file dump_photo_data.py
. Copy it to your system and also install osxphotos if you've not already done so. Then in Photos, in the Library view (which shows all your photos in a grid) or in an Album view (which shows all photos inside an album), select a single photo that's in your shared iCloud library by clicking it with the mouse (but not double-clicking to open the photo in the full screen view) then from the terminal run:
osxphotos run dump_photo_data.py > computer1.txt
and send me the text file. If you have access to another user's Mac who's also using your shared library, do the same on their computer (osxphotos run dump_photo_data.py > computer2.txt
) after selecting the same photo.
Note that the dump script will dump a lot of data about the selected photo including location, filename, title, caption/description, etc. so pick a photo that doesn't contain sensitive information.
What I'm after information wise is how Photos is determining which photos are in the shared library. I believe I know enough enough now to match photos between the two libraries but I need to be able to filter for just photos in the shared library.
I took a random screenshot-file, and I ran the dump tool twice on it:
Once before I moved it to the shared library, and once after.
This is a diff:
--- shared 2023-08-01 23:07:22
+++ not_shared 2023-08-01 23:06:52
@@ -2,8 +2,8 @@
ZASSET (2434906D-F55C-458A-A48D-399FFE9B4273):
Z_PK: 42114
Z_ENT: 3
- Z_OPT: 7
- ZACTIVELIBRARYSCOPEPARTICIPATIONSTATE: 1
+ Z_OPT: 6
+ ZACTIVELIBRARYSCOPEPARTICIPATIONSTATE: 0
ZAVALANCHEPICKTYPE: 0
ZBUNDLESCOPE: 0
ZCAMERAPROCESSINGADJUSTMENTSTATE: 0
@@ -31,7 +31,7 @@
ZISMAGICCARPET: 0
ZKIND: 0
ZKINDSUBTYPE: 10
- ZLIBRARYSCOPESHARESTATE: 10485760
+ ZLIBRARYSCOPESHARESTATE: 0
ZMONOSKITYPE: 0
ZORIENTATION: 1
ZPACKEDACCEPTABLECROPRECT: 0
@@ -69,7 +69,7 @@
ZHIGHLIGHTBEINGKEYASSETSHARED: None
ZHIGHLIGHTBEINGSUMMARYASSETS: None
ZIMPORTSESSION: None
- ZLIBRARYSCOPE: 1
+ ZLIBRARYSCOPE: None
ZMASTER: 40518
ZMEDIAANALYSISATTRIBUTES: None
ZMOMENT: 6144
@@ -96,7 +96,7 @@
ZLASTSHAREDDATE: 712604920
ZLATITUDE: -180.0
ZLONGITUDE: -180.0
- ZMODIFICATIONDATE: 712616816.145502
+ ZMODIFICATIONDATE: 712604920.646597
ZOVERALLAESTHETICSCORE: 0.5
ZPROMOTIONSCORE: 0.0
ZSORTTOKEN: 712604904.0
@@ -119,7 +119,7 @@
ZADDITIONALASSETATTRIBUTES (2434906D-F55C-458A-A48D-399FFE9B4273):
Z_PK: 42114
Z_ENT: 1
- Z_OPT: 3
+ Z_OPT: 2
ZALLOWEDFORANALYSIS: 1
ZCAMERACAPTUREDEVICE: 0
ZCLOUDAVALANCHEPICKTYPE: 0
@@ -205,8 +205,8 @@
ZSHIFTEDLOCATIONDATA: None
Z_PK: 42114
Z_ENT: 1
- Z_OPT: 3
- ZACTIVELIBRARYSCOPEPARTICIPATIONSTATE: 1
+ Z_OPT: 2
+ ZACTIVELIBRARYSCOPEPARTICIPATIONSTATE: 0
ZAVALANCHEPICKTYPE: 0
ZBUNDLESCOPE: 0
ZCAMERAPROCESSINGADJUSTMENTSTATE: 0
@@ -234,7 +234,7 @@
ZISMAGICCARPET: 0
ZKIND: 0
ZKINDSUBTYPE: 10
- ZLIBRARYSCOPESHARESTATE: 10485760
+ ZLIBRARYSCOPESHARESTATE: 0
ZMONOSKITYPE: 0
ZORIENTATION: 1
ZPACKEDACCEPTABLECROPRECT: 0
@@ -272,7 +272,7 @@
ZHIGHLIGHTBEINGKEYASSETSHARED: None
ZHIGHLIGHTBEINGSUMMARYASSETS: None
ZIMPORTSESSION: None
- ZLIBRARYSCOPE: 1
+ ZLIBRARYSCOPE: None
ZMASTER: 40518
ZMEDIAANALYSISATTRIBUTES: None
ZMOMENT: 6144
@@ -299,7 +299,7 @@
ZLASTSHAREDDATE: 712604920
ZLATITUDE: -180.0
ZLONGITUDE: -180.0
- ZMODIFICATIONDATE: 712616816.145502
+ ZMODIFICATIONDATE: 712604920.646597
ZOVERALLAESTHETICSCORE: 0.5
ZPROMOTIONSCORE: 0.0
ZSORTTOKEN: 712604904.0
@kvisle Thank you! This is very helpful. Here's one more command to run from terminal.
osxphotos repl
At the >>>
REPL prompt,
find('2434906D-F55C-458A-A48D-399FFE9B4273')
This will print out a list of all files associated with this UUID. Post the list here as it will help me figure out where the shared library files are being stored (my guess is photos moves them into the scopes
subdirectory of the Photos library).
Thanks! I totally forgot, and my wife’s laptop is in the shop.
On Tue, Aug 1 2023 at 3:25 PM, Rhet Turnbull @.***> wrote:
@kvisle https://github.com/kvisle Thank you! This is very helpful. Here's one more command to run from terminal.
osxphotos repl
At the >>> REPL prompt,
find('2434906D-F55C-458A-A48D-399FFE9B4273')
This will print out a list of all files associated with this UUID. Post the list here as it will help me figure out where the shared library files are being stored (my guess is photos moves them into the scopes subdirectory of the Photos library).
— Reply to this email directly, view it on GitHub https://github.com/RhetTbull/osxphotos/issues/860#issuecomment-1661180031, or unsubscribe https://github.com/notifications/unsubscribe-auth/AABWPZDDRRK7NEKZAITEBCLXTF65VANCNFSM6AAAAAAS2SWS5A . You are receiving this because you were mentioned.Message ID: @.***>
Looks like the following columns will let us figure out if a photo is in a shared library:
ZACTIVELIBRARYSCOPEPARTICIPATIONSTATE
ZLIBRARYSCOPESHARESTATE
ZLIBRARYSCOPE
Any one of these may be sufficient for determining if photo is in a shared icloud library but there may be more to these so will require some more experimentation. This is enough though for now for osxphotos to recognize these photos. Now we just need to confirm where the photos are stored on disk. My guess is they'll have been moved from ~/Pictures/Photos Library.photoslibrary/originals
to somewhere under ~/Pictures/Photos Library.photoslibrary/scopes
.
ZLIBRARYSCOPESHARESTATE: 10485760
may be a bit mask. 10485760 is '0b101000000000000000000000' in binary which is a 24-bit number with only 2 values set to 1.
I did the osxphotos repl
thing. The first output is in my personal library, and the second output is in the shared library.
They are identical:
['/Users/tv/Pictures/Photos Library.photoslibrary/resources/renders/2/2434906D-F55C-458A-A48D-399FFE9B4273_1_201_a.jpeg', '/Users/tv/Pictures/Photos Library.photoslibrary/resources/renders/2/2434906D-F55C-458A-A48D-399FFE9B4273.plist', '/Users/tv/Pictures/Photos Library.photoslibrary/resources/derivatives/masters/2/2434906D-F55C-458A-A48D-399FFE9B4273_4_5005_c.jpeg', '/Users/tv/Pictures/Photos Library.photoslibrary/resources/derivatives/2/2434906D-F55C-458A-A48D-399FFE9B4273_1_105_c.jpeg', '/Users/tv/Pictures/Photos Library.photoslibrary/originals/2/2434906D-F55C-458A-A48D-399FFE9B4273.png']
['/Users/tv/Pictures/Photos Library.photoslibrary/resources/renders/2/2434906D-F55C-458A-A48D-399FFE9B4273_1_201_a.jpeg', '/Users/tv/Pictures/Photos Library.photoslibrary/resources/renders/2/2434906D-F55C-458A-A48D-399FFE9B4273.plist', '/Users/tv/Pictures/Photos Library.photoslibrary/resources/derivatives/masters/2/2434906D-F55C-458A-A48D-399FFE9B4273_4_5005_c.jpeg', '/Users/tv/Pictures/Photos Library.photoslibrary/resources/derivatives/2/2434906D-F55C-458A-A48D-399FFE9B4273_1_105_c.jpeg', '/Users/tv/Pictures/Photos Library.photoslibrary/originals/2/2434906D-F55C-458A-A48D-399FFE9B4273.png']
Great! The files are not moved from their default location as I thought they might be (other types of shared photos are moved). This means osxphotos should be able to export these now. All that is needed is a filter option to select or deselect photos from a shared library as desired.
@kvisle I have one more request for data and I think I'll have enough to fully implement support for shared libraries. On one of the computers using the shared library do the following:
osxphotos snap
osxphotos diff -r > diff.txt
This will create a snapshot of the library then do a diff after the change is made. The diff.txt
file will contain much more information than the previous dump including potentially identification info for the iCloud account so you may not want to post it here. You can post it (After sanitizing it) or email to me at rturnbull+git@gmail.com
It didn't look too bad, but I dropped you an email.
@kvisle I'm working on this now and want to confirm the location of photos which were shared by another user using the shared library. Can you select in Photos a single photo shared into the shared library by a different account then in the repl (osxphotos repl
) run this command
find(selected[0].uuid)
Here you go:
>>> find(selected[0].uuid)
['/Users/tv/Pictures/Photos Library.photoslibrary/resources/derivatives/masters/2/2D935AB6-D515-4307-9B2B-B86A957944C0_4_5005_c.jpeg', '/Users/tv/Pictures/Photos Library.photoslibrary/resources/derivatives/2/2D935AB6-D515-4307-9B2B-B86A957944C0_1_105_c.jpeg', '/Users/tv/Pictures/Photos Library.photoslibrary/originals/2/2D935AB6-D515-4307-9B2B-B86A957944C0.jpeg']
@kvisle thanks. I think I've got enough data now to identify if an asset is in the shared library and get contact information for who shared it. I likely can't get a release out until this weekend but once I do, will need testing to confirm the code is working then I can add this to inspect, add query options to filter photos etc. I think I can also extract metadata about the shared library (who many assets are in it, etc.) but I've had to make some guesses so this will require more testing.
@rizwank @kvisle I've added initial support for shared iCloud library to v0.62.0. I'm not 100% sure it's correct as I had to make some guesses. osxphotos inspect
should now show shared iCloud library
under the Flags:
heading if the photo is a shared library. To add information on participants I need some more testing. If you could save the following script to shared_library.py
then select a photo that is in your shared iCloud library in Photos then run the script with osxphotos run shared_library.py > shared.txt
then send me the text file that would be helpful for testing. (send to rturnbull+git@gmail.com instead of posting here as it may contain names/email addresses of shared participants, etc.)
"""Dump info about shared library photos.
Select a photo that's in the shared library then run with `osxphotos run shared_library.py > shared.txt`
"""
import sys
import photoscript
import osxphotos
from osxphotos.cli import echo_error
def main():
selected = photoscript.PhotosLibrary().selection
if not selected:
echo_error("No photo selected")
sys.exit(1)
uuid = selected[0].uuid
library = osxphotos.PhotosDB()
photo = library.get_photo(uuid)
if not photo:
echo_error(f"Could not find photo with UUID {uuid}")
sys.exit(1)
print(f"Photo info (uuid={uuid}):")
print(f"{photo.path=}")
print(f"{photo.shared_library=}")
print(f"{photo.share_info=}")
if participants := photo.share_participants:
print("Shared participants:")
for participant in participants:
print(participant.asdict())
print()
print(photo.asdict())
if __name__ == "__main__":
main()
Ran tool and sent you output.
@kvisle Got it -- thanks! I've been able to decode the name data of the person who shared the photo thanks to the data you provided. Working on an update to osxphotos to incorporate this.
@all-contributors please add @kvisle for user testing
@RhetTbull
I've put up a pull request to add @kvisle! :tada:
@kvisle I've pushed a new release at v0.62.2. If you don't mind, please update to this version then run osxphotos inspect
and select a photo in your shared iCloud library. Try selecting one that you added and one added by another contributor to the library. The inspect window should show the name of the contributor.
Also, with one of these photos selected, run osxphotos repl
then at the prompt, try:
get_selected()[0].share_participants
and
get_selected()[0].share_participant_info
Both of these should show additional information about the shared photo (and hopefully not throw an error). I've not been able to test this part of the code.
This works as expected on objects I shared a while ago
When I do it on objects I shared today (although the objects themselves are years old) - both of these return a blank array.
The returned values look to me to be information about the person who shared the object.
Noticed in the most recent under inspect that
Tried to run the script you sent to get you more info, but threw an Exception
│ /Users/rizwank/shared_library.py:33 in main │ │ │ │ 30 │ if participants := photo.share_participants: │ │ 31 │ │ print("Shared participants:") │ │ 32 │ │ for participant in participants: │ │ ❱ 33 │ │ │ print(participant.asdict()) │ │ 34 │ print() │ │ 35 │ print(photo.asdict()) │ │ 36 │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────╯ AttributeError: 'str' object has no attribute 'asdict'
Does this mean you might have more access to the underlying Persons database?
Yes. But it varies by what you mean by person. For people in a shared library I can access full name, email, and phone. For persons labeled in photos osxphotos doesn't currently provide much other than name but it is possible in some cases to get the associated Contacts record. I've not yet done the engineering to implement that though.
Search info lists categories 2401 (appears to be which library personal or shared) and 1900 (says Photos for me, not sure what it says on others.)
Thanks. For categories which I've not yet decoded I just print the category number and the value. Apple sadly doesn't provide a key to the category numbers as this is extracted from an undocumented database.
2401 seems to just say Personal or Shared, for what it’s worth.
In the database, is there a persons table that shows the underlying face matching score? When I get home, I’m happy to check the database myself as well. Thanks!
On Tue, Aug 29 2023 at 1:03 AM, Rhet Turnbull @.***> wrote:
Search info lists categories 2401 (appears to be which library personal or shared) and 1900 (says Photos for me, not sure what it says on others.)
Thanks. For categories which I've not yet decoded I just print the category number and the value. Apple sadly doesn't provide a key to the category numbers as this is extracted from an undocumented database.
— Reply to this email directly, view it on GitHub https://github.com/RhetTbull/osxphotos/issues/860#issuecomment-1696541024, or unsubscribe https://github.com/notifications/unsubscribe-auth/AABWPZA5URUDLGI2D7DIS43XXUPSJANCNFSM6AAAAAAS2SWS5A . You are receiving this because you were mentioned.Message ID: @.***>
The ZPERSON
table has information about persons associated with faces (ZDETECTEDFACE
table). The column ZPERSON.ZMERGECANDIDATECONFIDENCE
might be what you're looking for. I've not explored faces/persons beyond just ensuring that what osxphotos reports matches what is shown in Photos.
Is your feature request related to a problem? Please describe. macOS 13.0 added support for iCloud Shared Library; and there are two additional attributes that could be available from the database; whether an item is in the Personal Library or Shared Library; and who contributed the asset to the Shared Library. (The latter is not available as a Smart Album search, but is available via the inspector pane and the search bar)
Would it be possible for the inspect osxphotos function to show those details? (I imagine, once those details are available there; they might further be available to query, labels or keywords, etc.