def get_system_library_path(): """ return the path to the system Photos library as string """ """ only works on MacOS 10.15+ """ """ on earlier versions, returns None """ _, major, _ = _get_os_version() if int(major) < 15: logging.debug( f"get_system_library_path not implemented for MacOS < 10.15: you have {major}" ) return None plist_file = pathlib.Path( str(pathlib.Path.home()) + "/Library/Containers/com.apple.photolibraryd/Data/Library/Preferences/com.apple.photolibraryd.plist" ) if plist_file.is_file(): with open(plist_file, "rb") as fp: pl = plistload(fp) else: logging.warning(f"could not find plist file: {str(plist_file)}") return None photospath = pl["SystemLibraryPath"] if photospath is not None: return photospath else: logging.warning("Could not get path to Photos database") return None
def get_last_library_path(): """ returns the path to the last opened Photos library If a library has never been opened, returns None """ plist_file = pathlib.Path( str(pathlib.Path.home()) + "/Library/Containers/com.apple.Photos/Data/Library/Preferences/com.apple.Photos.plist" ) if plist_file.is_file(): with open(plist_file, "rb") as fp: pl = plistload(fp) else: logging.debug(f"could not find plist file: {str(plist_file)}") return None # get the IPXDefaultLibraryURLBookmark from com.apple.Photos.plist # this is a serialized CFData object photosurlref = pl["IPXDefaultLibraryURLBookmark"] if photosurlref is not None: # use CFURLCreateByResolvingBookmarkData to de-serialize bookmark data into a CFURLRef # pylint: disable=no-member # pylint: disable=undefined-variable photosurl = CoreFoundation.CFURLCreateByResolvingBookmarkData( kCFAllocatorDefault, photosurlref, 0, None, None, None, None ) # the CFURLRef we got is a sruct that python treats as an array # I'd like to pass this to CFURLGetFileSystemRepresentation to get the path but # CFURLGetFileSystemRepresentation barfs when it gets an array from python instead of expected struct # first element is the path string in form: # file:///Users/username/Pictures/Photos%20Library.photoslibrary/ photosurlstr = photosurl[0].absoluteString() if photosurl[0] else None # now coerce the file URI back into an OS path # surely there must be a better way if photosurlstr is not None: photospath = os.path.normpath( urllib.parse.unquote(urllib.parse.urlparse(photosurlstr).path) ) else: logging.warning( "Could not extract photos URL String from IPXDefaultLibraryURLBookmark" ) return None return photospath else: logging.debug("Could not get path to Photos database") return None