3324 lines
443 KiB
HTML
3324 lines
443 KiB
HTML
|
|
<!DOCTYPE html>
|
|
|
|
<html>
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
<title>osxphotos.photosdb.photosdb — osxphotos 0.42.11 documentation</title>
|
|
<link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
|
|
<link rel="stylesheet" href="../../../_static/alabaster.css" type="text/css" />
|
|
<script id="documentation_options" data-url_root="../../../" src="../../../_static/documentation_options.js"></script>
|
|
<script src="../../../_static/jquery.js"></script>
|
|
<script src="../../../_static/underscore.js"></script>
|
|
<script src="../../../_static/doctools.js"></script>
|
|
<link rel="index" title="Index" href="../../../genindex.html" />
|
|
<link rel="search" title="Search" href="../../../search.html" />
|
|
|
|
<link rel="stylesheet" href="../../../_static/custom.css" type="text/css" />
|
|
|
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
|
|
|
|
</head><body>
|
|
|
|
|
|
<div class="document">
|
|
<div class="documentwrapper">
|
|
<div class="bodywrapper">
|
|
|
|
|
|
<div class="body" role="main">
|
|
|
|
<h1>Source code for osxphotos.photosdb.photosdb</h1><div class="highlight"><pre>
|
|
<span></span><span class="sd">"""</span>
|
|
<span class="sd">PhotosDB class</span>
|
|
<span class="sd">Processes a Photos.app library database to extract information about photos</span>
|
|
<span class="sd">"""</span>
|
|
|
|
<span class="kn">import</span> <span class="nn">logging</span>
|
|
<span class="kn">import</span> <span class="nn">os</span>
|
|
<span class="kn">import</span> <span class="nn">os.path</span>
|
|
<span class="kn">import</span> <span class="nn">pathlib</span>
|
|
<span class="kn">import</span> <span class="nn">platform</span>
|
|
<span class="kn">import</span> <span class="nn">re</span>
|
|
<span class="kn">import</span> <span class="nn">sys</span>
|
|
<span class="kn">import</span> <span class="nn">tempfile</span>
|
|
<span class="kn">from</span> <span class="nn">datetime</span> <span class="kn">import</span> <span class="n">datetime</span><span class="p">,</span> <span class="n">timedelta</span><span class="p">,</span> <span class="n">timezone</span>
|
|
<span class="kn">from</span> <span class="nn">pprint</span> <span class="kn">import</span> <span class="n">pformat</span>
|
|
<span class="kn">from</span> <span class="nn">typing</span> <span class="kn">import</span> <span class="n">List</span>
|
|
|
|
<span class="kn">import</span> <span class="nn">bitmath</span>
|
|
|
|
<span class="kn">from</span> <span class="nn">.._constants</span> <span class="kn">import</span> <span class="p">(</span>
|
|
<span class="n">_DB_TABLE_NAMES</span><span class="p">,</span>
|
|
<span class="n">_MOVIE_TYPE</span><span class="p">,</span>
|
|
<span class="n">_PHOTO_TYPE</span><span class="p">,</span>
|
|
<span class="n">_PHOTOS_3_VERSION</span><span class="p">,</span>
|
|
<span class="n">_PHOTOS_4_ALBUM_KIND</span><span class="p">,</span>
|
|
<span class="n">_PHOTOS_4_ROOT_FOLDER</span><span class="p">,</span>
|
|
<span class="n">_PHOTOS_4_TOP_LEVEL_ALBUM</span><span class="p">,</span>
|
|
<span class="n">_PHOTOS_4_VERSION</span><span class="p">,</span>
|
|
<span class="n">_PHOTOS_5_ALBUM_KIND</span><span class="p">,</span>
|
|
<span class="n">_PHOTOS_5_FOLDER_KIND</span><span class="p">,</span>
|
|
<span class="n">_PHOTOS_5_IMPORT_SESSION_ALBUM_KIND</span><span class="p">,</span>
|
|
<span class="n">_PHOTOS_5_ROOT_FOLDER_KIND</span><span class="p">,</span>
|
|
<span class="n">_PHOTOS_5_SHARED_ALBUM_KIND</span><span class="p">,</span>
|
|
<span class="n">_TESTED_OS_VERSIONS</span><span class="p">,</span>
|
|
<span class="n">_UNKNOWN_PERSON</span><span class="p">,</span>
|
|
<span class="n">BURST_KEY</span><span class="p">,</span>
|
|
<span class="n">BURST_SELECTED</span><span class="p">,</span>
|
|
<span class="n">TIME_DELTA</span><span class="p">,</span>
|
|
<span class="p">)</span>
|
|
<span class="kn">from</span> <span class="nn">.._version</span> <span class="kn">import</span> <span class="n">__version__</span>
|
|
<span class="kn">from</span> <span class="nn">..albuminfo</span> <span class="kn">import</span> <span class="n">AlbumInfo</span><span class="p">,</span> <span class="n">FolderInfo</span><span class="p">,</span> <span class="n">ImportInfo</span>
|
|
<span class="kn">from</span> <span class="nn">..datetime_utils</span> <span class="kn">import</span> <span class="n">datetime_has_tz</span><span class="p">,</span> <span class="n">datetime_naive_to_local</span>
|
|
<span class="kn">from</span> <span class="nn">..fileutil</span> <span class="kn">import</span> <span class="n">FileUtil</span>
|
|
<span class="kn">from</span> <span class="nn">..personinfo</span> <span class="kn">import</span> <span class="n">PersonInfo</span>
|
|
<span class="kn">from</span> <span class="nn">..photoinfo</span> <span class="kn">import</span> <span class="n">PhotoInfo</span>
|
|
<span class="kn">from</span> <span class="nn">..queryoptions</span> <span class="kn">import</span> <span class="n">QueryOptions</span>
|
|
<span class="kn">from</span> <span class="nn">..utils</span> <span class="kn">import</span> <span class="p">(</span>
|
|
<span class="n">_check_file_exists</span><span class="p">,</span>
|
|
<span class="n">_db_is_locked</span><span class="p">,</span>
|
|
<span class="n">_debug</span><span class="p">,</span>
|
|
<span class="n">_get_os_version</span><span class="p">,</span>
|
|
<span class="n">_open_sql_file</span><span class="p">,</span>
|
|
<span class="n">get_last_library_path</span><span class="p">,</span>
|
|
<span class="n">noop</span><span class="p">,</span>
|
|
<span class="n">normalize_unicode</span><span class="p">,</span>
|
|
<span class="p">)</span>
|
|
<span class="kn">from</span> <span class="nn">.photosdb_utils</span> <span class="kn">import</span> <span class="n">get_db_model_version</span><span class="p">,</span> <span class="n">get_db_version</span>
|
|
|
|
<span class="c1"># TODO: Add test for imageTimeZoneOffsetSeconds = None</span>
|
|
<span class="c1"># TODO: Add test for __str__</span>
|
|
<span class="c1"># TODO: Add special albums and magic albums</span>
|
|
|
|
|
|
<div class="viewcode-block" id="PhotosDB"><a class="viewcode-back" href="../../../reference.html#osxphotos.PhotosDB">[docs]</a><span class="k">class</span> <span class="nc">PhotosDB</span><span class="p">:</span>
|
|
<span class="sd">""" Processes a Photos.app library database to extract information about photos """</span>
|
|
|
|
<span class="c1"># import additional methods</span>
|
|
<span class="kn">from</span> <span class="nn">._photosdb_process_exif</span> <span class="kn">import</span> <span class="n">_process_exifinfo</span>
|
|
<span class="kn">from</span> <span class="nn">._photosdb_process_faceinfo</span> <span class="kn">import</span> <span class="n">_process_faceinfo</span>
|
|
<span class="kn">from</span> <span class="nn">._photosdb_process_searchinfo</span> <span class="kn">import</span> <span class="p">(</span>
|
|
<span class="n">_process_searchinfo</span><span class="p">,</span>
|
|
<span class="n">labels</span><span class="p">,</span>
|
|
<span class="n">labels_normalized</span><span class="p">,</span>
|
|
<span class="n">labels_as_dict</span><span class="p">,</span>
|
|
<span class="n">labels_normalized_as_dict</span><span class="p">,</span>
|
|
<span class="p">)</span>
|
|
<span class="kn">from</span> <span class="nn">._photosdb_process_scoreinfo</span> <span class="kn">import</span> <span class="n">_process_scoreinfo</span>
|
|
<span class="kn">from</span> <span class="nn">._photosdb_process_comments</span> <span class="kn">import</span> <span class="n">_process_comments</span>
|
|
|
|
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">dbfile</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">verbose</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">exiftool</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="sd">""" Create a new PhotosDB object.</span>
|
|
|
|
<span class="sd"> Args:</span>
|
|
<span class="sd"> dbfile: specify full path to photos library or photos.db; if None, will attempt to locate last library opened by Photos.</span>
|
|
<span class="sd"> verbose: optional callable function to use for printing verbose text during processing; if None (default), does not print output.</span>
|
|
<span class="sd"> exiftool: optional path to exiftool for methods that require this (e.g. PhotoInfo.exiftool); if not provided, will search PATH</span>
|
|
<span class="sd"> </span>
|
|
<span class="sd"> Raises:</span>
|
|
<span class="sd"> FileNotFoundError if dbfile is not a valid Photos library.</span>
|
|
<span class="sd"> TypeError if verbose is not None and not callable.</span>
|
|
<span class="sd"> """</span>
|
|
|
|
<span class="c1"># Check OS version</span>
|
|
<span class="n">system</span> <span class="o">=</span> <span class="n">platform</span><span class="o">.</span><span class="n">system</span><span class="p">()</span>
|
|
<span class="p">(</span><span class="n">ver</span><span class="p">,</span> <span class="n">major</span><span class="p">,</span> <span class="n">_</span><span class="p">)</span> <span class="o">=</span> <span class="n">_get_os_version</span><span class="p">()</span>
|
|
<span class="k">if</span> <span class="n">system</span> <span class="o">!=</span> <span class="s2">"Darwin"</span> <span class="ow">or</span> <span class="p">((</span><span class="n">ver</span><span class="p">,</span> <span class="n">major</span><span class="p">)</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">_TESTED_OS_VERSIONS</span><span class="p">):</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span>
|
|
<span class="sa">f</span><span class="s2">"WARNING: This module has only been tested with macOS versions "</span>
|
|
<span class="sa">f</span><span class="s2">"[</span><span class="si">{</span><span class="s1">', '</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="sa">f</span><span class="s1">'</span><span class="si">{</span><span class="n">v</span><span class="si">}</span><span class="s1">.</span><span class="si">{</span><span class="n">m</span><span class="si">}</span><span class="s1">'</span> <span class="k">for</span> <span class="p">(</span><span class="n">v</span><span class="p">,</span> <span class="n">m</span><span class="p">)</span> <span class="ow">in</span> <span class="n">_TESTED_OS_VERSIONS</span><span class="p">)</span><span class="si">}</span><span class="s2">]: "</span>
|
|
<span class="sa">f</span><span class="s2">"you have </span><span class="si">{</span><span class="n">system</span><span class="si">}</span><span class="s2">, OS version: </span><span class="si">{</span><span class="n">ver</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="n">major</span><span class="si">}</span><span class="s2">"</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="n">verbose</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="n">verbose</span> <span class="o">=</span> <span class="n">noop</span>
|
|
<span class="k">elif</span> <span class="ow">not</span> <span class="n">callable</span><span class="p">(</span><span class="n">verbose</span><span class="p">):</span>
|
|
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s2">"verbose must be callable"</span><span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_verbose</span> <span class="o">=</span> <span class="n">verbose</span>
|
|
|
|
<span class="c1"># enable beta features</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_beta</span> <span class="o">=</span> <span class="kc">False</span>
|
|
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_exiftool_path</span> <span class="o">=</span> <span class="n">exiftool</span>
|
|
|
|
<span class="c1"># create a temporary directory</span>
|
|
<span class="c1"># tempfile.TemporaryDirectory gets cleaned up when the object does</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_tempdir</span> <span class="o">=</span> <span class="n">tempfile</span><span class="o">.</span><span class="n">TemporaryDirectory</span><span class="p">(</span><span class="n">prefix</span><span class="o">=</span><span class="s2">"osxphotos_"</span><span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_tempdir_name</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_tempdir</span><span class="o">.</span><span class="n">name</span>
|
|
|
|
<span class="c1"># set up the data structures used to store all the Photo database info</span>
|
|
|
|
<span class="c1"># TODO: I don't think these keywords flags are actually used</span>
|
|
<span class="c1"># if True, will treat persons as keywords when exporting metadata</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">use_persons_as_keywords</span> <span class="o">=</span> <span class="kc">False</span>
|
|
|
|
<span class="c1"># if True, will treat albums as keywords when exporting metadata</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">use_albums_as_keywords</span> <span class="o">=</span> <span class="kc">False</span>
|
|
|
|
<span class="c1"># Path to the Photos library database file</span>
|
|
<span class="c1"># photos.db in the photos library database/ directory</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbfile</span> <span class="o">=</span> <span class="kc">None</span>
|
|
|
|
<span class="c1"># the actual file with library data</span>
|
|
<span class="c1"># in Photos 5 this is Photos.sqlite instead of photos.db</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbfile_actual</span> <span class="o">=</span> <span class="kc">None</span>
|
|
|
|
<span class="c1"># Dict with information about all photos by uuid</span>
|
|
<span class="c1"># This is the "master" data structure, built by process_database</span>
|
|
<span class="c1"># key is a photo UUID, value is a dictionary with all the information</span>
|
|
<span class="c1"># known about a photo</span>
|
|
<span class="c1"># this is built by joining data from multiple queries against the photos database</span>
|
|
<span class="c1"># several of the keys in the info dictionary point to other data structures described below</span>
|
|
<span class="c1"># e.g. self._dbphotos[uuid]["keywords"] = self._dbkeywords_uuid[uuid]</span>
|
|
<span class="c1"># self._dbphotos[uuid]["persons"] = self._dbfaces_uuid[uuid]</span>
|
|
<span class="c1"># self._dbphotos[uuid]["albums"] = self._dbalbums_uuid[uuid]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span> <span class="o">=</span> <span class="p">{}</span>
|
|
|
|
<span class="c1"># Dict with information about all burst photos by burst uuid</span>
|
|
<span class="c1"># key is UUID of the burst set, value is a set of photo UUIDs in the burst set</span>
|
|
<span class="c1"># e.g. {'BD94B7C0-2EB8-43DB-98B4-3B8E9653C255': {'8B386814-CA8A-42AA-BCA8-97C1AA746D8A', '52B95550-DE4A-44DD-9E67-89E979F2E97F'}}</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos_burst</span> <span class="o">=</span> <span class="p">{}</span>
|
|
|
|
<span class="c1"># Dict with additional information from RKMaster</span>
|
|
<span class="c1"># key is UUID from RKMaster, value is dict with info related to each master</span>
|
|
<span class="c1"># currently used to get information on RAW images</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos_master</span> <span class="o">=</span> <span class="p">{}</span>
|
|
|
|
<span class="c1"># Dict with information about all persons by person PK</span>
|
|
<span class="c1"># key is person PK, value is dict with info about each person</span>
|
|
<span class="c1"># e.g. {3: {"pk": 3, "fullname": "Maria Smith"...}}</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbpersons_pk</span> <span class="o">=</span> <span class="p">{}</span>
|
|
|
|
<span class="c1"># Dict with information about all persons by person fullname</span>
|
|
<span class="c1"># key is person PK, value is list of person PKs with fullname</span>
|
|
<span class="c1"># there may be more than one person PK with the same fullname</span>
|
|
<span class="c1"># e.g. {"Maria Smith": [1, 2]}</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbpersons_fullname</span> <span class="o">=</span> <span class="p">{}</span>
|
|
|
|
<span class="c1"># Dict with information about all persons/photos by uuid</span>
|
|
<span class="c1"># key is photo UUID, value is list of person primary keys of persons in the photo</span>
|
|
<span class="c1"># Note: Photos 5 identifies faces even if not given a name</span>
|
|
<span class="c1"># and those are labeled by process_database as _UNKNOWN_</span>
|
|
<span class="c1"># e.g. {'1EB2B765-0765-43BA-A90C-0D0580E6172C': [1, 3, 5]}</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbfaces_uuid</span> <span class="o">=</span> <span class="p">{}</span>
|
|
|
|
<span class="c1"># Dict with information about detected faces by person primary key</span>
|
|
<span class="c1"># key is person pk, value is list of photo UUIDs</span>
|
|
<span class="c1"># e.g. {3: ['E9BC5C36-7CD1-40A1-A72B-8B8FAC227D51']}</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbfaces_pk</span> <span class="o">=</span> <span class="p">{}</span>
|
|
|
|
<span class="c1"># Dict with information about all keywords/photos by uuid</span>
|
|
<span class="c1"># key is photo uuid and value is list of keywords</span>
|
|
<span class="c1"># e.g. {'1EB2B765-0765-43BA-A90C-0D0580E6172C': ['Kids']}</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbkeywords_uuid</span> <span class="o">=</span> <span class="p">{}</span>
|
|
|
|
<span class="c1"># Dict with information about all keywords/photos by keyword</span>
|
|
<span class="c1"># key is keyword and value is list of photo UUIDs that have that keyword</span>
|
|
<span class="c1"># e.g. {'England': ['DC99FBDD-7A52-4100-A5BB-344131646C30']}</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbkeywords_keyword</span> <span class="o">=</span> <span class="p">{}</span>
|
|
|
|
<span class="c1"># Dict with information about all albums/photos by uuid</span>
|
|
<span class="c1"># key is photo UUID, value is list of album UUIDs the photo is contained in</span>
|
|
<span class="c1"># e.g. {'1EB2B765-0765-43BA-A90C-0D0580E6172C': ['0C514A98-7B77-4E4F-801B-364B7B65EAFA']}</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbalbums_uuid</span> <span class="o">=</span> <span class="p">{}</span>
|
|
|
|
<span class="c1"># Dict with information about all albums/photos by primary key in the album database</span>
|
|
<span class="c1"># key is album pk, value is album uuid</span>
|
|
<span class="c1"># e.g. {'43': '0C514A98-7B77-4E4F-801B-364B7B65EAFA'}</span>
|
|
<span class="c1"># specific to Photos versions >= 5</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbalbums_pk</span> <span class="o">=</span> <span class="p">{}</span>
|
|
|
|
<span class="c1"># Dict with information about all albums/photos by album</span>
|
|
<span class="c1"># key is album UUID, value is list of tuples of (photo UUID, sort order) contained in that album</span>
|
|
<span class="c1"># e.g. {'0C514A98-7B77-4E4F-801B-364B7B65EAFA': [('1EB2B765-0765-43BA-A90C-0D0580E6172C', 1024)]}</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbalbums_album</span> <span class="o">=</span> <span class="p">{}</span>
|
|
|
|
<span class="c1"># Dict with information about album details</span>
|
|
<span class="c1"># key is album UUID, value is a dict with some additional details</span>
|
|
<span class="c1"># (mostly about cloud status) of the album</span>
|
|
<span class="c1"># e.g. {'0C514A98-7B77-4E4F-801B-364B7B65EAFA': {'cloudidentifier': None,</span>
|
|
<span class="c1"># 'cloudlibrarystate': None, 'cloudlocalstate': 0, 'cloudownderlastname': None,</span>
|
|
<span class="c1"># 'cloudownerfirstname': None, 'cloudownerhashedpersonid': None, 'title': 'Pumpkin Farm'}}</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbalbum_details</span> <span class="o">=</span> <span class="p">{}</span>
|
|
|
|
<span class="c1"># Dict with information about album titles</span>
|
|
<span class="c1"># key is title of album, value is list of album UUIDs with that title</span>
|
|
<span class="c1"># (It's possible to have more than one album with the same title)</span>
|
|
<span class="c1"># e.g. {'Pumpkin Farm': ['0C514A98-7B77-4E4F-801B-364B7B65EAFA']}</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbalbum_titles</span> <span class="o">=</span> <span class="p">{}</span>
|
|
|
|
<span class="c1"># Dict with information about all the file system volumes/photos by uuid</span>
|
|
<span class="c1"># key is volume UUID, value is name of file system volume</span>
|
|
<span class="c1"># e.g. {'8A0B2944-7B09-4D06-9AC3-4B0BF3F363F1': 'MacBook Mojave'}</span>
|
|
<span class="c1"># Used to find path of photos imported but not copied to the Photos library</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbvolumes</span> <span class="o">=</span> <span class="p">{}</span>
|
|
|
|
<span class="c1"># Dict with information about parent folders for folders and albums</span>
|
|
<span class="c1"># key is album or folder UUID and value is list of UUIDs of parent folder</span>
|
|
<span class="c1"># e.g. {'0C514A98-7B77-4E4F-801B-364B7B65EAFA': ['92D68107-B6C7-453B-96D2-97B0F26D5B8B'],}</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbalbum_parent_folders</span> <span class="o">=</span> <span class="p">{}</span>
|
|
|
|
<span class="c1"># Dict with information about folder hierarchy for each album / folder</span>
|
|
<span class="c1"># key is uuid of album / folder, value is dict with uuid of descendant folder / album</span>
|
|
<span class="c1"># structure is recursive as a descendant may itself have descendants</span>
|
|
<span class="c1"># e.g. {'AA4145F5-098C-496E-9197-B7584958FF9B': {'99D24D3E-59E7-465F-B386-A48A94B00BC1': {'F2246D82-1A12-4994-9654-3DC6FE38A7A8': None}}, }</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbalbum_folders</span> <span class="o">=</span> <span class="p">{}</span>
|
|
|
|
<span class="c1"># Dict with information about folders</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbfolder_details</span> <span class="o">=</span> <span class="p">{}</span>
|
|
|
|
<span class="c1"># Will hold the primary key of root folder</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_folder_root_pk</span> <span class="o">=</span> <span class="kc">None</span>
|
|
|
|
<span class="k">if</span> <span class="n">_debug</span><span class="p">():</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="sa">f</span><span class="s2">"dbfile = </span><span class="si">{</span><span class="n">dbfile</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="n">dbfile</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="n">dbfile</span> <span class="o">=</span> <span class="n">get_last_library_path</span><span class="p">()</span>
|
|
<span class="k">if</span> <span class="n">dbfile</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="c1"># get_last_library_path must have failed to find library</span>
|
|
<span class="k">raise</span> <span class="ne">FileNotFoundError</span><span class="p">(</span><span class="s2">"Could not get path to photo library database"</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">isdir</span><span class="p">(</span><span class="n">dbfile</span><span class="p">):</span>
|
|
<span class="c1"># passed a directory, assume it's a photoslibrary</span>
|
|
<span class="n">dbfile</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">dbfile</span><span class="p">,</span> <span class="s2">"database/photos.db"</span><span class="p">)</span>
|
|
|
|
<span class="c1"># if get here, should have a dbfile path; make sure it exists</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">_check_file_exists</span><span class="p">(</span><span class="n">dbfile</span><span class="p">):</span>
|
|
<span class="k">raise</span> <span class="ne">FileNotFoundError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"dbfile </span><span class="si">{</span><span class="n">dbfile</span><span class="si">}</span><span class="s2"> does not exist"</span><span class="p">,</span> <span class="n">dbfile</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="n">_debug</span><span class="p">():</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="sa">f</span><span class="s2">"dbfile = </span><span class="si">{</span><span class="n">dbfile</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
|
|
|
|
<span class="c1"># init database names</span>
|
|
<span class="c1"># _tmp_db is the file that will processed by _process_database4/5</span>
|
|
<span class="c1"># assume _tmp_db will be _dbfile or _dbfile_actual based on Photos version</span>
|
|
<span class="c1"># unless DB is locked, in which case _tmp_db will point to a temporary copy</span>
|
|
<span class="c1"># if Photos <=4, _dbfile = _dbfile_actual = photos.db</span>
|
|
<span class="c1"># if Photos >= 5, _dbfile = photos.db, from which we get DB version but the actual</span>
|
|
<span class="c1"># photos data is in Photos.sqlite</span>
|
|
<span class="c1"># In either case, a temporary copy will be made if the DB is locked by Photos</span>
|
|
<span class="c1"># or photosanalysisd</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbfile</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbfile_actual</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_tmp_db</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">abspath</span><span class="p">(</span><span class="n">dbfile</span><span class="p">)</span>
|
|
|
|
<span class="n">verbose</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Processing database </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbfile</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
|
|
|
|
<span class="c1"># if database is exclusively locked, make a copy of it and use the copy</span>
|
|
<span class="c1"># Photos maintains an exclusive lock on the database file while Photos is open</span>
|
|
<span class="c1"># photoanalysisd sometimes maintains this lock even after Photos is closed</span>
|
|
<span class="c1"># In those cases, make a temp copy of the file for sqlite3 to read</span>
|
|
<span class="k">if</span> <span class="n">_db_is_locked</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbfile</span><span class="p">):</span>
|
|
<span class="n">verbose</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Database locked, creating temporary copy."</span><span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_tmp_db</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_copy_db_file</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbfile</span><span class="p">)</span>
|
|
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_db_version</span> <span class="o">=</span> <span class="n">get_db_version</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_tmp_db</span><span class="p">)</span>
|
|
|
|
<span class="c1"># If Photos >= 5, actual data isn't in photos.db but in Photos.sqlite</span>
|
|
<span class="k">if</span> <span class="nb">int</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_db_version</span><span class="p">)</span> <span class="o">></span> <span class="nb">int</span><span class="p">(</span><span class="n">_PHOTOS_4_VERSION</span><span class="p">):</span>
|
|
<span class="n">dbpath</span> <span class="o">=</span> <span class="n">pathlib</span><span class="o">.</span><span class="n">Path</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbfile</span><span class="p">)</span><span class="o">.</span><span class="n">parent</span>
|
|
<span class="n">dbfile</span> <span class="o">=</span> <span class="n">dbpath</span> <span class="o">/</span> <span class="s2">"Photos.sqlite"</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">_check_file_exists</span><span class="p">(</span><span class="n">dbfile</span><span class="p">):</span>
|
|
<span class="k">raise</span> <span class="ne">FileNotFoundError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"dbfile </span><span class="si">{</span><span class="n">dbfile</span><span class="si">}</span><span class="s2"> does not exist"</span><span class="p">,</span> <span class="n">dbfile</span><span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbfile_actual</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_tmp_db</span> <span class="o">=</span> <span class="n">dbfile</span>
|
|
<span class="n">verbose</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Processing database </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbfile_actual</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
|
|
<span class="c1"># if database is exclusively locked, make a copy of it and use the copy</span>
|
|
<span class="k">if</span> <span class="n">_db_is_locked</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbfile_actual</span><span class="p">):</span>
|
|
<span class="n">verbose</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Database locked, creating temporary copy."</span><span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_tmp_db</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_copy_db_file</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbfile_actual</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="n">_debug</span><span class="p">():</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span>
|
|
<span class="sa">f</span><span class="s2">"_dbfile = </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbfile</span><span class="si">}</span><span class="s2">, _dbfile_actual = </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbfile_actual</span><span class="si">}</span><span class="s2">"</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="n">library_path</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">dirname</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">abspath</span><span class="p">(</span><span class="n">dbfile</span><span class="p">))</span>
|
|
<span class="p">(</span><span class="n">library_path</span><span class="p">,</span> <span class="n">_</span><span class="p">)</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="n">library_path</span><span class="p">)</span> <span class="c1"># drop /database from path</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_library_path</span> <span class="o">=</span> <span class="n">library_path</span>
|
|
<span class="k">if</span> <span class="nb">int</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_db_version</span><span class="p">)</span> <span class="o"><=</span> <span class="nb">int</span><span class="p">(</span><span class="n">_PHOTOS_4_VERSION</span><span class="p">):</span>
|
|
<span class="n">masters_path</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">library_path</span><span class="p">,</span> <span class="s2">"Masters"</span><span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_masters_path</span> <span class="o">=</span> <span class="n">masters_path</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">masters_path</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">library_path</span><span class="p">,</span> <span class="s2">"originals"</span><span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_masters_path</span> <span class="o">=</span> <span class="n">masters_path</span>
|
|
|
|
<span class="k">if</span> <span class="n">_debug</span><span class="p">():</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="sa">f</span><span class="s2">"library = </span><span class="si">{</span><span class="n">library_path</span><span class="si">}</span><span class="s2">, masters = </span><span class="si">{</span><span class="n">masters_path</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="nb">int</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_db_version</span><span class="p">)</span> <span class="o"><=</span> <span class="nb">int</span><span class="p">(</span><span class="n">_PHOTOS_4_VERSION</span><span class="p">):</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_process_database4</span><span class="p">()</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_process_database5</span><span class="p">()</span>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="k">def</span> <span class="nf">keywords_as_dict</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">""" return keywords as dict of keyword, count in reverse sorted order (descending) """</span>
|
|
<span class="n">keywords</span> <span class="o">=</span> <span class="p">{</span>
|
|
<span class="n">k</span><span class="p">:</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbkeywords_keyword</span><span class="p">[</span><span class="n">k</span><span class="p">])</span> <span class="k">for</span> <span class="n">k</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbkeywords_keyword</span><span class="o">.</span><span class="n">keys</span><span class="p">()</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="n">keywords</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">(</span><span class="nb">sorted</span><span class="p">(</span><span class="n">keywords</span><span class="o">.</span><span class="n">items</span><span class="p">(),</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">kv</span><span class="p">:</span> <span class="n">kv</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">reverse</span><span class="o">=</span><span class="kc">True</span><span class="p">))</span>
|
|
<span class="k">return</span> <span class="n">keywords</span>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="k">def</span> <span class="nf">persons_as_dict</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">""" return persons as dict of person, count in reverse sorted order (descending) """</span>
|
|
<span class="n">persons</span> <span class="o">=</span> <span class="p">{}</span>
|
|
<span class="k">for</span> <span class="n">pk</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbfaces_pk</span><span class="p">:</span>
|
|
<span class="n">fullname</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbpersons_pk</span><span class="p">[</span><span class="n">pk</span><span class="p">][</span><span class="s2">"fullname"</span><span class="p">]</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">persons</span><span class="p">[</span><span class="n">fullname</span><span class="p">]</span> <span class="o">+=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbfaces_pk</span><span class="p">[</span><span class="n">pk</span><span class="p">])</span>
|
|
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
|
|
<span class="n">persons</span><span class="p">[</span><span class="n">fullname</span><span class="p">]</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbfaces_pk</span><span class="p">[</span><span class="n">pk</span><span class="p">])</span>
|
|
<span class="n">persons</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">(</span><span class="nb">sorted</span><span class="p">(</span><span class="n">persons</span><span class="o">.</span><span class="n">items</span><span class="p">(),</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">kv</span><span class="p">:</span> <span class="n">kv</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">reverse</span><span class="o">=</span><span class="kc">True</span><span class="p">))</span>
|
|
<span class="k">return</span> <span class="n">persons</span>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="k">def</span> <span class="nf">albums_as_dict</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">""" return albums as dict of albums, count in reverse sorted order (descending) """</span>
|
|
<span class="n">albums</span> <span class="o">=</span> <span class="p">{}</span>
|
|
<span class="n">album_keys</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_album_uuids</span><span class="p">(</span><span class="n">shared</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
|
|
<span class="k">for</span> <span class="n">album</span> <span class="ow">in</span> <span class="n">album_keys</span><span class="p">:</span>
|
|
<span class="n">title</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbalbum_details</span><span class="p">[</span><span class="n">album</span><span class="p">][</span><span class="s2">"title"</span><span class="p">]</span>
|
|
<span class="k">if</span> <span class="n">album</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbalbums_album</span><span class="p">:</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">albums</span><span class="p">[</span><span class="n">title</span><span class="p">]</span> <span class="o">+=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbalbums_album</span><span class="p">[</span><span class="n">album</span><span class="p">])</span>
|
|
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
|
|
<span class="n">albums</span><span class="p">[</span><span class="n">title</span><span class="p">]</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbalbums_album</span><span class="p">[</span><span class="n">album</span><span class="p">])</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">albums</span><span class="p">[</span><span class="n">title</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span> <span class="c1"># empty album</span>
|
|
<span class="n">albums</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">(</span><span class="nb">sorted</span><span class="p">(</span><span class="n">albums</span><span class="o">.</span><span class="n">items</span><span class="p">(),</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">kv</span><span class="p">:</span> <span class="n">kv</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">reverse</span><span class="o">=</span><span class="kc">True</span><span class="p">))</span>
|
|
<span class="k">return</span> <span class="n">albums</span>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="k">def</span> <span class="nf">albums_shared_as_dict</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">""" returns shared albums as dict of albums, count in reverse sorted order (descending)</span>
|
|
<span class="sd"> valid only on Photos 5; on Photos <= 4, prints warning and returns empty dict """</span>
|
|
|
|
<span class="n">albums</span> <span class="o">=</span> <span class="p">{}</span>
|
|
<span class="n">album_keys</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_album_uuids</span><span class="p">(</span><span class="n">shared</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
|
|
<span class="k">for</span> <span class="n">album</span> <span class="ow">in</span> <span class="n">album_keys</span><span class="p">:</span>
|
|
<span class="n">title</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbalbum_details</span><span class="p">[</span><span class="n">album</span><span class="p">][</span><span class="s2">"title"</span><span class="p">]</span>
|
|
<span class="k">if</span> <span class="n">album</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbalbums_album</span><span class="p">:</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">albums</span><span class="p">[</span><span class="n">title</span><span class="p">]</span> <span class="o">+=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbalbums_album</span><span class="p">[</span><span class="n">album</span><span class="p">])</span>
|
|
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
|
|
<span class="n">albums</span><span class="p">[</span><span class="n">title</span><span class="p">]</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbalbums_album</span><span class="p">[</span><span class="n">album</span><span class="p">])</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">albums</span><span class="p">[</span><span class="n">title</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span> <span class="c1"># empty album</span>
|
|
<span class="n">albums</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">(</span><span class="nb">sorted</span><span class="p">(</span><span class="n">albums</span><span class="o">.</span><span class="n">items</span><span class="p">(),</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">kv</span><span class="p">:</span> <span class="n">kv</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">reverse</span><span class="o">=</span><span class="kc">True</span><span class="p">))</span>
|
|
<span class="k">return</span> <span class="n">albums</span>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="k">def</span> <span class="nf">keywords</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">""" return list of keywords found in photos database """</span>
|
|
<span class="n">keywords</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbkeywords_keyword</span><span class="o">.</span><span class="n">keys</span><span class="p">()</span>
|
|
<span class="k">return</span> <span class="nb">list</span><span class="p">(</span><span class="n">keywords</span><span class="p">)</span>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="k">def</span> <span class="nf">persons</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">""" return list of persons found in photos database """</span>
|
|
<span class="n">persons</span> <span class="o">=</span> <span class="p">{</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbpersons_pk</span><span class="p">[</span><span class="n">k</span><span class="p">][</span><span class="s2">"fullname"</span><span class="p">]</span> <span class="k">for</span> <span class="n">k</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbfaces_pk</span><span class="p">}</span>
|
|
<span class="k">return</span> <span class="nb">list</span><span class="p">(</span><span class="n">persons</span><span class="p">)</span>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="k">def</span> <span class="nf">person_info</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">""" return list of PersonInfo objects for each person in the photos database """</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_person_info</span>
|
|
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_person_info</span> <span class="o">=</span> <span class="p">[</span>
|
|
<span class="n">PersonInfo</span><span class="p">(</span><span class="n">db</span><span class="o">=</span><span class="bp">self</span><span class="p">,</span> <span class="n">pk</span><span class="o">=</span><span class="n">pk</span><span class="p">)</span> <span class="k">for</span> <span class="n">pk</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbpersons_pk</span>
|
|
<span class="p">]</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_person_info</span>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="k">def</span> <span class="nf">folder_info</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">""" return list FolderInfo objects representing top-level folders in the photos database """</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db_version</span> <span class="o"><=</span> <span class="n">_PHOTOS_4_VERSION</span><span class="p">:</span>
|
|
<span class="n">folders</span> <span class="o">=</span> <span class="p">[</span>
|
|
<span class="n">FolderInfo</span><span class="p">(</span><span class="n">db</span><span class="o">=</span><span class="bp">self</span><span class="p">,</span> <span class="n">uuid</span><span class="o">=</span><span class="n">folder</span><span class="p">)</span>
|
|
<span class="k">for</span> <span class="n">folder</span><span class="p">,</span> <span class="n">detail</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbfolder_details</span><span class="o">.</span><span class="n">items</span><span class="p">()</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">detail</span><span class="p">[</span><span class="s2">"intrash"</span><span class="p">]</span>
|
|
<span class="ow">and</span> <span class="ow">not</span> <span class="n">detail</span><span class="p">[</span><span class="s2">"isMagic"</span><span class="p">]</span>
|
|
<span class="ow">and</span> <span class="n">detail</span><span class="p">[</span><span class="s2">"parentFolderUuid"</span><span class="p">]</span> <span class="o">==</span> <span class="n">_PHOTOS_4_TOP_LEVEL_ALBUM</span>
|
|
<span class="p">]</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">folders</span> <span class="o">=</span> <span class="p">[</span>
|
|
<span class="n">FolderInfo</span><span class="p">(</span><span class="n">db</span><span class="o">=</span><span class="bp">self</span><span class="p">,</span> <span class="n">uuid</span><span class="o">=</span><span class="n">album</span><span class="p">)</span>
|
|
<span class="k">for</span> <span class="n">album</span><span class="p">,</span> <span class="n">detail</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbalbum_details</span><span class="o">.</span><span class="n">items</span><span class="p">()</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">detail</span><span class="p">[</span><span class="s2">"intrash"</span><span class="p">]</span>
|
|
<span class="ow">and</span> <span class="n">detail</span><span class="p">[</span><span class="s2">"kind"</span><span class="p">]</span> <span class="o">==</span> <span class="n">_PHOTOS_5_FOLDER_KIND</span>
|
|
<span class="ow">and</span> <span class="n">detail</span><span class="p">[</span><span class="s2">"parentfolder"</span><span class="p">]</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">_folder_root_pk</span>
|
|
<span class="p">]</span>
|
|
<span class="k">return</span> <span class="n">folders</span>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="k">def</span> <span class="nf">folders</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">""" return list of top-level folder names in the photos database """</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db_version</span> <span class="o"><=</span> <span class="n">_PHOTOS_4_VERSION</span><span class="p">:</span>
|
|
<span class="n">folder_names</span> <span class="o">=</span> <span class="p">[</span>
|
|
<span class="n">folder</span><span class="p">[</span><span class="s2">"name"</span><span class="p">]</span>
|
|
<span class="k">for</span> <span class="n">folder</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbfolder_details</span><span class="o">.</span><span class="n">values</span><span class="p">()</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">folder</span><span class="p">[</span><span class="s2">"intrash"</span><span class="p">]</span>
|
|
<span class="ow">and</span> <span class="ow">not</span> <span class="n">folder</span><span class="p">[</span><span class="s2">"isMagic"</span><span class="p">]</span>
|
|
<span class="ow">and</span> <span class="n">folder</span><span class="p">[</span><span class="s2">"parentFolderUuid"</span><span class="p">]</span> <span class="o">==</span> <span class="n">_PHOTOS_4_TOP_LEVEL_ALBUM</span>
|
|
<span class="p">]</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">folder_names</span> <span class="o">=</span> <span class="p">[</span>
|
|
<span class="n">detail</span><span class="p">[</span><span class="s2">"title"</span><span class="p">]</span>
|
|
<span class="k">for</span> <span class="n">detail</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbalbum_details</span><span class="o">.</span><span class="n">values</span><span class="p">()</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">detail</span><span class="p">[</span><span class="s2">"intrash"</span><span class="p">]</span>
|
|
<span class="ow">and</span> <span class="n">detail</span><span class="p">[</span><span class="s2">"kind"</span><span class="p">]</span> <span class="o">==</span> <span class="n">_PHOTOS_5_FOLDER_KIND</span>
|
|
<span class="ow">and</span> <span class="n">detail</span><span class="p">[</span><span class="s2">"parentfolder"</span><span class="p">]</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">_folder_root_pk</span>
|
|
<span class="p">]</span>
|
|
<span class="k">return</span> <span class="n">folder_names</span>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="k">def</span> <span class="nf">album_info</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">""" return list of AlbumInfo objects for each album in the photos database """</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_album_info</span>
|
|
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_album_info</span> <span class="o">=</span> <span class="p">[</span>
|
|
<span class="n">AlbumInfo</span><span class="p">(</span><span class="n">db</span><span class="o">=</span><span class="bp">self</span><span class="p">,</span> <span class="n">uuid</span><span class="o">=</span><span class="n">album</span><span class="p">)</span>
|
|
<span class="k">for</span> <span class="n">album</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_album_uuids</span><span class="p">(</span><span class="n">shared</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
|
|
<span class="p">]</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_album_info</span>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="k">def</span> <span class="nf">album_info_shared</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">""" return list of AlbumInfo objects for each shared album in the photos database</span>
|
|
<span class="sd"> only valid for Photos 5; on Photos <= 4, prints warning and returns empty list """</span>
|
|
<span class="c1"># if _dbalbum_details[key]["cloudownerhashedpersonid"] is not None, then it's a shared album</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_album_info_shared</span>
|
|
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_album_info_shared</span> <span class="o">=</span> <span class="p">[</span>
|
|
<span class="n">AlbumInfo</span><span class="p">(</span><span class="n">db</span><span class="o">=</span><span class="bp">self</span><span class="p">,</span> <span class="n">uuid</span><span class="o">=</span><span class="n">album</span><span class="p">)</span>
|
|
<span class="k">for</span> <span class="n">album</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_album_uuids</span><span class="p">(</span><span class="n">shared</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
|
|
<span class="p">]</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_album_info_shared</span>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="k">def</span> <span class="nf">albums</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">""" return list of albums found in photos database """</span>
|
|
|
|
<span class="c1"># Could be more than one album with same name</span>
|
|
<span class="c1"># Right now, they are treated as same album and photos are combined from albums with same name</span>
|
|
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_albums</span>
|
|
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_albums</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_albums</span><span class="p">(</span><span class="n">shared</span><span class="o">=</span><span class="kc">False</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_albums</span>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="k">def</span> <span class="nf">albums_shared</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">""" return list of shared albums found in photos database</span>
|
|
<span class="sd"> only valid for Photos 5; on Photos <= 4, prints warning and returns empty list """</span>
|
|
|
|
<span class="c1"># Could be more than one album with same name</span>
|
|
<span class="c1"># Right now, they are treated as same album and photos are combined from albums with same name</span>
|
|
|
|
<span class="c1"># if _dbalbum_details[key]["cloudownerhashedpersonid"] is not None, then it's a shared album</span>
|
|
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_albums_shared</span>
|
|
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_albums_shared</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_albums</span><span class="p">(</span><span class="n">shared</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_albums_shared</span>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="k">def</span> <span class="nf">import_info</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">""" return list of ImportInfo objects for each import session in the database """</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_import_info</span>
|
|
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_import_info</span> <span class="o">=</span> <span class="p">[</span>
|
|
<span class="n">ImportInfo</span><span class="p">(</span><span class="n">db</span><span class="o">=</span><span class="bp">self</span><span class="p">,</span> <span class="n">uuid</span><span class="o">=</span><span class="n">album</span><span class="p">)</span>
|
|
<span class="k">for</span> <span class="n">album</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_album_uuids</span><span class="p">(</span><span class="n">import_session</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
|
|
<span class="p">]</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_import_info</span>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="k">def</span> <span class="nf">db_version</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">""" return the database version as stored in LiGlobals table """</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db_version</span>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="k">def</span> <span class="nf">db_path</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">""" returns path to the Photos library database PhotosDB was initialized with """</span>
|
|
<span class="k">return</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">abspath</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbfile</span><span class="p">)</span>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="k">def</span> <span class="nf">library_path</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">""" returns path to the Photos library PhotosDB was initialized with """</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_library_path</span>
|
|
|
|
<div class="viewcode-block" id="PhotosDB.get_db_connection"><a class="viewcode-back" href="../../../reference.html#osxphotos.PhotosDB.get_db_connection">[docs]</a> <span class="k">def</span> <span class="nf">get_db_connection</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">""" Get connection to the working copy of the Photos database </span>
|
|
|
|
<span class="sd"> Returns:</span>
|
|
<span class="sd"> tuple of (connection, cursor) to sqlite3 database</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">return</span> <span class="n">_open_sql_file</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_tmp_db</span><span class="p">)</span></div>
|
|
|
|
<span class="k">def</span> <span class="nf">_copy_db_file</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">fname</span><span class="p">):</span>
|
|
<span class="sd">""" copies the sqlite database file to a temp file """</span>
|
|
<span class="sd">""" returns the name of the temp file """</span>
|
|
<span class="sd">""" If sqlite shared memory and write-ahead log files exist, those are copied too """</span>
|
|
<span class="c1"># required because python's sqlite3 implementation can't read a locked file</span>
|
|
<span class="c1"># _, suffix = os.path.splitext(fname)</span>
|
|
<span class="n">dest_name</span> <span class="o">=</span> <span class="n">dest_path</span> <span class="o">=</span> <span class="s2">""</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">dest_name</span> <span class="o">=</span> <span class="n">pathlib</span><span class="o">.</span><span class="n">Path</span><span class="p">(</span><span class="n">fname</span><span class="p">)</span><span class="o">.</span><span class="n">name</span>
|
|
<span class="n">dest_path</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_tempdir_name</span><span class="p">,</span> <span class="n">dest_name</span><span class="p">)</span>
|
|
<span class="n">FileUtil</span><span class="o">.</span><span class="n">copy</span><span class="p">(</span><span class="n">fname</span><span class="p">,</span> <span class="n">dest_path</span><span class="p">)</span>
|
|
<span class="c1"># copy write-ahead log and shared memory files (-wal and -shm) files if they exist</span>
|
|
<span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">fname</span><span class="si">}</span><span class="s2">-wal"</span><span class="p">):</span>
|
|
<span class="n">FileUtil</span><span class="o">.</span><span class="n">copy</span><span class="p">(</span><span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">fname</span><span class="si">}</span><span class="s2">-wal"</span><span class="p">,</span> <span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">dest_path</span><span class="si">}</span><span class="s2">-wal"</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">(</span><span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">fname</span><span class="si">}</span><span class="s2">-shm"</span><span class="p">):</span>
|
|
<span class="n">FileUtil</span><span class="o">.</span><span class="n">copy</span><span class="p">(</span><span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">fname</span><span class="si">}</span><span class="s2">-shm"</span><span class="p">,</span> <span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">dest_path</span><span class="si">}</span><span class="s2">-shm"</span><span class="p">)</span>
|
|
<span class="k">except</span><span class="p">:</span>
|
|
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Error copying</span><span class="si">{</span><span class="n">fname</span><span class="si">}</span><span class="s2"> to </span><span class="si">{</span><span class="n">dest_path</span><span class="si">}</span><span class="s2">"</span><span class="p">,</span> <span class="n">file</span><span class="o">=</span><span class="n">sys</span><span class="o">.</span><span class="n">stderr</span><span class="p">)</span>
|
|
<span class="k">raise</span> <span class="ne">Exception</span>
|
|
|
|
<span class="k">if</span> <span class="n">_debug</span><span class="p">():</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">dest_path</span><span class="p">)</span>
|
|
|
|
<span class="k">return</span> <span class="n">dest_path</span>
|
|
|
|
<span class="c1"># NOTE: This method seems to cause problems with applescript</span>
|
|
<span class="c1"># Bummer...would'be been nice to avoid copying the DB</span>
|
|
<span class="c1"># def _link_db_file(self, fname):</span>
|
|
<span class="c1"># """ links the sqlite database file to a temp file """</span>
|
|
<span class="c1"># """ returns the name of the temp file """</span>
|
|
<span class="c1"># """ If sqlite shared memory and write-ahead log files exist, those are copied too """</span>
|
|
<span class="c1"># # required because python's sqlite3 implementation can't read a locked file</span>
|
|
<span class="c1"># # _, suffix = os.path.splitext(fname)</span>
|
|
<span class="c1"># dest_name = dest_path = ""</span>
|
|
<span class="c1"># try:</span>
|
|
<span class="c1"># dest_name = pathlib.Path(fname).name</span>
|
|
<span class="c1"># dest_path = os.path.join(self._tempdir_name, dest_name)</span>
|
|
<span class="c1"># FileUtil.hardlink(fname, dest_path)</span>
|
|
<span class="c1"># # link write-ahead log and shared memory files (-wal and -shm) files if they exist</span>
|
|
<span class="c1"># if os.path.exists(f"{fname}-wal"):</span>
|
|
<span class="c1"># FileUtil.hardlink(f"{fname}-wal", f"{dest_path}-wal")</span>
|
|
<span class="c1"># if os.path.exists(f"{fname}-shm"):</span>
|
|
<span class="c1"># FileUtil.hardlink(f"{fname}-shm", f"{dest_path}-shm")</span>
|
|
<span class="c1"># except:</span>
|
|
<span class="c1"># print("Error linking " + fname + " to " + dest_path, file=sys.stderr)</span>
|
|
<span class="c1"># raise Exception</span>
|
|
|
|
<span class="c1"># if _debug():</span>
|
|
<span class="c1"># logging.debug(dest_path)</span>
|
|
|
|
<span class="c1"># return dest_path</span>
|
|
|
|
<span class="k">def</span> <span class="nf">_process_database4</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">""" process the Photos database to extract info</span>
|
|
<span class="sd"> works on Photos version <= 4.0 """</span>
|
|
|
|
<span class="n">verbose</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_verbose</span>
|
|
<span class="n">verbose</span><span class="p">(</span><span class="s2">"Processing database."</span><span class="p">)</span>
|
|
<span class="n">verbose</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Database version: </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">_db_version</span><span class="si">}</span><span class="s2">."</span><span class="p">)</span>
|
|
|
|
<span class="p">(</span><span class="n">conn</span><span class="p">,</span> <span class="n">c</span><span class="p">)</span> <span class="o">=</span> <span class="n">_open_sql_file</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_tmp_db</span><span class="p">)</span>
|
|
|
|
<span class="c1"># get info to associate persons with photos</span>
|
|
<span class="c1"># then get detected faces in each photo and link to persons</span>
|
|
<span class="n">verbose</span><span class="p">(</span><span class="s2">"Processing persons in photos."</span><span class="p">)</span>
|
|
<span class="n">c</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span>
|
|
<span class="sd">""" SELECT</span>
|
|
<span class="sd"> RKPerson.modelID,</span>
|
|
<span class="sd"> RKPerson.uuid,</span>
|
|
<span class="sd"> RKPerson.name,</span>
|
|
<span class="sd"> RKPerson.faceCount,</span>
|
|
<span class="sd"> RKPerson.displayName,</span>
|
|
<span class="sd"> RKPerson.representativeFaceId</span>
|
|
<span class="sd"> FROM RKPerson</span>
|
|
<span class="sd"> """</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="c1"># 0 RKPerson.modelID,</span>
|
|
<span class="c1"># 1 RKPerson.uuid,</span>
|
|
<span class="c1"># 2 RKPerson.name,</span>
|
|
<span class="c1"># 3 RKPerson.faceCount,</span>
|
|
<span class="c1"># 4 RKPerson.displayName</span>
|
|
<span class="c1"># 5 RKPerson.representativeFaceId</span>
|
|
|
|
<span class="k">for</span> <span class="n">person</span> <span class="ow">in</span> <span class="n">c</span><span class="p">:</span>
|
|
<span class="n">pk</span> <span class="o">=</span> <span class="n">person</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
|
<span class="n">fullname</span> <span class="o">=</span> <span class="n">person</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="k">if</span> <span class="n">person</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="k">else</span> <span class="n">_UNKNOWN_PERSON</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbpersons_pk</span><span class="p">[</span><span class="n">pk</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span>
|
|
<span class="s2">"pk"</span><span class="p">:</span> <span class="n">pk</span><span class="p">,</span>
|
|
<span class="s2">"uuid"</span><span class="p">:</span> <span class="n">person</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span>
|
|
<span class="s2">"fullname"</span><span class="p">:</span> <span class="n">fullname</span><span class="p">,</span>
|
|
<span class="s2">"facecount"</span><span class="p">:</span> <span class="n">person</span><span class="p">[</span><span class="mi">3</span><span class="p">],</span>
|
|
<span class="s2">"keyface"</span><span class="p">:</span> <span class="n">person</span><span class="p">[</span><span class="mi">5</span><span class="p">],</span>
|
|
<span class="s2">"displayname"</span><span class="p">:</span> <span class="n">person</span><span class="p">[</span><span class="mi">4</span><span class="p">],</span>
|
|
<span class="s2">"photo_uuid"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
|
|
<span class="s2">"keyface_uuid"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
|
|
<span class="p">}</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbpersons_fullname</span><span class="p">[</span><span class="n">fullname</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">pk</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbpersons_fullname</span><span class="p">[</span><span class="n">fullname</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="n">pk</span><span class="p">]</span>
|
|
|
|
<span class="c1"># get info on key face</span>
|
|
<span class="n">c</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span>
|
|
<span class="sd">""" SELECT</span>
|
|
<span class="sd"> RKPerson.modelID,</span>
|
|
<span class="sd"> RKPerson.representativeFaceId,</span>
|
|
<span class="sd"> RKVersion.uuid,</span>
|
|
<span class="sd"> RKFace.uuid</span>
|
|
<span class="sd"> FROM RKPerson, RKFace, RKVersion</span>
|
|
<span class="sd"> WHERE </span>
|
|
<span class="sd"> RKFace.modelId = RKPerson.representativeFaceId AND</span>
|
|
<span class="sd"> RKVersion.modelId = RKFace.ImageModelId</span>
|
|
<span class="sd"> """</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="c1"># 0 RKPerson.modelID,</span>
|
|
<span class="c1"># 1 RKPerson.representativeFaceId</span>
|
|
<span class="c1"># 2 RKVersion.uuid,</span>
|
|
<span class="c1"># 3 RKFace.uuid</span>
|
|
|
|
<span class="k">for</span> <span class="n">person</span> <span class="ow">in</span> <span class="n">c</span><span class="p">:</span>
|
|
<span class="n">pk</span> <span class="o">=</span> <span class="n">person</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbpersons_pk</span><span class="p">[</span><span class="n">pk</span><span class="p">][</span><span class="s2">"photo_uuid"</span><span class="p">]</span> <span class="o">=</span> <span class="n">person</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbpersons_pk</span><span class="p">[</span><span class="n">pk</span><span class="p">][</span><span class="s2">"keyface_uuid"</span><span class="p">]</span> <span class="o">=</span> <span class="n">person</span><span class="p">[</span><span class="mi">3</span><span class="p">]</span>
|
|
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Unexpected KeyError _dbpersons_pk[</span><span class="si">{</span><span class="n">pk</span><span class="si">}</span><span class="s2">]"</span><span class="p">)</span>
|
|
|
|
<span class="c1"># get information on detected faces</span>
|
|
<span class="n">verbose</span><span class="p">(</span><span class="s2">"Processing detected faces in photos."</span><span class="p">)</span>
|
|
<span class="n">c</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span>
|
|
<span class="sd">""" SELECT </span>
|
|
<span class="sd"> RKPerson.modelID,</span>
|
|
<span class="sd"> RKVersion.uuid </span>
|
|
<span class="sd"> FROM </span>
|
|
<span class="sd"> RKFace, RKPerson, RKVersion, RKMaster </span>
|
|
<span class="sd"> WHERE </span>
|
|
<span class="sd"> RKFace.personID = RKperson.modelID AND </span>
|
|
<span class="sd"> RKVersion.modelId = RKFace.ImageModelId AND</span>
|
|
<span class="sd"> RKVersion.masterUuid = RKMaster.uuid </span>
|
|
<span class="sd"> """</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="c1"># 0 RKPerson.modelID</span>
|
|
<span class="c1"># 1 RKVersion.uuid</span>
|
|
|
|
<span class="k">for</span> <span class="n">face</span> <span class="ow">in</span> <span class="n">c</span><span class="p">:</span>
|
|
<span class="n">pk</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
|
<span class="n">uuid</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbfaces_uuid</span><span class="p">[</span><span class="n">uuid</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">pk</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbfaces_uuid</span><span class="p">[</span><span class="n">uuid</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="n">pk</span><span class="p">]</span>
|
|
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbfaces_pk</span><span class="p">[</span><span class="n">pk</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">uuid</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbfaces_pk</span><span class="p">[</span><span class="n">pk</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="n">uuid</span><span class="p">]</span>
|
|
|
|
<span class="k">if</span> <span class="n">_debug</span><span class="p">():</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Finished walking through persons"</span><span class="p">)</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">pformat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbpersons_pk</span><span class="p">))</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">pformat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbpersons_fullname</span><span class="p">))</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">pformat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbfaces_pk</span><span class="p">))</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">pformat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbfaces_uuid</span><span class="p">))</span>
|
|
|
|
<span class="c1"># Get info on albums</span>
|
|
<span class="n">verbose</span><span class="p">(</span><span class="s2">"Processing albums."</span><span class="p">)</span>
|
|
<span class="n">c</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span>
|
|
<span class="sd">""" SELECT </span>
|
|
<span class="sd"> RKAlbum.uuid, </span>
|
|
<span class="sd"> RKVersion.uuid,</span>
|
|
<span class="sd"> RKCustomSortOrder.orderNumber</span>
|
|
<span class="sd"> FROM RKVersion</span>
|
|
<span class="sd"> JOIN RKCustomSortOrder on RKCustomSortOrder.objectUuid = RKVersion.uuid</span>
|
|
<span class="sd"> JOIN RKAlbum on RKAlbum.uuid = RKCustomSortOrder.containerUuid</span>
|
|
<span class="sd"> """</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="c1"># 0 RKAlbum.uuid,</span>
|
|
<span class="c1"># 1 RKVersion.uuid,</span>
|
|
<span class="c1"># 2 RKCustomSortOrder.orderNumber</span>
|
|
|
|
<span class="k">for</span> <span class="n">album</span> <span class="ow">in</span> <span class="n">c</span><span class="p">:</span>
|
|
<span class="c1"># store by uuid in _dbalbums_uuid and by album in _dbalbums_album</span>
|
|
<span class="n">album_uuid</span> <span class="o">=</span> <span class="n">album</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
|
<span class="n">photo_uuid</span> <span class="o">=</span> <span class="n">album</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
|
|
<span class="n">sort_order</span> <span class="o">=</span> <span class="n">album</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbalbums_uuid</span><span class="p">[</span><span class="n">photo_uuid</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">album_uuid</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbalbums_uuid</span><span class="p">[</span><span class="n">photo_uuid</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="n">album_uuid</span><span class="p">]</span>
|
|
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbalbums_album</span><span class="p">[</span><span class="n">album_uuid</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">photo_uuid</span><span class="p">,</span> <span class="n">sort_order</span><span class="p">))</span>
|
|
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbalbums_album</span><span class="p">[</span><span class="n">album_uuid</span><span class="p">]</span> <span class="o">=</span> <span class="p">[(</span><span class="n">photo_uuid</span><span class="p">,</span> <span class="n">sort_order</span><span class="p">)]</span>
|
|
|
|
<span class="c1"># now get additional details about albums</span>
|
|
<span class="n">c</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span>
|
|
<span class="sd">""" SELECT </span>
|
|
<span class="sd"> uuid, </span>
|
|
<span class="sd"> name, </span>
|
|
<span class="sd"> cloudLibraryState, </span>
|
|
<span class="sd"> cloudIdentifier, </span>
|
|
<span class="sd"> isInTrash, </span>
|
|
<span class="sd"> folderUuid,</span>
|
|
<span class="sd"> albumType, </span>
|
|
<span class="sd"> albumSubclass,</span>
|
|
<span class="sd"> createDate </span>
|
|
<span class="sd"> FROM RKAlbum """</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="c1"># Order of results</span>
|
|
<span class="c1"># 0: uuid</span>
|
|
<span class="c1"># 1: name</span>
|
|
<span class="c1"># 2: cloudLibraryState</span>
|
|
<span class="c1"># 3: cloudIdentifier</span>
|
|
<span class="c1"># 4: isInTrash</span>
|
|
<span class="c1"># 5: folderUuid</span>
|
|
<span class="c1"># 6: albumType</span>
|
|
<span class="c1"># 7: albumSubclass -- if 3, normal user album</span>
|
|
<span class="c1"># 8: createDate</span>
|
|
|
|
<span class="k">for</span> <span class="n">album</span> <span class="ow">in</span> <span class="n">c</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbalbum_details</span><span class="p">[</span><span class="n">album</span><span class="p">[</span><span class="mi">0</span><span class="p">]]</span> <span class="o">=</span> <span class="p">{</span>
|
|
<span class="s2">"_uuid"</span><span class="p">:</span> <span class="n">album</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span>
|
|
<span class="s2">"title"</span><span class="p">:</span> <span class="n">normalize_unicode</span><span class="p">(</span><span class="n">album</span><span class="p">[</span><span class="mi">1</span><span class="p">]),</span>
|
|
<span class="s2">"cloudlibrarystate"</span><span class="p">:</span> <span class="n">album</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span>
|
|
<span class="s2">"cloudidentifier"</span><span class="p">:</span> <span class="n">album</span><span class="p">[</span><span class="mi">3</span><span class="p">],</span>
|
|
<span class="s2">"intrash"</span><span class="p">:</span> <span class="kc">False</span> <span class="k">if</span> <span class="n">album</span><span class="p">[</span><span class="mi">4</span><span class="p">]</span> <span class="o">==</span> <span class="mi">0</span> <span class="k">else</span> <span class="kc">True</span><span class="p">,</span>
|
|
<span class="s2">"cloudlocalstate"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span> <span class="c1"># Photos 5</span>
|
|
<span class="s2">"cloudownerfirstname"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span> <span class="c1"># Photos 5</span>
|
|
<span class="s2">"cloudownderlastname"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span> <span class="c1"># Photos 5</span>
|
|
<span class="s2">"cloudownerhashedpersonid"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span> <span class="c1"># Photos 5</span>
|
|
<span class="s2">"folderUuid"</span><span class="p">:</span> <span class="n">album</span><span class="p">[</span><span class="mi">5</span><span class="p">],</span>
|
|
<span class="s2">"albumType"</span><span class="p">:</span> <span class="n">album</span><span class="p">[</span><span class="mi">6</span><span class="p">],</span>
|
|
<span class="s2">"albumSubclass"</span><span class="p">:</span> <span class="n">album</span><span class="p">[</span><span class="mi">7</span><span class="p">],</span>
|
|
<span class="c1"># for compatability with Photos 5 where album kind is ZKIND</span>
|
|
<span class="s2">"kind"</span><span class="p">:</span> <span class="n">album</span><span class="p">[</span><span class="mi">7</span><span class="p">],</span>
|
|
<span class="s2">"creation_date"</span><span class="p">:</span> <span class="n">album</span><span class="p">[</span><span class="mi">8</span><span class="p">],</span>
|
|
<span class="s2">"start_date"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span> <span class="c1"># Photos 5 only</span>
|
|
<span class="s2">"end_date"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span> <span class="c1"># Photos 5 only</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="c1"># get details about folders</span>
|
|
<span class="n">c</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span>
|
|
<span class="sd">""" SELECT </span>
|
|
<span class="sd"> uuid, </span>
|
|
<span class="sd"> modelId, </span>
|
|
<span class="sd"> name, </span>
|
|
<span class="sd"> isMagic, </span>
|
|
<span class="sd"> isInTrash, </span>
|
|
<span class="sd"> folderType, </span>
|
|
<span class="sd"> parentFolderUuid, </span>
|
|
<span class="sd"> folderPath</span>
|
|
<span class="sd"> FROM RKFolder """</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="c1"># Order of results</span>
|
|
<span class="c1"># 0 uuid,</span>
|
|
<span class="c1"># 1 modelId,</span>
|
|
<span class="c1"># 2 name,</span>
|
|
<span class="c1"># 3 isMagic,</span>
|
|
<span class="c1"># 4 isInTrash,</span>
|
|
<span class="c1"># 5 folderType,</span>
|
|
<span class="c1"># 6 parentFolderUuid,</span>
|
|
<span class="c1"># 7 folderPath</span>
|
|
|
|
<span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">c</span><span class="p">:</span>
|
|
<span class="n">uuid</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbfolder_details</span><span class="p">[</span><span class="n">uuid</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span>
|
|
<span class="s2">"_uuid"</span><span class="p">:</span> <span class="n">row</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span>
|
|
<span class="s2">"modelId"</span><span class="p">:</span> <span class="n">row</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span>
|
|
<span class="s2">"name"</span><span class="p">:</span> <span class="n">normalize_unicode</span><span class="p">(</span><span class="n">row</span><span class="p">[</span><span class="mi">2</span><span class="p">]),</span>
|
|
<span class="s2">"isMagic"</span><span class="p">:</span> <span class="n">row</span><span class="p">[</span><span class="mi">3</span><span class="p">],</span>
|
|
<span class="s2">"intrash"</span><span class="p">:</span> <span class="n">row</span><span class="p">[</span><span class="mi">4</span><span class="p">],</span>
|
|
<span class="s2">"folderType"</span><span class="p">:</span> <span class="n">row</span><span class="p">[</span><span class="mi">5</span><span class="p">],</span>
|
|
<span class="s2">"parentFolderUuid"</span><span class="p">:</span> <span class="n">row</span><span class="p">[</span><span class="mi">6</span><span class="p">],</span>
|
|
<span class="s2">"folderPath"</span><span class="p">:</span> <span class="n">row</span><span class="p">[</span><span class="mi">7</span><span class="p">],</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="c1"># build _dbalbum_folders in form uuid: [parent uuid] to be consistent with _process_database5</span>
|
|
<span class="k">for</span> <span class="n">album</span><span class="p">,</span> <span class="n">details</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbalbum_details</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
|
|
<span class="c1"># album can be in a single folder</span>
|
|
<span class="n">parent</span> <span class="o">=</span> <span class="n">details</span><span class="p">[</span><span class="s2">"folderUuid"</span><span class="p">]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbalbum_parent_folders</span><span class="p">[</span><span class="n">album</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="n">parent</span><span class="p">]</span>
|
|
|
|
<span class="c1"># build folder hierarchy</span>
|
|
<span class="k">for</span> <span class="n">album</span><span class="p">,</span> <span class="n">details</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbalbum_details</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
|
|
<span class="n">parent_folder</span> <span class="o">=</span> <span class="n">details</span><span class="p">[</span><span class="s2">"folderUuid"</span><span class="p">]</span>
|
|
<span class="k">if</span> <span class="n">details</span><span class="p">[</span>
|
|
<span class="s2">"albumSubclass"</span>
|
|
<span class="p">]</span> <span class="o">==</span> <span class="n">_PHOTOS_4_ALBUM_KIND</span> <span class="ow">and</span> <span class="n">parent_folder</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">[</span>
|
|
<span class="n">_PHOTOS_4_TOP_LEVEL_ALBUM</span>
|
|
<span class="p">]:</span>
|
|
<span class="n">folder_hierarchy</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_build_album_folder_hierarchy_4</span><span class="p">(</span><span class="n">parent_folder</span><span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbalbum_folders</span><span class="p">[</span><span class="n">album</span><span class="p">]</span> <span class="o">=</span> <span class="n">folder_hierarchy</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbalbum_folders</span><span class="p">[</span><span class="n">album</span><span class="p">]</span> <span class="o">=</span> <span class="p">{}</span>
|
|
|
|
<span class="k">if</span> <span class="n">_debug</span><span class="p">():</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Finished walking through albums"</span><span class="p">)</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">pformat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbalbums_album</span><span class="p">))</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">pformat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbalbums_uuid</span><span class="p">))</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">pformat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbalbum_details</span><span class="p">))</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">pformat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbalbum_folders</span><span class="p">))</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">pformat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbfolder_details</span><span class="p">))</span>
|
|
|
|
<span class="c1"># Get info on keywords</span>
|
|
<span class="n">verbose</span><span class="p">(</span><span class="s2">"Processing keywords."</span><span class="p">)</span>
|
|
<span class="n">c</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span>
|
|
<span class="sd">""" SELECT</span>
|
|
<span class="sd"> RKKeyword.name, </span>
|
|
<span class="sd"> RKVersion.uuid, </span>
|
|
<span class="sd"> RKMaster.uuid </span>
|
|
<span class="sd"> FROM </span>
|
|
<span class="sd"> RKKeyword, RKKeywordForVersion, RKVersion, RKMaster </span>
|
|
<span class="sd"> WHERE </span>
|
|
<span class="sd"> RKKeyword.modelId = RKKeyWordForVersion.keywordID AND </span>
|
|
<span class="sd"> RKVersion.modelID = RKKeywordForVersion.versionID AND </span>
|
|
<span class="sd"> RKMaster.uuid = RKVersion.masterUuid</span>
|
|
<span class="sd"> """</span>
|
|
<span class="p">)</span>
|
|
<span class="k">for</span> <span class="n">keyword</span> <span class="ow">in</span> <span class="n">c</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">keyword</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbkeywords_uuid</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbkeywords_uuid</span><span class="p">[</span><span class="n">keyword</span><span class="p">[</span><span class="mi">1</span><span class="p">]]</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">keyword</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbkeywords_keyword</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbkeywords_keyword</span><span class="p">[</span><span class="n">keyword</span><span class="p">[</span><span class="mi">0</span><span class="p">]]</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbkeywords_uuid</span><span class="p">[</span><span class="n">keyword</span><span class="p">[</span><span class="mi">1</span><span class="p">]]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">keyword</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbkeywords_keyword</span><span class="p">[</span><span class="n">keyword</span><span class="p">[</span><span class="mi">0</span><span class="p">]]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">keyword</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
|
|
|
|
<span class="c1"># Get info on disk volumes</span>
|
|
<span class="n">c</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"select RKVolume.modelId, RKVolume.name from RKVolume"</span><span class="p">)</span>
|
|
<span class="k">for</span> <span class="n">vol</span> <span class="ow">in</span> <span class="n">c</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbvolumes</span><span class="p">[</span><span class="n">vol</span><span class="p">[</span><span class="mi">0</span><span class="p">]]</span> <span class="o">=</span> <span class="n">vol</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
|
|
|
|
<span class="c1"># Get photo details</span>
|
|
<span class="n">verbose</span><span class="p">(</span><span class="s2">"Processing photo details."</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db_version</span> <span class="o"><</span> <span class="n">_PHOTOS_3_VERSION</span><span class="p">:</span>
|
|
<span class="c1"># Photos < 3.0 doesn't have RKVersion.selfPortrait (selfie)</span>
|
|
<span class="n">c</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span>
|
|
<span class="sd">""" SELECT RKVersion.uuid, RKVersion.modelId, RKVersion.masterUuid, RKVersion.filename, </span>
|
|
<span class="sd"> RKVersion.lastmodifieddate, RKVersion.imageDate, RKVersion.mainRating, </span>
|
|
<span class="sd"> RKVersion.hasAdjustments, RKVersion.hasKeywords, RKVersion.imageTimeZoneOffsetSeconds, </span>
|
|
<span class="sd"> RKMaster.volumeId, RKMaster.imagePath, RKVersion.extendedDescription, RKVersion.name, </span>
|
|
<span class="sd"> RKMaster.isMissing, RKMaster.originalFileName, RKVersion.isFavorite, RKVersion.isHidden, </span>
|
|
<span class="sd"> RKVersion.latitude, RKVersion.longitude, </span>
|
|
<span class="sd"> RKVersion.adjustmentUuid, RKVersion.type, RKMaster.UTI,</span>
|
|
<span class="sd"> RKVersion.burstUuid, RKVersion.burstPickType,</span>
|
|
<span class="sd"> RKVersion.specialType, RKMaster.modelID, null, RKVersion.momentUuid,</span>
|
|
<span class="sd"> RKVersion.rawMasterUuid,</span>
|
|
<span class="sd"> RKVersion.nonRawMasterUuid,</span>
|
|
<span class="sd"> RKMaster.alternateMasterUuid,</span>
|
|
<span class="sd"> RKVersion.isInTrash,</span>
|
|
<span class="sd"> RKVersion.processedHeight, </span>
|
|
<span class="sd"> RKVersion.processedWidth, </span>
|
|
<span class="sd"> RKVersion.orientation,</span>
|
|
<span class="sd"> RKMaster.height,</span>
|
|
<span class="sd"> RKMaster.width, </span>
|
|
<span class="sd"> RKMaster.orientation,</span>
|
|
<span class="sd"> RKMaster.fileSize,</span>
|
|
<span class="sd"> RKVersion.subType,</span>
|
|
<span class="sd"> RKVersion.inTrashDate,</span>
|
|
<span class="sd"> RKVersion.showInLibrary,</span>
|
|
<span class="sd"> RKMaster.fileIsReference</span>
|
|
<span class="sd"> FROM RKVersion, RKMaster</span>
|
|
<span class="sd"> WHERE RKVersion.masterUuid = RKMaster.uuid"""</span>
|
|
<span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">c</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span>
|
|
<span class="sd">""" SELECT RKVersion.uuid, RKVersion.modelId, RKVersion.masterUuid, RKVersion.filename, </span>
|
|
<span class="sd"> RKVersion.lastmodifieddate, RKVersion.imageDate, RKVersion.mainRating, </span>
|
|
<span class="sd"> RKVersion.hasAdjustments, RKVersion.hasKeywords, RKVersion.imageTimeZoneOffsetSeconds, </span>
|
|
<span class="sd"> RKMaster.volumeId, RKMaster.imagePath, RKVersion.extendedDescription, RKVersion.name, </span>
|
|
<span class="sd"> RKMaster.isMissing, RKMaster.originalFileName, RKVersion.isFavorite, RKVersion.isHidden, </span>
|
|
<span class="sd"> RKVersion.latitude, RKVersion.longitude, </span>
|
|
<span class="sd"> RKVersion.adjustmentUuid, RKVersion.type, RKMaster.UTI,</span>
|
|
<span class="sd"> RKVersion.burstUuid, RKVersion.burstPickType,</span>
|
|
<span class="sd"> RKVersion.specialType, RKMaster.modelID,</span>
|
|
<span class="sd"> RKVersion.selfPortrait,</span>
|
|
<span class="sd"> RKVersion.momentUuid,</span>
|
|
<span class="sd"> RKVersion.rawMasterUuid,</span>
|
|
<span class="sd"> RKVersion.nonRawMasterUuid,</span>
|
|
<span class="sd"> RKMaster.alternateMasterUuid,</span>
|
|
<span class="sd"> RKVersion.isInTrash,</span>
|
|
<span class="sd"> RKVersion.processedHeight, </span>
|
|
<span class="sd"> RKVersion.processedWidth, </span>
|
|
<span class="sd"> RKVersion.orientation,</span>
|
|
<span class="sd"> RKMaster.height,</span>
|
|
<span class="sd"> RKMaster.width, </span>
|
|
<span class="sd"> RKMaster.orientation,</span>
|
|
<span class="sd"> RKMaster.originalFileSize,</span>
|
|
<span class="sd"> RKVersion.subType,</span>
|
|
<span class="sd"> RKVersion.inTrashDate,</span>
|
|
<span class="sd"> RKVersion.showInLibrary,</span>
|
|
<span class="sd"> RKMaster.fileIsReference</span>
|
|
<span class="sd"> FROM RKVersion, RKMaster</span>
|
|
<span class="sd"> WHERE RKVersion.masterUuid = RKMaster.uuid"""</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="c1"># order of results</span>
|
|
<span class="c1"># 0 RKVersion.uuid</span>
|
|
<span class="c1"># 1 RKVersion.modelId</span>
|
|
<span class="c1"># 2 RKVersion.masterUuid</span>
|
|
<span class="c1"># 3 RKVersion.filename</span>
|
|
<span class="c1"># 4 RKVersion.lastmodifieddate</span>
|
|
<span class="c1"># 5 RKVersion.imageDate</span>
|
|
<span class="c1"># 6 RKVersion.mainRating</span>
|
|
<span class="c1"># 7 RKVersion.hasAdjustments</span>
|
|
<span class="c1"># 8 RKVersion.hasKeywords</span>
|
|
<span class="c1"># 9 RKVersion.imageTimeZoneOffsetSeconds</span>
|
|
<span class="c1"># 10 RKMaster.volumeId</span>
|
|
<span class="c1"># 11 RKMaster.imagePath</span>
|
|
<span class="c1"># 12 RKVersion.extendedDescription</span>
|
|
<span class="c1"># 13 RKVersion.name</span>
|
|
<span class="c1"># 14 RKMaster.isMissing</span>
|
|
<span class="c1"># 15 RKMaster.originalFileName</span>
|
|
<span class="c1"># 16 RKVersion.isFavorite</span>
|
|
<span class="c1"># 17 RKVersion.isHidden</span>
|
|
<span class="c1"># 18 RKVersion.latitude</span>
|
|
<span class="c1"># 19 RKVersion.longitude</span>
|
|
<span class="c1"># 20 RKVersion.adjustmentUuid</span>
|
|
<span class="c1"># 21 RKVersion.type</span>
|
|
<span class="c1"># 22 RKMaster.UTI</span>
|
|
<span class="c1"># 23 RKVersion.burstUuid</span>
|
|
<span class="c1"># 24 RKVersion.burstPickType</span>
|
|
<span class="c1"># 25 RKVersion.specialType</span>
|
|
<span class="c1"># 26 RKMaster.modelID</span>
|
|
<span class="c1"># 27 RKVersion.selfPortrait -- 1 if selfie, Photos >= 3, not present for Photos < 3</span>
|
|
<span class="c1"># 28 RKVersion.momentID (# 27 for Photos < 3)</span>
|
|
<span class="c1"># 29 RKVersion.rawMasterUuid, -- UUID of RAW master</span>
|
|
<span class="c1"># 30 RKVersion.nonRawMasterUuid, -- UUID of non-RAW master</span>
|
|
<span class="c1"># 31 RKMaster.alternateMasterUuid -- UUID of alternate master (will be RAW master for JPEG and JPEG master for RAW)</span>
|
|
<span class="c1"># 32 RKVersion.isInTrash</span>
|
|
<span class="c1"># 33 RKVersion.processedHeight,</span>
|
|
<span class="c1"># 34 RKVersion.processedWidth,</span>
|
|
<span class="c1"># 35 RKVersion.orientation,</span>
|
|
<span class="c1"># 36 RKMaster.height,</span>
|
|
<span class="c1"># 37 RKMaster.width,</span>
|
|
<span class="c1"># 38 RKMaster.orientation,</span>
|
|
<span class="c1"># 39 RKMaster.originalFileSize</span>
|
|
<span class="c1"># 40 RKVersion.subType</span>
|
|
<span class="c1"># 41 RKVersion.inTrashDate</span>
|
|
<span class="c1"># 42 RKVersion.showInLibrary -- is item visible in library (e.g. non-selected burst images are not visible)</span>
|
|
<span class="c1"># 43 RKMaster.fileIsReference -- file is reference (imported without copying to Photos library)</span>
|
|
|
|
<span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">c</span><span class="p">:</span>
|
|
<span class="n">uuid</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
|
<span class="k">if</span> <span class="n">_debug</span><span class="p">():</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="sa">f</span><span class="s2">"uuid = '</span><span class="si">{</span><span class="n">uuid</span><span class="si">}</span><span class="s2">, master = '</span><span class="si">{</span><span class="n">row</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">]</span> <span class="o">=</span> <span class="p">{}</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"_uuid"</span><span class="p">]</span> <span class="o">=</span> <span class="n">uuid</span> <span class="c1"># stored here for easier debugging</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"modelID"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"masterUuid"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"filename"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">3</span><span class="p">]</span>
|
|
|
|
<span class="c1"># There are sometimes negative values for lastmodifieddate in the database</span>
|
|
<span class="c1"># I don't know what these mean but they will raise exception in datetime if</span>
|
|
<span class="c1"># not accounted for</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"lastmodifieddate_timestamp"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">4</span><span class="p">]</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"lastmodifieddate"</span><span class="p">]</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">fromtimestamp</span><span class="p">(</span>
|
|
<span class="n">row</span><span class="p">[</span><span class="mi">4</span><span class="p">]</span> <span class="o">+</span> <span class="n">TIME_DELTA</span>
|
|
<span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"lastmodifieddate"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"lastmodifieddate"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"imageTimeZoneOffsetSeconds"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">9</span><span class="p">]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"imageDate_timestamp"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">5</span><span class="p">]</span>
|
|
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">imagedate</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">fromtimestamp</span><span class="p">(</span><span class="n">row</span><span class="p">[</span><span class="mi">5</span><span class="p">]</span> <span class="o">+</span> <span class="n">TIME_DELTA</span><span class="p">)</span>
|
|
<span class="n">seconds</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"imageTimeZoneOffsetSeconds"</span><span class="p">]</span> <span class="ow">or</span> <span class="mi">0</span>
|
|
<span class="n">delta</span> <span class="o">=</span> <span class="n">timedelta</span><span class="p">(</span><span class="n">seconds</span><span class="o">=</span><span class="n">seconds</span><span class="p">)</span>
|
|
<span class="n">tz</span> <span class="o">=</span> <span class="n">timezone</span><span class="p">(</span><span class="n">delta</span><span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"imageDate"</span><span class="p">]</span> <span class="o">=</span> <span class="n">imagedate</span><span class="o">.</span><span class="n">astimezone</span><span class="p">(</span><span class="n">tz</span><span class="o">=</span><span class="n">tz</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
|
|
<span class="c1"># sometimes imageDate is invalid so use 1 Jan 1970 in UTC as image date</span>
|
|
<span class="n">imagedate</span> <span class="o">=</span> <span class="n">datetime</span><span class="p">(</span><span class="mi">1970</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
|
|
<span class="n">tz</span> <span class="o">=</span> <span class="n">timezone</span><span class="p">(</span><span class="n">timedelta</span><span class="p">(</span><span class="mi">0</span><span class="p">))</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"imageDate"</span><span class="p">]</span> <span class="o">=</span> <span class="n">imagedate</span><span class="o">.</span><span class="n">astimezone</span><span class="p">(</span><span class="n">tz</span><span class="o">=</span><span class="n">tz</span><span class="p">)</span>
|
|
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"mainRating"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">6</span><span class="p">]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"hasAdjustments"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">7</span><span class="p">]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"hasKeywords"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">8</span><span class="p">]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"volumeId"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">10</span><span class="p">]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"imagePath"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">11</span><span class="p">]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"extendedDescription"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">12</span><span class="p">]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"name"</span><span class="p">]</span> <span class="o">=</span> <span class="n">normalize_unicode</span><span class="p">(</span><span class="n">row</span><span class="p">[</span><span class="mi">13</span><span class="p">])</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"isMissing"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">14</span><span class="p">]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"originalFilename"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">15</span><span class="p">]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"favorite"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">16</span><span class="p">]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"hidden"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">17</span><span class="p">]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"latitude"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">18</span><span class="p">]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"longitude"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">19</span><span class="p">]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"adjustmentUuid"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">20</span><span class="p">]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"adjustmentFormatID"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
|
|
<span class="c1"># find type and UTI</span>
|
|
<span class="k">if</span> <span class="n">row</span><span class="p">[</span><span class="mi">21</span><span class="p">]</span> <span class="o">==</span> <span class="mi">2</span><span class="p">:</span>
|
|
<span class="c1"># photo</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"type"</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PHOTO_TYPE</span>
|
|
<span class="k">elif</span> <span class="n">row</span><span class="p">[</span><span class="mi">21</span><span class="p">]</span> <span class="o">==</span> <span class="mi">8</span><span class="p">:</span>
|
|
<span class="c1"># movie</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"type"</span><span class="p">]</span> <span class="o">=</span> <span class="n">_MOVIE_TYPE</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="c1"># unknown</span>
|
|
<span class="k">if</span> <span class="n">_debug</span><span class="p">():</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="sa">f</span><span class="s2">"WARNING: </span><span class="si">{</span><span class="n">uuid</span><span class="si">}</span><span class="s2"> found unknown type </span><span class="si">{</span><span class="n">row</span><span class="p">[</span><span class="mi">21</span><span class="p">]</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"type"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"UTI"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">22</span><span class="p">]</span>
|
|
|
|
<span class="c1"># The UTI in RKMaster will always be UTI of the original</span>
|
|
<span class="c1"># Unlike Photos 5 which changes the UTI to match latest edit</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"UTI_original"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">22</span><span class="p">]</span>
|
|
|
|
<span class="c1"># UTI edited will be read from RKModelResource</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"UTI_edited"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
|
|
<span class="c1"># handle burst photos</span>
|
|
<span class="c1"># if burst photo, determine whether or not it's a selected burst photo</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"burstUUID"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">23</span><span class="p">]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"burstPickType"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">24</span><span class="p">]</span>
|
|
<span class="k">if</span> <span class="n">row</span><span class="p">[</span><span class="mi">23</span><span class="p">]</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="c1"># it's a burst photo</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"burst"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span>
|
|
<span class="n">burst_uuid</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">23</span><span class="p">]</span>
|
|
<span class="k">if</span> <span class="n">burst_uuid</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos_burst</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos_burst</span><span class="p">[</span><span class="n">burst_uuid</span><span class="p">]</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos_burst</span><span class="p">[</span><span class="n">burst_uuid</span><span class="p">]</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">uuid</span><span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="c1"># not a burst photo</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"burst"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">False</span>
|
|
|
|
<span class="c1"># RKVersion.specialType</span>
|
|
<span class="c1"># 1 == panorama</span>
|
|
<span class="c1"># 2 == slow-mo movie</span>
|
|
<span class="c1"># 3 == time-lapse movie</span>
|
|
<span class="c1"># 4 == HDR</span>
|
|
<span class="c1"># 5 == live photo</span>
|
|
<span class="c1"># 6 == screenshot</span>
|
|
<span class="c1"># 7 == JPEG/RAW pair</span>
|
|
<span class="c1"># 8 == HDR live photo</span>
|
|
<span class="c1"># 9 = portrait</span>
|
|
|
|
<span class="c1"># get info on special types</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"specialType"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">25</span><span class="p">]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"masterModelID"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">26</span><span class="p">]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"panorama"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span> <span class="k">if</span> <span class="n">row</span><span class="p">[</span><span class="mi">25</span><span class="p">]</span> <span class="o">==</span> <span class="mi">1</span> <span class="k">else</span> <span class="kc">False</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"slow_mo"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span> <span class="k">if</span> <span class="n">row</span><span class="p">[</span><span class="mi">25</span><span class="p">]</span> <span class="o">==</span> <span class="mi">2</span> <span class="k">else</span> <span class="kc">False</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"time_lapse"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span> <span class="k">if</span> <span class="n">row</span><span class="p">[</span><span class="mi">25</span><span class="p">]</span> <span class="o">==</span> <span class="mi">3</span> <span class="k">else</span> <span class="kc">False</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"hdr"</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span>
|
|
<span class="kc">True</span> <span class="k">if</span> <span class="p">(</span><span class="n">row</span><span class="p">[</span><span class="mi">25</span><span class="p">]</span> <span class="o">==</span> <span class="mi">4</span> <span class="ow">or</span> <span class="n">row</span><span class="p">[</span><span class="mi">25</span><span class="p">]</span> <span class="o">==</span> <span class="mi">8</span><span class="p">)</span> <span class="k">else</span> <span class="kc">False</span>
|
|
<span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"live_photo"</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span>
|
|
<span class="kc">True</span> <span class="k">if</span> <span class="p">(</span><span class="n">row</span><span class="p">[</span><span class="mi">25</span><span class="p">]</span> <span class="o">==</span> <span class="mi">5</span> <span class="ow">or</span> <span class="n">row</span><span class="p">[</span><span class="mi">25</span><span class="p">]</span> <span class="o">==</span> <span class="mi">8</span><span class="p">)</span> <span class="k">else</span> <span class="kc">False</span>
|
|
<span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"screenshot"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span> <span class="k">if</span> <span class="n">row</span><span class="p">[</span><span class="mi">25</span><span class="p">]</span> <span class="o">==</span> <span class="mi">6</span> <span class="k">else</span> <span class="kc">False</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"portrait"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span> <span class="k">if</span> <span class="n">row</span><span class="p">[</span><span class="mi">25</span><span class="p">]</span> <span class="o">==</span> <span class="mi">9</span> <span class="k">else</span> <span class="kc">False</span>
|
|
|
|
<span class="c1"># selfies (front facing camera, RKVersion.selfPortrait == 1)</span>
|
|
<span class="k">if</span> <span class="n">row</span><span class="p">[</span><span class="mi">27</span><span class="p">]</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"selfie"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span> <span class="k">if</span> <span class="n">row</span><span class="p">[</span><span class="mi">27</span><span class="p">]</span> <span class="o">==</span> <span class="mi">1</span> <span class="k">else</span> <span class="kc">False</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"selfie"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"momentID"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">28</span><span class="p">]</span>
|
|
|
|
<span class="c1"># Init cloud details that will be filled in later if cloud asset</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"cloudAssetGUID"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span> <span class="c1"># Photos 5</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"cloudLocalState"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span> <span class="c1"># Photos 5</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"cloudLibraryState"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"cloudStatus"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"cloudAvailable"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"incloud"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
|
|
<span class="c1"># associated RAW image info</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"has_raw"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span> <span class="k">if</span> <span class="n">row</span><span class="p">[</span><span class="mi">25</span><span class="p">]</span> <span class="o">==</span> <span class="mi">7</span> <span class="k">else</span> <span class="kc">False</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"UTI_raw"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"raw_data_length"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"raw_info"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"resource_type"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span> <span class="c1"># Photos 5</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"datastore_subtype"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span> <span class="c1"># Photos 5</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"raw_master_uuid"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">29</span><span class="p">]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"non_raw_master_uuid"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">30</span><span class="p">]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"alt_master_uuid"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">31</span><span class="p">]</span>
|
|
|
|
<span class="c1"># original resource choice (e.g. RAW or jpeg)</span>
|
|
<span class="c1"># In Photos 5+, original_resource_choice set from:</span>
|
|
<span class="c1"># ZADDITIONALASSETATTRIBUTES.ZORIGINALRESOURCECHOICE</span>
|
|
<span class="c1"># = 0 if jpeg is selected as "original" in Photos (the default)</span>
|
|
<span class="c1"># = 1 if RAW is selected as "original" in Photos</span>
|
|
<span class="c1"># RKVersion.subType, RAW always appears to be 16</span>
|
|
<span class="c1"># 4 = mov</span>
|
|
<span class="c1"># 16 = RAW</span>
|
|
<span class="c1"># 32 = JPEG</span>
|
|
<span class="c1"># 64 = TIFF</span>
|
|
<span class="c1"># 2048 = PNG</span>
|
|
<span class="c1"># 32768 = HIEC</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"original_resource_choice"</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span>
|
|
<span class="mi">1</span> <span class="k">if</span> <span class="n">row</span><span class="p">[</span><span class="mi">40</span><span class="p">]</span> <span class="o">==</span> <span class="mi">16</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"has_raw"</span><span class="p">]</span> <span class="k">else</span> <span class="mi">0</span>
|
|
<span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"raw_is_original"</span><span class="p">]</span> <span class="o">=</span> <span class="nb">bool</span><span class="p">(</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"original_resource_choice"</span><span class="p">]</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="c1"># recently deleted items</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"intrash"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">32</span><span class="p">]</span> <span class="o">==</span> <span class="mi">1</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"trasheddate_timestamp"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">41</span><span class="p">]</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"trasheddate"</span><span class="p">]</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">fromtimestamp</span><span class="p">(</span>
|
|
<span class="n">row</span><span class="p">[</span><span class="mi">41</span><span class="p">]</span> <span class="o">+</span> <span class="n">TIME_DELTA</span>
|
|
<span class="p">)</span>
|
|
<span class="k">except</span> <span class="p">(</span><span class="ne">ValueError</span><span class="p">,</span> <span class="ne">TypeError</span><span class="p">):</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"trasheddate"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
|
|
<span class="c1"># height/width/orientation</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"height"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">33</span><span class="p">]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"width"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">34</span><span class="p">]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"orientation"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">35</span><span class="p">]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"original_height"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">36</span><span class="p">]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"original_width"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">37</span><span class="p">]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"original_orientation"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">38</span><span class="p">]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"original_filesize"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">39</span><span class="p">]</span>
|
|
|
|
<span class="c1"># visibility state</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"visibility_state"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">42</span><span class="p">]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"visible"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">42</span><span class="p">]</span> <span class="o">==</span> <span class="mi">1</span>
|
|
|
|
<span class="c1"># file is reference (not copied into Photos library)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"isreference"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">43</span><span class="p">]</span> <span class="o">==</span> <span class="mi">1</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"saved_asset_type"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span> <span class="c1"># Photos 5+</span>
|
|
|
|
<span class="c1"># import session not yet handled for Photos 4</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"import_session"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"import_uuid"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"fok_import_session"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
|
|
<span class="c1"># get additional details from RKMaster, needed for RAW processing</span>
|
|
<span class="n">verbose</span><span class="p">(</span><span class="s2">"Processing additional photo details."</span><span class="p">)</span>
|
|
<span class="n">c</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span>
|
|
<span class="sd">""" SELECT </span>
|
|
<span class="sd"> RKMaster.uuid,</span>
|
|
<span class="sd"> RKMaster.volumeId, </span>
|
|
<span class="sd"> RKMaster.imagePath, </span>
|
|
<span class="sd"> RKMaster.isMissing, </span>
|
|
<span class="sd"> RKMaster.originalFileName, </span>
|
|
<span class="sd"> RKMaster.UTI,</span>
|
|
<span class="sd"> RKMaster.modelID, </span>
|
|
<span class="sd"> RKMaster.fileSize, </span>
|
|
<span class="sd"> RKMaster.isTrulyRaw,</span>
|
|
<span class="sd"> RKMaster.alternateMasterUuid,</span>
|
|
<span class="sd"> RKMaster.filename</span>
|
|
<span class="sd"> FROM RKMaster</span>
|
|
<span class="sd"> """</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="c1"># Order of results:</span>
|
|
<span class="c1"># 0 RKMaster.uuid,</span>
|
|
<span class="c1"># 1 RKMaster.volumeId,</span>
|
|
<span class="c1"># 2 RKMaster.imagePath,</span>
|
|
<span class="c1"># 3 RKMaster.isMissing,</span>
|
|
<span class="c1"># 4 RKMaster.originalFileName,</span>
|
|
<span class="c1"># 5 RKMaster.UTI,</span>
|
|
<span class="c1"># 6 RKMaster.modelID,</span>
|
|
<span class="c1"># 7 RKMaster.fileSize,</span>
|
|
<span class="c1"># 8 RKMaster.isTrulyRaw,</span>
|
|
<span class="c1"># 9 RKMaster.alternateMasterUuid</span>
|
|
<span class="c1"># 10 RKMaster.filename</span>
|
|
|
|
<span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">c</span><span class="p">:</span>
|
|
<span class="n">uuid</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
|
<span class="n">info</span> <span class="o">=</span> <span class="p">{}</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"_uuid"</span><span class="p">]</span> <span class="o">=</span> <span class="n">uuid</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"volumeId"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"imagePath"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"isMissing"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">3</span><span class="p">]</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"originalFilename"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">4</span><span class="p">]</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"UTI"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">5</span><span class="p">]</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"modelID"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">6</span><span class="p">]</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"fileSize"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">7</span><span class="p">]</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"isTrulyRAW"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">8</span><span class="p">]</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"alternateMasterUuid"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">9</span><span class="p">]</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"filename"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">10</span><span class="p">]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos_master</span><span class="p">[</span><span class="n">uuid</span><span class="p">]</span> <span class="o">=</span> <span class="n">info</span>
|
|
|
|
<span class="c1"># get details needed to find path of the edited photos</span>
|
|
<span class="n">c</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span>
|
|
<span class="sd">""" SELECT RKVersion.uuid, RKVersion.adjustmentUuid, RKModelResource.modelId,</span>
|
|
<span class="sd"> RKModelResource.resourceTag, RKModelResource.UTI, RKVersion.specialType,</span>
|
|
<span class="sd"> RKModelResource.attachedModelType, RKModelResource.resourceType</span>
|
|
<span class="sd"> FROM RKVersion</span>
|
|
<span class="sd"> JOIN RKModelResource on RKModelResource.attachedModelId = RKVersion.modelId """</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="c1"># Order of results:</span>
|
|
<span class="c1"># 0 RKVersion.uuid</span>
|
|
<span class="c1"># 1 RKVersion.adjustmentUuid</span>
|
|
<span class="c1"># 2 RKModelResource.modelId</span>
|
|
<span class="c1"># 3 RKModelResource.resourceTag</span>
|
|
<span class="c1"># 4 RKModelResource.UTI</span>
|
|
<span class="c1"># 5 RKVersion.specialType</span>
|
|
<span class="c1"># 6 RKModelResource.attachedModelType</span>
|
|
<span class="c1"># 7 RKModelResource.resourceType</span>
|
|
|
|
<span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">c</span><span class="p">:</span>
|
|
<span class="n">uuid</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
|
<span class="k">if</span> <span class="n">uuid</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">:</span>
|
|
<span class="c1"># get info on adjustments (edits)</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"adjustmentUuid"</span><span class="p">]</span> <span class="o">==</span> <span class="n">row</span><span class="p">[</span><span class="mi">3</span><span class="p">]:</span>
|
|
<span class="k">if</span> <span class="p">(</span>
|
|
<span class="n">row</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">!=</span> <span class="s2">"UNADJUSTEDNONRAW"</span>
|
|
<span class="ow">and</span> <span class="n">row</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">!=</span> <span class="s2">"UNADJUSTED"</span>
|
|
<span class="ow">and</span> <span class="n">row</span><span class="p">[</span><span class="mi">6</span><span class="p">]</span> <span class="o">==</span> <span class="mi">2</span>
|
|
<span class="p">):</span>
|
|
<span class="k">if</span> <span class="s2">"edit_resource_id"</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">]:</span>
|
|
<span class="k">if</span> <span class="n">_debug</span><span class="p">():</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span>
|
|
<span class="sa">f</span><span class="s2">"WARNING: found more than one edit_resource_id for "</span>
|
|
<span class="sa">f</span><span class="s2">"UUID </span><span class="si">{</span><span class="n">row</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="si">}</span><span class="s2">,adjustmentUUID </span><span class="si">{</span><span class="n">row</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="si">}</span><span class="s2">, modelID </span><span class="si">{</span><span class="n">row</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span><span class="si">}</span><span class="s2">"</span>
|
|
<span class="p">)</span>
|
|
<span class="c1"># TODO: I think there should never be more than one edit but</span>
|
|
<span class="c1"># I've seen this once in my library</span>
|
|
<span class="c1"># should we return all edits or just most recent one?</span>
|
|
<span class="c1"># For now, return most recent edit</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"edit_resource_id"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"UTI_edited"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">4</span><span class="p">]</span>
|
|
|
|
<span class="c1"># get details on external edits</span>
|
|
<span class="n">c</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span>
|
|
<span class="sd">""" SELECT RKVersion.uuid, </span>
|
|
<span class="sd"> RKVersion.adjustmentUuid, </span>
|
|
<span class="sd"> RKAdjustmentData.originator, </span>
|
|
<span class="sd"> RKAdjustmentData.format </span>
|
|
<span class="sd"> FROM RKVersion, RKAdjustmentData </span>
|
|
<span class="sd"> WHERE RKVersion.adjustmentUuid = RKAdjustmentData.uuid """</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">c</span><span class="p">:</span>
|
|
<span class="n">uuid</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
|
<span class="k">if</span> <span class="n">uuid</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"adjustmentFormatID"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">3</span><span class="p">]</span>
|
|
|
|
<span class="c1"># get details to find path of live photos</span>
|
|
<span class="n">c</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span>
|
|
<span class="sd">""" SELECT </span>
|
|
<span class="sd"> RKVersion.uuid, </span>
|
|
<span class="sd"> RKModelResource.modelId,</span>
|
|
<span class="sd"> RKModelResource.UTI,</span>
|
|
<span class="sd"> RKVersion.specialType, </span>
|
|
<span class="sd"> RKModelResource.attachedModelType,</span>
|
|
<span class="sd"> RKModelResource.resourceType,</span>
|
|
<span class="sd"> RKModelResource.isOnDisk</span>
|
|
<span class="sd"> FROM RKVersion </span>
|
|
<span class="sd"> INNER JOIN RKMaster on RKVersion.masterUuid = RKMaster.uuid </span>
|
|
<span class="sd"> INNER JOIN RKModelResource on RKMaster.modelId = RKModelResource.attachedModelId </span>
|
|
<span class="sd"> WHERE RKModelResource.UTI = 'com.apple.quicktime-movie'</span>
|
|
<span class="sd"> """</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="c1"># Order of results</span>
|
|
<span class="c1"># 0 RKVersion.uuid,</span>
|
|
<span class="c1"># 1 RKModelResource.modelId,</span>
|
|
<span class="c1"># 2 RKModelResource.UTI,</span>
|
|
<span class="c1"># 3 RKVersion.specialType,</span>
|
|
<span class="c1"># 4 RKModelResource.attachedModelType,</span>
|
|
<span class="c1"># 5 RKModelResource.resourceType</span>
|
|
<span class="c1"># 6 RKModelResource.isOnDisk</span>
|
|
|
|
<span class="c1"># TODO: don't think we need most of these fields, remove from SQL query?</span>
|
|
<span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">c</span><span class="p">:</span>
|
|
<span class="n">uuid</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
|
<span class="k">if</span> <span class="n">uuid</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"live_model_id"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"modeResourceIsOnDisk"</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span>
|
|
<span class="kc">True</span> <span class="k">if</span> <span class="n">row</span><span class="p">[</span><span class="mi">6</span><span class="p">]</span> <span class="o">==</span> <span class="mi">1</span> <span class="k">else</span> <span class="kc">False</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="c1"># init any uuids that had no edits or live photos</span>
|
|
<span class="k">for</span> <span class="n">uuid</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="s2">"edit_resource_id"</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">]:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"edit_resource_id"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="k">if</span> <span class="s2">"live_model_id"</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">]:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"live_model_id"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"modeResourceIsOnDisk"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
|
|
<span class="c1"># get cloud details</span>
|
|
<span class="n">c</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span>
|
|
<span class="sd">""" SELECT </span>
|
|
<span class="sd"> RKVersion.uuid, </span>
|
|
<span class="sd"> RKMaster.cloudLibraryState,</span>
|
|
<span class="sd"> RKCloudResource.available, </span>
|
|
<span class="sd"> RKCloudResource.status</span>
|
|
<span class="sd"> FROM RKCloudResource</span>
|
|
<span class="sd"> INNER JOIN RKMaster ON RKMaster.fingerprint = RKCloudResource.fingerprint</span>
|
|
<span class="sd"> INNER JOIN RKVersion ON RKVersion.masterUuid = RKMaster.uuid """</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="c1"># Order of results</span>
|
|
<span class="c1"># 0 RKVersion.uuid,</span>
|
|
<span class="c1"># 1 RKMaster.cloudLibraryState,</span>
|
|
<span class="c1"># 2 RKCloudResource.available,</span>
|
|
<span class="c1"># 3 RKCloudResource.status</span>
|
|
|
|
<span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">c</span><span class="p">:</span>
|
|
<span class="n">uuid</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
|
<span class="k">if</span> <span class="n">uuid</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"cloudLibraryState"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"cloudAvailable"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"cloudStatus"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">3</span><span class="p">]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"incloud"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span> <span class="k">if</span> <span class="n">row</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="o">==</span> <span class="mi">1</span> <span class="k">else</span> <span class="kc">False</span>
|
|
|
|
<span class="c1"># get location data</span>
|
|
<span class="n">verbose</span><span class="p">(</span><span class="s2">"Processing location data."</span><span class="p">)</span>
|
|
<span class="c1"># get the country codes</span>
|
|
<span class="n">country_codes</span> <span class="o">=</span> <span class="n">c</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span>
|
|
<span class="s2">"SELECT modelID, countryCode "</span>
|
|
<span class="s2">"FROM RKPlace "</span>
|
|
<span class="s2">"WHERE countryCode IS NOT NULL "</span>
|
|
<span class="p">)</span><span class="o">.</span><span class="n">fetchall</span><span class="p">()</span>
|
|
<span class="n">countries</span> <span class="o">=</span> <span class="p">{</span><span class="n">code</span><span class="p">[</span><span class="mi">0</span><span class="p">]:</span> <span class="n">code</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="k">for</span> <span class="n">code</span> <span class="ow">in</span> <span class="n">country_codes</span><span class="p">}</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_db_countries</span> <span class="o">=</span> <span class="n">countries</span>
|
|
|
|
<span class="c1"># get the place data</span>
|
|
<span class="n">place_data</span> <span class="o">=</span> <span class="n">c</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span>
|
|
<span class="s2">"SELECT modelID, defaultName, type, area "</span> <span class="s2">"FROM RKPlace "</span>
|
|
<span class="p">)</span><span class="o">.</span><span class="n">fetchall</span><span class="p">()</span>
|
|
<span class="n">places</span> <span class="o">=</span> <span class="p">{</span><span class="n">p</span><span class="p">[</span><span class="mi">0</span><span class="p">]:</span> <span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">place_data</span><span class="p">}</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_db_places</span> <span class="o">=</span> <span class="n">places</span>
|
|
|
|
<span class="k">for</span> <span class="n">uuid</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">:</span>
|
|
<span class="c1"># get placeId which is then used to lookup defaultName</span>
|
|
<span class="n">place_ids_query</span> <span class="o">=</span> <span class="n">c</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span>
|
|
<span class="s2">"SELECT placeId "</span>
|
|
<span class="s2">"FROM RKPlaceForVersion "</span>
|
|
<span class="sa">f</span><span class="s2">"WHERE versionId = '</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s1">'modelID'</span><span class="p">]</span><span class="si">}</span><span class="s2">'"</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="n">place_ids</span> <span class="o">=</span> <span class="p">[</span><span class="nb">id</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">for</span> <span class="nb">id</span> <span class="ow">in</span> <span class="n">place_ids_query</span><span class="o">.</span><span class="n">fetchall</span><span class="p">()]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"placeIDs"</span><span class="p">]</span> <span class="o">=</span> <span class="n">place_ids</span>
|
|
<span class="n">country_code</span> <span class="o">=</span> <span class="p">[</span><span class="n">countries</span><span class="p">[</span><span class="n">x</span><span class="p">]</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">place_ids</span> <span class="k">if</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">countries</span><span class="p">]</span>
|
|
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">country_code</span><span class="p">)</span> <span class="o">></span> <span class="mi">1</span><span class="p">:</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Found more than one country code for uuid: </span><span class="si">{</span><span class="n">uuid</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="n">country_code</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"countryCode"</span><span class="p">]</span> <span class="o">=</span> <span class="n">country_code</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"countryCode"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
|
|
<span class="c1"># get the place info that matches the RKPlace modelIDs for this photo</span>
|
|
<span class="c1"># (place_ids), sort by area (element 3 of the place_data tuple in places)</span>
|
|
<span class="c1"># area could be None so assume 0 if it is (issue #230)</span>
|
|
<span class="n">place_names</span> <span class="o">=</span> <span class="p">[</span>
|
|
<span class="n">pname</span>
|
|
<span class="k">for</span> <span class="n">pname</span> <span class="ow">in</span> <span class="nb">sorted</span><span class="p">(</span>
|
|
<span class="p">[</span><span class="n">places</span><span class="p">[</span><span class="n">p</span><span class="p">]</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">places</span> <span class="k">if</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">place_ids</span><span class="p">],</span>
|
|
<span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">place</span><span class="p">:</span> <span class="n">place</span><span class="p">[</span><span class="mi">3</span><span class="p">]</span> <span class="k">if</span> <span class="n">place</span><span class="p">[</span><span class="mi">3</span><span class="p">]</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="k">else</span> <span class="mi">0</span><span class="p">,</span>
|
|
<span class="p">)</span>
|
|
<span class="p">]</span>
|
|
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"placeNames"</span><span class="p">]</span> <span class="o">=</span> <span class="n">place_names</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"reverse_geolocation"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span> <span class="c1"># Photos 5</span>
|
|
|
|
<span class="c1"># build album_titles dictionary</span>
|
|
<span class="k">for</span> <span class="n">album_id</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbalbum_details</span><span class="p">:</span>
|
|
<span class="n">title</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbalbum_details</span><span class="p">[</span><span class="n">album_id</span><span class="p">][</span><span class="s2">"title"</span><span class="p">]</span>
|
|
<span class="k">if</span> <span class="n">title</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbalbum_titles</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbalbum_titles</span><span class="p">[</span><span class="n">title</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">album_id</span><span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbalbum_titles</span><span class="p">[</span><span class="n">title</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="n">album_id</span><span class="p">]</span>
|
|
|
|
<span class="c1"># add volume name to _dbphotos_master</span>
|
|
<span class="k">for</span> <span class="n">info</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos_master</span><span class="o">.</span><span class="n">values</span><span class="p">():</span>
|
|
<span class="c1"># issue 230: have seen bad volumeID values</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"volume"</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbvolumes</span><span class="p">[</span><span class="n">info</span><span class="p">[</span><span class="s2">"volumeId"</span><span class="p">]]</span>
|
|
<span class="k">if</span> <span class="n">info</span><span class="p">[</span><span class="s2">"volumeId"</span><span class="p">]</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span>
|
|
<span class="k">else</span> <span class="kc">None</span>
|
|
<span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"volume"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
|
|
<span class="c1"># add data on RAW images</span>
|
|
<span class="k">for</span> <span class="n">info</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="o">.</span><span class="n">values</span><span class="p">():</span>
|
|
<span class="k">if</span> <span class="n">info</span><span class="p">[</span><span class="s2">"has_raw"</span><span class="p">]:</span>
|
|
<span class="n">raw_uuid</span> <span class="o">=</span> <span class="n">info</span><span class="p">[</span><span class="s2">"raw_master_uuid"</span><span class="p">]</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"raw_info"</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos_master</span><span class="p">[</span><span class="n">raw_uuid</span><span class="p">]</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"UTI_raw"</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos_master</span><span class="p">[</span><span class="n">raw_uuid</span><span class="p">][</span><span class="s2">"UTI"</span><span class="p">]</span>
|
|
<span class="n">non_raw_uuid</span> <span class="o">=</span> <span class="n">info</span><span class="p">[</span><span class="s2">"non_raw_master_uuid"</span><span class="p">]</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"raw_pair_info"</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos_master</span><span class="p">[</span><span class="n">non_raw_uuid</span><span class="p">]</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"raw_info"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"UTI_raw"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"raw_pair_info"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
|
|
<span class="c1"># done with the database connection</span>
|
|
<span class="n">conn</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
|
|
|
|
<span class="c1"># process faces</span>
|
|
<span class="n">verbose</span><span class="p">(</span><span class="s2">"Processing face details."</span><span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_process_faceinfo</span><span class="p">()</span>
|
|
|
|
<span class="c1"># add faces and keywords to photo data</span>
|
|
<span class="k">for</span> <span class="n">uuid</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">:</span>
|
|
<span class="c1"># keywords</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"hasKeywords"</span><span class="p">]</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"keywords"</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbkeywords_uuid</span><span class="p">[</span><span class="n">uuid</span><span class="p">]</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"keywords"</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>
|
|
|
|
<span class="k">if</span> <span class="n">uuid</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbfaces_uuid</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"hasPersons"</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"persons"</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbfaces_uuid</span><span class="p">[</span><span class="n">uuid</span><span class="p">]</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"hasPersons"</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"persons"</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>
|
|
|
|
<span class="k">if</span> <span class="n">uuid</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbalbums_uuid</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"albums"</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbalbums_uuid</span><span class="p">[</span><span class="n">uuid</span><span class="p">]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"hasAlbums"</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"albums"</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"hasAlbums"</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span>
|
|
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"volumeId"</span><span class="p">]</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="c1"># issue 230: have seen bad volumeID values</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"volume"</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbvolumes</span><span class="p">[</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"volumeId"</span><span class="p">]</span>
|
|
<span class="p">]</span>
|
|
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"volume"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"volume"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
|
|
<span class="c1"># done processing, dump debug data if requested</span>
|
|
<span class="n">verbose</span><span class="p">(</span><span class="s2">"Done processing details from Photos library."</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">_debug</span><span class="p">():</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">"Faces (_dbfaces_uuid):"</span><span class="p">)</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">pformat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbfaces_uuid</span><span class="p">))</span>
|
|
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">"Persons (_dbpersons_pk):"</span><span class="p">)</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">pformat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbpersons_pk</span><span class="p">))</span>
|
|
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">"Keywords by uuid (_dbkeywords_uuid):"</span><span class="p">)</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">pformat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbkeywords_uuid</span><span class="p">))</span>
|
|
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">"Keywords by keyword (_dbkeywords_keywords):"</span><span class="p">)</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">pformat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbkeywords_keyword</span><span class="p">))</span>
|
|
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">"Albums by uuid (_dbalbums_uuid):"</span><span class="p">)</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">pformat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbalbums_uuid</span><span class="p">))</span>
|
|
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">"Albums by album (_dbalbums_albums):"</span><span class="p">)</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">pformat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbalbums_album</span><span class="p">))</span>
|
|
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">"Album details (_dbalbum_details):"</span><span class="p">)</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">pformat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbalbum_details</span><span class="p">))</span>
|
|
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">"Album titles (_dbalbum_titles):"</span><span class="p">)</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">pformat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbalbum_titles</span><span class="p">))</span>
|
|
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">"Volumes (_dbvolumes):"</span><span class="p">)</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">pformat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbvolumes</span><span class="p">))</span>
|
|
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">"Photos (_dbphotos):"</span><span class="p">)</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">pformat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">))</span>
|
|
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">"Burst Photos (dbphotos_burst:"</span><span class="p">)</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">pformat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos_burst</span><span class="p">))</span>
|
|
|
|
<span class="k">def</span> <span class="nf">_build_album_folder_hierarchy_4</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">uuid</span><span class="p">,</span> <span class="n">folders</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="sd">""" recursively build folder/album hierarchy</span>
|
|
<span class="sd"> uuid: parent uuid of the album being processed </span>
|
|
<span class="sd"> (parent uuid is a folder in RKFolders)</span>
|
|
<span class="sd"> folders: dict holding the folder hierarchy </span>
|
|
<span class="sd"> NOTE: This implementation is different than _build_album_folder_hierarchy_5 </span>
|
|
<span class="sd"> which takes the uuid of the album being processed. Here uuid is the parent uuid</span>
|
|
<span class="sd"> of the parent folder album because in Photos <=4, folders are in RKFolders and </span>
|
|
<span class="sd"> albums in RKAlbums. In Photos 5, folders are just special albums </span>
|
|
<span class="sd"> with kind = _PHOTOS_5_FOLDER_KIND """</span>
|
|
|
|
<span class="n">parent_uuid</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbfolder_details</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"parentFolderUuid"</span><span class="p">]</span>
|
|
|
|
<span class="k">if</span> <span class="n">parent_uuid</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">folders</span>
|
|
|
|
<span class="k">if</span> <span class="n">parent_uuid</span> <span class="o">==</span> <span class="n">_PHOTOS_4_TOP_LEVEL_ALBUM</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">folders</span><span class="p">:</span>
|
|
<span class="c1"># this is a top-level folder with no sub-folders</span>
|
|
<span class="n">folders</span> <span class="o">=</span> <span class="p">{</span><span class="n">uuid</span><span class="p">:</span> <span class="kc">None</span><span class="p">}</span>
|
|
<span class="c1"># at top of hierarchy, we're done</span>
|
|
<span class="k">return</span> <span class="n">folders</span>
|
|
|
|
<span class="c1"># recurse to keep building</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">folders</span><span class="p">:</span>
|
|
<span class="c1"># first time building</span>
|
|
<span class="n">folders</span> <span class="o">=</span> <span class="p">{</span><span class="n">uuid</span><span class="p">:</span> <span class="kc">None</span><span class="p">}</span>
|
|
<span class="n">folders</span> <span class="o">=</span> <span class="p">{</span><span class="n">parent_uuid</span><span class="p">:</span> <span class="n">folders</span><span class="p">}</span>
|
|
<span class="n">folders</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_build_album_folder_hierarchy_4</span><span class="p">(</span><span class="n">parent_uuid</span><span class="p">,</span> <span class="n">folders</span><span class="o">=</span><span class="n">folders</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">folders</span>
|
|
|
|
<span class="k">def</span> <span class="nf">_process_database5</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">""" process the Photos database to extract info </span>
|
|
<span class="sd"> works on Photos version 5 and version 6</span>
|
|
|
|
<span class="sd"> This is a big hairy 700 line function that should probably be refactored</span>
|
|
<span class="sd"> but it works so don't touch it.</span>
|
|
<span class="sd"> """</span>
|
|
|
|
<span class="k">if</span> <span class="n">_debug</span><span class="p">():</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="sa">f</span><span class="s2">"_process_database5"</span><span class="p">)</span>
|
|
<span class="n">verbose</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_verbose</span>
|
|
<span class="n">verbose</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Processing database."</span><span class="p">)</span>
|
|
<span class="p">(</span><span class="n">conn</span><span class="p">,</span> <span class="n">c</span><span class="p">)</span> <span class="o">=</span> <span class="n">_open_sql_file</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_tmp_db</span><span class="p">)</span>
|
|
|
|
<span class="c1"># some of the tables/columns have different names in different versions of Photos</span>
|
|
<span class="n">photos_ver</span> <span class="o">=</span> <span class="n">get_db_model_version</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_tmp_db</span><span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_photos_ver</span> <span class="o">=</span> <span class="n">photos_ver</span>
|
|
<span class="n">verbose</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Database version: </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">_db_version</span><span class="si">}</span><span class="s2">, </span><span class="si">{</span><span class="n">photos_ver</span><span class="si">}</span><span class="s2">."</span><span class="p">)</span>
|
|
<span class="n">asset_table</span> <span class="o">=</span> <span class="n">_DB_TABLE_NAMES</span><span class="p">[</span><span class="n">photos_ver</span><span class="p">][</span><span class="s2">"ASSET"</span><span class="p">]</span>
|
|
<span class="n">keyword_join</span> <span class="o">=</span> <span class="n">_DB_TABLE_NAMES</span><span class="p">[</span><span class="n">photos_ver</span><span class="p">][</span><span class="s2">"KEYWORD_JOIN"</span><span class="p">]</span>
|
|
<span class="n">album_join</span> <span class="o">=</span> <span class="n">_DB_TABLE_NAMES</span><span class="p">[</span><span class="n">photos_ver</span><span class="p">][</span><span class="s2">"ALBUM_JOIN"</span><span class="p">]</span>
|
|
<span class="n">album_sort</span> <span class="o">=</span> <span class="n">_DB_TABLE_NAMES</span><span class="p">[</span><span class="n">photos_ver</span><span class="p">][</span><span class="s2">"ALBUM_SORT_ORDER"</span><span class="p">]</span>
|
|
<span class="n">import_fok</span> <span class="o">=</span> <span class="n">_DB_TABLE_NAMES</span><span class="p">[</span><span class="n">photos_ver</span><span class="p">][</span><span class="s2">"IMPORT_FOK"</span><span class="p">]</span>
|
|
<span class="n">depth_state</span> <span class="o">=</span> <span class="n">_DB_TABLE_NAMES</span><span class="p">[</span><span class="n">photos_ver</span><span class="p">][</span><span class="s2">"DEPTH_STATE"</span><span class="p">]</span>
|
|
|
|
<span class="c1"># Look for all combinations of persons and pictures</span>
|
|
<span class="k">if</span> <span class="n">_debug</span><span class="p">():</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Getting information about persons"</span><span class="p">)</span>
|
|
|
|
<span class="c1"># get info to associate persons with photos</span>
|
|
<span class="c1"># then get detected faces in each photo and link to persons</span>
|
|
<span class="n">verbose</span><span class="p">(</span><span class="s2">"Processing persons in photos."</span><span class="p">)</span>
|
|
<span class="n">c</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span>
|
|
<span class="sd">""" SELECT</span>
|
|
<span class="sd"> ZPERSON.Z_PK,</span>
|
|
<span class="sd"> ZPERSON.ZPERSONUUID,</span>
|
|
<span class="sd"> ZPERSON.ZFULLNAME,</span>
|
|
<span class="sd"> ZPERSON.ZFACECOUNT,</span>
|
|
<span class="sd"> ZPERSON.ZKEYFACE,</span>
|
|
<span class="sd"> ZPERSON.ZDISPLAYNAME</span>
|
|
<span class="sd"> FROM ZPERSON</span>
|
|
<span class="sd"> """</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="c1"># 0 ZPERSON.Z_PK,</span>
|
|
<span class="c1"># 1 ZPERSON.ZPERSONUUID,</span>
|
|
<span class="c1"># 2 ZPERSON.ZFULLNAME,</span>
|
|
<span class="c1"># 3 ZPERSON.ZFACECOUNT,</span>
|
|
<span class="c1"># 4 ZPERSON.ZKEYFACE,</span>
|
|
<span class="c1"># 5 ZPERSON.ZDISPLAYNAME</span>
|
|
|
|
<span class="k">for</span> <span class="n">person</span> <span class="ow">in</span> <span class="n">c</span><span class="p">:</span>
|
|
<span class="n">pk</span> <span class="o">=</span> <span class="n">person</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
|
<span class="n">fullname</span> <span class="o">=</span> <span class="n">person</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="k">if</span> <span class="n">person</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="o">!=</span> <span class="s2">""</span> <span class="k">else</span> <span class="n">_UNKNOWN_PERSON</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbpersons_pk</span><span class="p">[</span><span class="n">pk</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span>
|
|
<span class="s2">"pk"</span><span class="p">:</span> <span class="n">pk</span><span class="p">,</span>
|
|
<span class="s2">"uuid"</span><span class="p">:</span> <span class="n">person</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span>
|
|
<span class="s2">"fullname"</span><span class="p">:</span> <span class="n">fullname</span><span class="p">,</span>
|
|
<span class="s2">"facecount"</span><span class="p">:</span> <span class="n">person</span><span class="p">[</span><span class="mi">3</span><span class="p">],</span>
|
|
<span class="s2">"keyface"</span><span class="p">:</span> <span class="n">person</span><span class="p">[</span><span class="mi">4</span><span class="p">],</span>
|
|
<span class="s2">"displayname"</span><span class="p">:</span> <span class="n">person</span><span class="p">[</span><span class="mi">5</span><span class="p">],</span>
|
|
<span class="s2">"photo_uuid"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
|
|
<span class="s2">"keyface_uuid"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span>
|
|
<span class="p">}</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbpersons_fullname</span><span class="p">[</span><span class="n">fullname</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">pk</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbpersons_fullname</span><span class="p">[</span><span class="n">fullname</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="n">pk</span><span class="p">]</span>
|
|
|
|
<span class="c1"># get info on keyface -- some photos have null keyface so can't do a single query</span>
|
|
<span class="c1"># (at least not with my SQL skills)</span>
|
|
<span class="n">c</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span>
|
|
<span class="sa">f</span><span class="s2">""" SELECT</span>
|
|
<span class="s2"> ZPERSON.Z_PK,</span>
|
|
<span class="s2"> ZPERSON.ZKEYFACE,</span>
|
|
<span class="s2"> </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.ZUUID,</span>
|
|
<span class="s2"> ZDETECTEDFACE.ZUUID</span>
|
|
<span class="s2"> FROM ZPERSON, ZDETECTEDFACE, </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2"></span>
|
|
<span class="s2"> WHERE ZDETECTEDFACE.Z_PK = ZPERSON.ZKEYFACE AND</span>
|
|
<span class="s2"> ZDETECTEDFACE.ZASSET = </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.Z_PK</span>
|
|
<span class="s2"> """</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="c1"># 0 ZPERSON.Z_PK,</span>
|
|
<span class="c1"># 1 ZPERSON.ZKEYFACE,</span>
|
|
<span class="c1"># 2 ZGENERICASSET.ZUUID,</span>
|
|
<span class="c1"># 3 ZDETECTEDFACE.ZUUID</span>
|
|
|
|
<span class="k">for</span> <span class="n">person</span> <span class="ow">in</span> <span class="n">c</span><span class="p">:</span>
|
|
<span class="n">pk</span> <span class="o">=</span> <span class="n">person</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbpersons_pk</span><span class="p">[</span><span class="n">pk</span><span class="p">][</span><span class="s2">"photo_uuid"</span><span class="p">]</span> <span class="o">=</span> <span class="n">person</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbpersons_pk</span><span class="p">[</span><span class="n">pk</span><span class="p">][</span><span class="s2">"keyface_uuid"</span><span class="p">]</span> <span class="o">=</span> <span class="n">person</span><span class="p">[</span><span class="mi">3</span><span class="p">]</span>
|
|
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Unexpected KeyError _dbpersons_pk[</span><span class="si">{</span><span class="n">pk</span><span class="si">}</span><span class="s2">]"</span><span class="p">)</span>
|
|
|
|
<span class="c1"># get information on detected faces</span>
|
|
<span class="n">verbose</span><span class="p">(</span><span class="s2">"Processing detected faces in photos."</span><span class="p">)</span>
|
|
<span class="n">c</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span>
|
|
<span class="sa">f</span><span class="s2">""" SELECT</span>
|
|
<span class="s2"> ZPERSON.Z_PK,</span>
|
|
<span class="s2"> </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.ZUUID</span>
|
|
<span class="s2"> FROM ZPERSON, ZDETECTEDFACE, </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2"></span>
|
|
<span class="s2"> WHERE ZDETECTEDFACE.ZPERSON = ZPERSON.Z_PK AND</span>
|
|
<span class="s2"> ZDETECTEDFACE.ZASSET = </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.Z_PK</span>
|
|
<span class="s2"> """</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="c1"># 0 ZPERSON.Z_PK,</span>
|
|
<span class="c1"># 1 ZGENERICASSET.ZUUID,</span>
|
|
|
|
<span class="k">for</span> <span class="n">face</span> <span class="ow">in</span> <span class="n">c</span><span class="p">:</span>
|
|
<span class="n">pk</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
|
<span class="n">uuid</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbfaces_uuid</span><span class="p">[</span><span class="n">uuid</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">pk</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbfaces_uuid</span><span class="p">[</span><span class="n">uuid</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="n">pk</span><span class="p">]</span>
|
|
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbfaces_pk</span><span class="p">[</span><span class="n">pk</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">uuid</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbfaces_pk</span><span class="p">[</span><span class="n">pk</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="n">uuid</span><span class="p">]</span>
|
|
|
|
<span class="k">if</span> <span class="n">_debug</span><span class="p">():</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Finished walking through persons"</span><span class="p">)</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">pformat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbpersons_pk</span><span class="p">))</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">pformat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbpersons_fullname</span><span class="p">))</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">pformat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbfaces_pk</span><span class="p">))</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">pformat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbfaces_uuid</span><span class="p">))</span>
|
|
|
|
<span class="c1"># get details about albums</span>
|
|
<span class="n">verbose</span><span class="p">(</span><span class="s2">"Processing albums."</span><span class="p">)</span>
|
|
<span class="n">c</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span>
|
|
<span class="sa">f</span><span class="s2">""" SELECT </span>
|
|
<span class="s2"> ZGENERICALBUM.ZUUID, </span>
|
|
<span class="s2"> </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.ZUUID,</span>
|
|
<span class="s2"> </span><span class="si">{</span><span class="n">album_sort</span><span class="si">}</span><span class="s2"></span>
|
|
<span class="s2"> FROM </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2"> </span>
|
|
<span class="s2"> JOIN Z_26ASSETS ON </span><span class="si">{</span><span class="n">album_join</span><span class="si">}</span><span class="s2"> = </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.Z_PK </span>
|
|
<span class="s2"> JOIN ZGENERICALBUM ON ZGENERICALBUM.Z_PK = Z_26ASSETS.Z_26ALBUMS</span>
|
|
<span class="s2"> """</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="c1"># 0 ZGENERICALBUM.ZUUID,</span>
|
|
<span class="c1"># 1 ZGENERICASSET.ZUUID,</span>
|
|
<span class="c1"># 2 Z_26ASSETS.Z_FOK_34ASSETS</span>
|
|
|
|
<span class="k">for</span> <span class="n">album</span> <span class="ow">in</span> <span class="n">c</span><span class="p">:</span>
|
|
<span class="c1"># store by uuid in _dbalbums_uuid and by album in _dbalbums_album</span>
|
|
<span class="n">album_uuid</span> <span class="o">=</span> <span class="n">album</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
|
<span class="n">photo_uuid</span> <span class="o">=</span> <span class="n">album</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
|
|
<span class="n">sort_order</span> <span class="o">=</span> <span class="n">album</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbalbums_uuid</span><span class="p">[</span><span class="n">photo_uuid</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">album_uuid</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbalbums_uuid</span><span class="p">[</span><span class="n">photo_uuid</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="n">album_uuid</span><span class="p">]</span>
|
|
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbalbums_album</span><span class="p">[</span><span class="n">album_uuid</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">photo_uuid</span><span class="p">,</span> <span class="n">sort_order</span><span class="p">))</span>
|
|
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbalbums_album</span><span class="p">[</span><span class="n">album_uuid</span><span class="p">]</span> <span class="o">=</span> <span class="p">[(</span><span class="n">photo_uuid</span><span class="p">,</span> <span class="n">sort_order</span><span class="p">)]</span>
|
|
|
|
<span class="c1"># now get additional details about albums</span>
|
|
<span class="n">c</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span>
|
|
<span class="s2">"SELECT "</span>
|
|
<span class="s2">"ZUUID, "</span> <span class="c1"># 0</span>
|
|
<span class="s2">"ZTITLE, "</span> <span class="c1"># 1</span>
|
|
<span class="s2">"ZCLOUDLOCALSTATE, "</span> <span class="c1"># 2</span>
|
|
<span class="s2">"ZCLOUDOWNERFIRSTNAME, "</span> <span class="c1"># 3</span>
|
|
<span class="s2">"ZCLOUDOWNERLASTNAME, "</span> <span class="c1"># 4</span>
|
|
<span class="s2">"ZCLOUDOWNERHASHEDPERSONID, "</span> <span class="c1"># 5</span>
|
|
<span class="s2">"ZKIND, "</span> <span class="c1"># 6</span>
|
|
<span class="s2">"ZPARENTFOLDER, "</span> <span class="c1"># 7</span>
|
|
<span class="s2">"Z_PK, "</span> <span class="c1"># 8</span>
|
|
<span class="s2">"ZTRASHEDSTATE, "</span> <span class="c1"># 9</span>
|
|
<span class="s2">"ZCREATIONDATE, "</span> <span class="c1"># 10</span>
|
|
<span class="s2">"ZSTARTDATE, "</span> <span class="c1"># 11</span>
|
|
<span class="s2">"ZENDDATE "</span> <span class="c1"># 12</span>
|
|
<span class="s2">"FROM ZGENERICALBUM "</span>
|
|
<span class="p">)</span>
|
|
<span class="k">for</span> <span class="n">album</span> <span class="ow">in</span> <span class="n">c</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbalbum_details</span><span class="p">[</span><span class="n">album</span><span class="p">[</span><span class="mi">0</span><span class="p">]]</span> <span class="o">=</span> <span class="p">{</span>
|
|
<span class="s2">"_uuid"</span><span class="p">:</span> <span class="n">album</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span>
|
|
<span class="s2">"title"</span><span class="p">:</span> <span class="n">normalize_unicode</span><span class="p">(</span><span class="n">album</span><span class="p">[</span><span class="mi">1</span><span class="p">]),</span>
|
|
<span class="s2">"cloudlocalstate"</span><span class="p">:</span> <span class="n">album</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span>
|
|
<span class="s2">"cloudownerfirstname"</span><span class="p">:</span> <span class="n">album</span><span class="p">[</span><span class="mi">3</span><span class="p">],</span>
|
|
<span class="s2">"cloudownderlastname"</span><span class="p">:</span> <span class="n">album</span><span class="p">[</span><span class="mi">4</span><span class="p">],</span>
|
|
<span class="s2">"cloudownerhashedpersonid"</span><span class="p">:</span> <span class="n">album</span><span class="p">[</span><span class="mi">5</span><span class="p">],</span>
|
|
<span class="s2">"cloudlibrarystate"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span> <span class="c1"># Photos 4</span>
|
|
<span class="s2">"cloudidentifier"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span> <span class="c1"># Photos 4</span>
|
|
<span class="s2">"kind"</span><span class="p">:</span> <span class="n">album</span><span class="p">[</span><span class="mi">6</span><span class="p">],</span>
|
|
<span class="s2">"parentfolder"</span><span class="p">:</span> <span class="n">album</span><span class="p">[</span><span class="mi">7</span><span class="p">],</span>
|
|
<span class="s2">"pk"</span><span class="p">:</span> <span class="n">album</span><span class="p">[</span><span class="mi">8</span><span class="p">],</span>
|
|
<span class="s2">"intrash"</span><span class="p">:</span> <span class="kc">False</span> <span class="k">if</span> <span class="n">album</span><span class="p">[</span><span class="mi">9</span><span class="p">]</span> <span class="o">==</span> <span class="mi">0</span> <span class="k">else</span> <span class="kc">True</span><span class="p">,</span>
|
|
<span class="s2">"creation_date"</span><span class="p">:</span> <span class="n">album</span><span class="p">[</span><span class="mi">10</span><span class="p">],</span>
|
|
<span class="s2">"start_date"</span><span class="p">:</span> <span class="n">album</span><span class="p">[</span><span class="mi">11</span><span class="p">],</span>
|
|
<span class="s2">"end_date"</span><span class="p">:</span> <span class="n">album</span><span class="p">[</span><span class="mi">12</span><span class="p">],</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="c1"># add cross-reference by pk to uuid</span>
|
|
<span class="c1"># needed to extract folder hierarchy</span>
|
|
<span class="c1"># in Photos >= 5, folders are special albums</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbalbums_pk</span><span class="p">[</span><span class="n">album</span><span class="p">[</span><span class="mi">8</span><span class="p">]]</span> <span class="o">=</span> <span class="n">album</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
|
|
|
<span class="c1"># get pk of root folder</span>
|
|
<span class="n">root_uuid</span> <span class="o">=</span> <span class="p">[</span>
|
|
<span class="n">album</span>
|
|
<span class="k">for</span> <span class="n">album</span><span class="p">,</span> <span class="n">details</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbalbum_details</span><span class="o">.</span><span class="n">items</span><span class="p">()</span>
|
|
<span class="k">if</span> <span class="n">details</span><span class="p">[</span><span class="s2">"kind"</span><span class="p">]</span> <span class="o">==</span> <span class="n">_PHOTOS_5_ROOT_FOLDER_KIND</span>
|
|
<span class="p">]</span>
|
|
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">root_uuid</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">1</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Error finding root folder: </span><span class="si">{</span><span class="n">root_uuid</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_folder_root_pk</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbalbum_details</span><span class="p">[</span><span class="n">root_uuid</span><span class="p">[</span><span class="mi">0</span><span class="p">]][</span><span class="s2">"pk"</span><span class="p">]</span>
|
|
|
|
<span class="c1"># build _dbalbum_folders which is in form uuid: [list of parent uuids]</span>
|
|
<span class="c1"># TODO: look at this code...it works but I think I album can only be in a single folder</span>
|
|
<span class="c1"># which means there's a code path that will never get executed</span>
|
|
<span class="k">for</span> <span class="n">album</span><span class="p">,</span> <span class="n">details</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbalbum_details</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
|
|
<span class="n">pk_parent</span> <span class="o">=</span> <span class="n">details</span><span class="p">[</span><span class="s2">"parentfolder"</span><span class="p">]</span>
|
|
<span class="k">if</span> <span class="n">pk_parent</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">continue</span>
|
|
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">parent</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbalbums_pk</span><span class="p">[</span><span class="n">pk_parent</span><span class="p">]</span>
|
|
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Did not find uuid for album </span><span class="si">{</span><span class="n">album</span><span class="si">}</span><span class="s2"> pk </span><span class="si">{</span><span class="n">pk_parent</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
|
|
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbalbum_parent_folders</span><span class="p">[</span><span class="n">album</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">parent</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbalbum_parent_folders</span><span class="p">[</span><span class="n">album</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="n">parent</span><span class="p">]</span>
|
|
|
|
<span class="k">for</span> <span class="n">album</span><span class="p">,</span> <span class="n">details</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbalbum_details</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
|
|
<span class="c1"># if details["kind"] in [_PHOTOS_5_ALBUM_KIND, _PHOTOS_5_FOLDER_KIND]:</span>
|
|
<span class="k">if</span> <span class="n">details</span><span class="p">[</span><span class="s2">"kind"</span><span class="p">]</span> <span class="o">==</span> <span class="n">_PHOTOS_5_ALBUM_KIND</span><span class="p">:</span>
|
|
<span class="n">folder_hierarchy</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_build_album_folder_hierarchy_5</span><span class="p">(</span><span class="n">album</span><span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbalbum_folders</span><span class="p">[</span><span class="n">album</span><span class="p">]</span> <span class="o">=</span> <span class="n">folder_hierarchy</span>
|
|
<span class="k">elif</span> <span class="n">details</span><span class="p">[</span><span class="s2">"kind"</span><span class="p">]</span> <span class="o">==</span> <span class="n">_PHOTOS_5_SHARED_ALBUM_KIND</span><span class="p">:</span>
|
|
<span class="c1"># shared albums can't be in folders</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbalbum_folders</span><span class="p">[</span><span class="n">album</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>
|
|
|
|
<span class="k">if</span> <span class="n">_debug</span><span class="p">():</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Finished walking through albums"</span><span class="p">)</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">pformat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbalbums_album</span><span class="p">))</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">pformat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbalbums_uuid</span><span class="p">))</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">pformat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbalbum_details</span><span class="p">))</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">pformat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbalbum_folders</span><span class="p">))</span>
|
|
|
|
<span class="c1"># get details on keywords</span>
|
|
<span class="n">verbose</span><span class="p">(</span><span class="s2">"Processing keywords."</span><span class="p">)</span>
|
|
<span class="n">c</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span>
|
|
<span class="sa">f</span><span class="s2">"""SELECT ZKEYWORD.ZTITLE, </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.ZUUID</span>
|
|
<span class="s2"> FROM </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2"> </span>
|
|
<span class="s2"> JOIN ZADDITIONALASSETATTRIBUTES ON ZADDITIONALASSETATTRIBUTES.ZASSET = </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.Z_PK </span>
|
|
<span class="s2"> JOIN Z_1KEYWORDS ON Z_1KEYWORDS.Z_1ASSETATTRIBUTES = ZADDITIONALASSETATTRIBUTES.Z_PK </span>
|
|
<span class="s2"> JOIN ZKEYWORD ON ZKEYWORD.Z_PK = </span><span class="si">{</span><span class="n">keyword_join</span><span class="si">}</span><span class="s2"> """</span>
|
|
<span class="p">)</span>
|
|
<span class="k">for</span> <span class="n">keyword</span> <span class="ow">in</span> <span class="n">c</span><span class="p">:</span>
|
|
<span class="n">keyword_title</span> <span class="o">=</span> <span class="n">normalize_unicode</span><span class="p">(</span><span class="n">keyword</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">keyword</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbkeywords_uuid</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbkeywords_uuid</span><span class="p">[</span><span class="n">keyword</span><span class="p">[</span><span class="mi">1</span><span class="p">]]</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">keyword_title</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbkeywords_keyword</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbkeywords_keyword</span><span class="p">[</span><span class="n">keyword_title</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbkeywords_uuid</span><span class="p">[</span><span class="n">keyword</span><span class="p">[</span><span class="mi">1</span><span class="p">]]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">keyword</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbkeywords_keyword</span><span class="p">[</span><span class="n">keyword_title</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">keyword</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
|
|
|
|
<span class="k">if</span> <span class="n">_debug</span><span class="p">():</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Finished walking through keywords"</span><span class="p">)</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">pformat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbkeywords_keyword</span><span class="p">))</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">pformat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbkeywords_uuid</span><span class="p">))</span>
|
|
|
|
<span class="c1"># get details on disk volumes</span>
|
|
<span class="n">c</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"SELECT ZUUID, ZNAME from ZFILESYSTEMVOLUME"</span><span class="p">)</span>
|
|
<span class="k">for</span> <span class="n">vol</span> <span class="ow">in</span> <span class="n">c</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbvolumes</span><span class="p">[</span><span class="n">vol</span><span class="p">[</span><span class="mi">0</span><span class="p">]]</span> <span class="o">=</span> <span class="n">vol</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
|
|
|
|
<span class="k">if</span> <span class="n">_debug</span><span class="p">():</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Finished walking through volumes"</span><span class="p">)</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbvolumes</span><span class="p">)</span>
|
|
|
|
<span class="c1"># get details about photos</span>
|
|
<span class="n">verbose</span><span class="p">(</span><span class="s2">"Processing photo details."</span><span class="p">)</span>
|
|
<span class="n">c</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span>
|
|
<span class="sa">f</span><span class="s2">"""SELECT </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.ZUUID, </span>
|
|
<span class="s2"> ZADDITIONALASSETATTRIBUTES.ZMASTERFINGERPRINT, </span>
|
|
<span class="s2"> ZADDITIONALASSETATTRIBUTES.ZTITLE, </span>
|
|
<span class="s2"> ZADDITIONALASSETATTRIBUTES.ZORIGINALFILENAME, </span>
|
|
<span class="s2"> </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.ZMODIFICATIONDATE, </span>
|
|
<span class="s2"> </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.ZDATECREATED, </span>
|
|
<span class="s2"> ZADDITIONALASSETATTRIBUTES.ZTIMEZONEOFFSET, </span>
|
|
<span class="s2"> ZADDITIONALASSETATTRIBUTES.ZINFERREDTIMEZONEOFFSET, </span>
|
|
<span class="s2"> ZADDITIONALASSETATTRIBUTES.ZTIMEZONENAME, </span>
|
|
<span class="s2"> </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.ZHIDDEN, </span>
|
|
<span class="s2"> </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.ZFAVORITE, </span>
|
|
<span class="s2"> </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.ZDIRECTORY, </span>
|
|
<span class="s2"> </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.ZFILENAME, </span>
|
|
<span class="s2"> </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.ZLATITUDE, </span>
|
|
<span class="s2"> </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.ZLONGITUDE, </span>
|
|
<span class="s2"> </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.ZHASADJUSTMENTS, </span>
|
|
<span class="s2"> </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.ZCLOUDBATCHPUBLISHDATE, </span>
|
|
<span class="s2"> </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.ZKIND, </span>
|
|
<span class="s2"> </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.ZUNIFORMTYPEIDENTIFIER,</span>
|
|
<span class="s2"> </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.ZAVALANCHEUUID,</span>
|
|
<span class="s2"> </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.ZAVALANCHEPICKTYPE,</span>
|
|
<span class="s2"> </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.ZKINDSUBTYPE,</span>
|
|
<span class="s2"> </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.ZCUSTOMRENDEREDVALUE,</span>
|
|
<span class="s2"> ZADDITIONALASSETATTRIBUTES.ZCAMERACAPTUREDEVICE,</span>
|
|
<span class="s2"> </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.ZCLOUDASSETGUID,</span>
|
|
<span class="s2"> ZADDITIONALASSETATTRIBUTES.ZREVERSELOCATIONDATA,</span>
|
|
<span class="s2"> </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.ZMOMENT,</span>
|
|
<span class="s2"> ZADDITIONALASSETATTRIBUTES.ZORIGINALRESOURCECHOICE,</span>
|
|
<span class="s2"> </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.ZTRASHEDSTATE,</span>
|
|
<span class="s2"> </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.ZHEIGHT, </span>
|
|
<span class="s2"> </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.ZWIDTH, </span>
|
|
<span class="s2"> </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.ZORIENTATION, </span>
|
|
<span class="s2"> ZADDITIONALASSETATTRIBUTES.ZORIGINALHEIGHT, </span>
|
|
<span class="s2"> ZADDITIONALASSETATTRIBUTES.ZORIGINALWIDTH, </span>
|
|
<span class="s2"> ZADDITIONALASSETATTRIBUTES.ZORIGINALORIENTATION,</span>
|
|
<span class="s2"> ZADDITIONALASSETATTRIBUTES.ZORIGINALFILESIZE,</span>
|
|
<span class="s2"> </span><span class="si">{</span><span class="n">depth_state</span><span class="si">}</span><span class="s2">,</span>
|
|
<span class="s2"> </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.ZADJUSTMENTTIMESTAMP,</span>
|
|
<span class="s2"> </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.ZVISIBILITYSTATE,</span>
|
|
<span class="s2"> </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.ZTRASHEDDATE,</span>
|
|
<span class="s2"> </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.ZSAVEDASSETTYPE</span>
|
|
<span class="s2"> FROM </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2"> </span>
|
|
<span class="s2"> JOIN ZADDITIONALASSETATTRIBUTES ON ZADDITIONALASSETATTRIBUTES.ZASSET = </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.Z_PK </span>
|
|
<span class="s2"> ORDER BY </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.ZUUID """</span>
|
|
<span class="p">)</span>
|
|
<span class="c1"># Order of results</span>
|
|
<span class="c1"># 0 SELECT ZGENERICASSET.ZUUID,</span>
|
|
<span class="c1"># 1 ZADDITIONALASSETATTRIBUTES.ZMASTERFINGERPRINT,</span>
|
|
<span class="c1"># 2 ZADDITIONALASSETATTRIBUTES.ZTITLE,</span>
|
|
<span class="c1"># 3 ZADDITIONALASSETATTRIBUTES.ZORIGINALFILENAME,</span>
|
|
<span class="c1"># 4 ZGENERICASSET.ZMODIFICATIONDATE,</span>
|
|
<span class="c1"># 5 ZGENERICASSET.ZDATECREATED,</span>
|
|
<span class="c1"># 6 ZADDITIONALASSETATTRIBUTES.ZTIMEZONEOFFSET,</span>
|
|
<span class="c1"># 7 ZADDITIONALASSETATTRIBUTES.ZINFERREDTIMEZONEOFFSET,</span>
|
|
<span class="c1"># 8 ZADDITIONALASSETATTRIBUTES.ZTIMEZONENAME,</span>
|
|
<span class="c1"># 9 ZGENERICASSET.ZHIDDEN,</span>
|
|
<span class="c1"># 10 ZGENERICASSET.ZFAVORITE,</span>
|
|
<span class="c1"># 11 ZGENERICASSET.ZDIRECTORY,</span>
|
|
<span class="c1"># 12 ZGENERICASSET.ZFILENAME,</span>
|
|
<span class="c1"># 13 ZGENERICASSET.ZLATITUDE,</span>
|
|
<span class="c1"># 14 ZGENERICASSET.ZLONGITUDE,</span>
|
|
<span class="c1"># 15 ZGENERICASSET.ZHASADJUSTMENTS</span>
|
|
<span class="c1"># 16 ZCLOUDBATCHPUBLISHDATE -- If not null, indicates a shared photo</span>
|
|
<span class="c1"># 17 ZKIND, -- 0 = photo, 1 = movie</span>
|
|
<span class="c1"># 18 ZUNIFORMTYPEIDENTIFIER -- UTI</span>
|
|
<span class="c1"># 19 ZGENERICASSET.ZAVALANCHEUUID, -- if not NULL, is burst photo</span>
|
|
<span class="c1"># 20 ZGENERICASSET.ZAVALANCHEPICKTYPE -- if not 2, is a selected burst photo</span>
|
|
<span class="c1"># 21 ZGENERICASSET.ZKINDSUBTYPE -- determine if live photos, etc</span>
|
|
<span class="c1"># 22 ZGENERICASSET.ZCUSTOMRENDEREDVALUE -- determine if HDR photo</span>
|
|
<span class="c1"># 23 ZADDITIONALASSETATTRIBUTES.ZCAMERACAPTUREDEVICE -- 1 if selfie (front facing camera)</span>
|
|
<span class="c1"># 24 ZGENERICASSET.ZCLOUDASSETGUID -- not null if asset is cloud asset</span>
|
|
<span class="c1"># (e.g. user has "iCloud Photos" checked in Photos preferences)</span>
|
|
<span class="c1"># 25 ZADDITIONALASSETATTRIBUTES.ZREVERSELOCATIONDATA -- reverse geolocation data</span>
|
|
<span class="c1"># 26 ZGENERICASSET.ZMOMENT -- FK for ZMOMENT.Z_PK</span>
|
|
<span class="c1"># 27 ZADDITIONALASSETATTRIBUTES.ZORIGINALRESOURCECHOICE -- 1 if associated RAW image is original else 0</span>
|
|
<span class="c1"># 28 ZGENERICASSET.ZTRASHEDSTATE -- 0 if not in trash, 1 if in trash</span>
|
|
<span class="c1"># 29 ZGENERICASSET.ZHEIGHT,</span>
|
|
<span class="c1"># 30 ZGENERICASSET.ZWIDTH,</span>
|
|
<span class="c1"># 31 ZGENERICASSET.ZORIENTATION,</span>
|
|
<span class="c1"># 32 ZADDITIONALASSETATTRIBUTES.ZORIGINALHEIGHT,</span>
|
|
<span class="c1"># 33 ZADDITIONALASSETATTRIBUTES.ZORIGINALWIDTH,</span>
|
|
<span class="c1"># 34 ZADDITIONALASSETATTRIBUTES.ZORIGINALORIENTATION,</span>
|
|
<span class="c1"># 35 ZADDITIONALASSETATTRIBUTES.ZORIGINALFILESIZE</span>
|
|
<span class="c1"># 36 ZGENERICASSET.ZDEPTHSTATES / ZASSET.ZDEPTHTYPE</span>
|
|
<span class="c1"># 37 ZGENERICASSET.ZADJUSTMENTTIMESTAMP -- when was photo edited?</span>
|
|
<span class="c1"># 38 ZGENERICASSET.ZVISIBILITYSTATE -- 0 if visible, 2 if not (e.g. a burst image)</span>
|
|
<span class="c1"># 39 ZGENERICASSET.ZTRASHEDDATE -- date item placed in the trash or null if not in trash</span>
|
|
<span class="c1"># 40 ZGENERICASSET.ZSAVEDASSETTYPE -- how item imported</span>
|
|
|
|
<span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">c</span><span class="p">:</span>
|
|
<span class="n">uuid</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
|
<span class="n">info</span> <span class="o">=</span> <span class="p">{}</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"_uuid"</span><span class="p">]</span> <span class="o">=</span> <span class="n">uuid</span> <span class="c1"># stored here for easier debugging</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"modelID"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"masterUuid"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"masterFingerprint"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"name"</span><span class="p">]</span> <span class="o">=</span> <span class="n">normalize_unicode</span><span class="p">(</span><span class="n">row</span><span class="p">[</span><span class="mi">2</span><span class="p">])</span>
|
|
|
|
<span class="c1"># There are sometimes negative values for lastmodifieddate in the database</span>
|
|
<span class="c1"># I don't know what these mean but they will raise exception in datetime if</span>
|
|
<span class="c1"># not accounted for</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"lastmodifieddate_timestamp"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">37</span><span class="p">]</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"lastmodifieddate"</span><span class="p">]</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">fromtimestamp</span><span class="p">(</span><span class="n">row</span><span class="p">[</span><span class="mi">37</span><span class="p">]</span> <span class="o">+</span> <span class="n">TIME_DELTA</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="p">(</span><span class="ne">ValueError</span><span class="p">,</span> <span class="ne">TypeError</span><span class="p">):</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"lastmodifieddate"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"imageTimeZoneOffsetSeconds"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">6</span><span class="p">]</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"imageDate_timestamp"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">5</span><span class="p">]</span>
|
|
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">imagedate</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">fromtimestamp</span><span class="p">(</span><span class="n">row</span><span class="p">[</span><span class="mi">5</span><span class="p">]</span> <span class="o">+</span> <span class="n">TIME_DELTA</span><span class="p">)</span>
|
|
<span class="n">seconds</span> <span class="o">=</span> <span class="n">info</span><span class="p">[</span><span class="s2">"imageTimeZoneOffsetSeconds"</span><span class="p">]</span> <span class="ow">or</span> <span class="mi">0</span>
|
|
<span class="n">delta</span> <span class="o">=</span> <span class="n">timedelta</span><span class="p">(</span><span class="n">seconds</span><span class="o">=</span><span class="n">seconds</span><span class="p">)</span>
|
|
<span class="n">tz</span> <span class="o">=</span> <span class="n">timezone</span><span class="p">(</span><span class="n">delta</span><span class="p">)</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"imageDate"</span><span class="p">]</span> <span class="o">=</span> <span class="n">imagedate</span><span class="o">.</span><span class="n">astimezone</span><span class="p">(</span><span class="n">tz</span><span class="o">=</span><span class="n">tz</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
|
|
<span class="c1"># sometimes imageDate is invalid so use 1 Jan 1970 in UTC as image date</span>
|
|
<span class="n">imagedate</span> <span class="o">=</span> <span class="n">datetime</span><span class="p">(</span><span class="mi">1970</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
|
|
<span class="n">tz</span> <span class="o">=</span> <span class="n">timezone</span><span class="p">(</span><span class="n">timedelta</span><span class="p">(</span><span class="mi">0</span><span class="p">))</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"imageDate"</span><span class="p">]</span> <span class="o">=</span> <span class="n">imagedate</span><span class="o">.</span><span class="n">astimezone</span><span class="p">(</span><span class="n">tz</span><span class="o">=</span><span class="n">tz</span><span class="p">)</span>
|
|
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"hidden"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">9</span><span class="p">]</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"favorite"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">10</span><span class="p">]</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"originalFilename"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">3</span><span class="p">]</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"filename"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">12</span><span class="p">]</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"directory"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">11</span><span class="p">]</span>
|
|
|
|
<span class="c1"># set latitude and longitude</span>
|
|
<span class="c1"># if both latitude and longitude = -180.0, then they are NULL</span>
|
|
<span class="k">if</span> <span class="n">row</span><span class="p">[</span><span class="mi">13</span><span class="p">]</span> <span class="o">==</span> <span class="o">-</span><span class="mf">180.0</span> <span class="ow">and</span> <span class="n">row</span><span class="p">[</span><span class="mi">14</span><span class="p">]</span> <span class="o">==</span> <span class="o">-</span><span class="mf">180.0</span><span class="p">:</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"latitude"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"longitude"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"latitude"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">13</span><span class="p">]</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"longitude"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">14</span><span class="p">]</span>
|
|
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"hasAdjustments"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">15</span><span class="p">]</span>
|
|
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"cloudbatchpublishdate"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">16</span><span class="p">]</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"shared"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span> <span class="k">if</span> <span class="n">row</span><span class="p">[</span><span class="mi">16</span><span class="p">]</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="k">else</span> <span class="kc">False</span>
|
|
|
|
<span class="c1"># these will get filled in later</span>
|
|
<span class="c1"># init to avoid key errors</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"extendedDescription"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span> <span class="c1"># fill this in later</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"localAvailability"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"remoteAvailability"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"isMissing"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"adjustmentUuid"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"adjustmentFormatID"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
|
|
<span class="c1"># find type</span>
|
|
<span class="k">if</span> <span class="n">row</span><span class="p">[</span><span class="mi">17</span><span class="p">]</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"type"</span><span class="p">]</span> <span class="o">=</span> <span class="n">_PHOTO_TYPE</span>
|
|
<span class="k">elif</span> <span class="n">row</span><span class="p">[</span><span class="mi">17</span><span class="p">]</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"type"</span><span class="p">]</span> <span class="o">=</span> <span class="n">_MOVIE_TYPE</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">_debug</span><span class="p">():</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="sa">f</span><span class="s2">"WARNING: </span><span class="si">{</span><span class="n">uuid</span><span class="si">}</span><span class="s2"> found unknown type </span><span class="si">{</span><span class="n">row</span><span class="p">[</span><span class="mi">17</span><span class="p">]</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"type"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"UTI"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">18</span><span class="p">]</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"UTI_original"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span> <span class="c1"># filled in later</span>
|
|
|
|
<span class="c1"># handle burst photos</span>
|
|
<span class="c1"># if burst photo, determine whether or not it's a selected burst photo</span>
|
|
<span class="c1"># in Photos 5, burstUUID is called avalancheUUID</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"burstUUID"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">19</span><span class="p">]</span> <span class="c1"># avalancheUUID</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"burstPickType"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">20</span><span class="p">]</span> <span class="c1"># avalanchePickType</span>
|
|
<span class="k">if</span> <span class="n">row</span><span class="p">[</span><span class="mi">19</span><span class="p">]</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="c1"># it's a burst photo</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"burst"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span>
|
|
<span class="n">burst_uuid</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">19</span><span class="p">]</span>
|
|
<span class="k">if</span> <span class="n">burst_uuid</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos_burst</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos_burst</span><span class="p">[</span><span class="n">burst_uuid</span><span class="p">]</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos_burst</span><span class="p">[</span><span class="n">burst_uuid</span><span class="p">]</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">uuid</span><span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="c1"># not a burst photo</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"burst"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">False</span>
|
|
|
|
<span class="c1"># Info on sub-type (live photo, panorama, etc)</span>
|
|
<span class="c1"># ZGENERICASSET.ZKINDSUBTYPE</span>
|
|
<span class="c1"># 1 == panorama</span>
|
|
<span class="c1"># 2 == live photo</span>
|
|
<span class="c1"># 10 = screenshot</span>
|
|
<span class="c1"># 100 = shared movie (MP4) ??</span>
|
|
<span class="c1"># 101 = slow-motion video</span>
|
|
<span class="c1"># 102 = Time lapse video</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"subtype"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">21</span><span class="p">]</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"live_photo"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span> <span class="k">if</span> <span class="n">row</span><span class="p">[</span><span class="mi">21</span><span class="p">]</span> <span class="o">==</span> <span class="mi">2</span> <span class="k">else</span> <span class="kc">False</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"screenshot"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span> <span class="k">if</span> <span class="n">row</span><span class="p">[</span><span class="mi">21</span><span class="p">]</span> <span class="o">==</span> <span class="mi">10</span> <span class="k">else</span> <span class="kc">False</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"slow_mo"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span> <span class="k">if</span> <span class="n">row</span><span class="p">[</span><span class="mi">21</span><span class="p">]</span> <span class="o">==</span> <span class="mi">101</span> <span class="k">else</span> <span class="kc">False</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"time_lapse"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span> <span class="k">if</span> <span class="n">row</span><span class="p">[</span><span class="mi">21</span><span class="p">]</span> <span class="o">==</span> <span class="mi">102</span> <span class="k">else</span> <span class="kc">False</span>
|
|
|
|
<span class="c1"># Handle HDR photos and portraits</span>
|
|
<span class="c1"># ZGENERICASSET.ZCUSTOMRENDEREDVALUE</span>
|
|
<span class="c1"># 3 = HDR photo</span>
|
|
<span class="c1"># 4 = non-HDR version of the photo</span>
|
|
<span class="c1"># 6 = panorama</span>
|
|
<span class="c1"># > 6 = portrait (sometimes, see ZDEPTHSTATE/ZDEPTHTYPE)</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"customRenderedValue"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">22</span><span class="p">]</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"hdr"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span> <span class="k">if</span> <span class="n">row</span><span class="p">[</span><span class="mi">22</span><span class="p">]</span> <span class="o">==</span> <span class="mi">3</span> <span class="k">else</span> <span class="kc">False</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"depth_state"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">36</span><span class="p">]</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"portrait"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span> <span class="k">if</span> <span class="n">row</span><span class="p">[</span><span class="mi">36</span><span class="p">]</span> <span class="o">!=</span> <span class="mi">0</span> <span class="k">else</span> <span class="kc">False</span>
|
|
|
|
<span class="c1"># Set panorama from either KindSubType or RenderedValue</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"panorama"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span> <span class="k">if</span> <span class="n">row</span><span class="p">[</span><span class="mi">21</span><span class="p">]</span> <span class="o">==</span> <span class="mi">1</span> <span class="ow">or</span> <span class="n">row</span><span class="p">[</span><span class="mi">22</span><span class="p">]</span> <span class="o">==</span> <span class="mi">6</span> <span class="k">else</span> <span class="kc">False</span>
|
|
|
|
<span class="c1"># Handle selfies (front facing camera, ZCAMERACAPTUREDEVICE=1)</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"selfie"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span> <span class="k">if</span> <span class="n">row</span><span class="p">[</span><span class="mi">23</span><span class="p">]</span> <span class="o">==</span> <span class="mi">1</span> <span class="k">else</span> <span class="kc">False</span>
|
|
|
|
<span class="c1"># Determine if photo is part of cloud library (ZGENERICASSET.ZCLOUDASSETGUID not NULL)</span>
|
|
<span class="c1"># Initialize cloud fields that will filled in later</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"cloudAssetGUID"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">24</span><span class="p">]</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"cloudLocalState"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"incloud"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"cloudLibraryState"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span> <span class="c1"># Photos 4</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"cloudStatus"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span> <span class="c1"># Photos 4</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"cloudAvailable"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span> <span class="c1"># Photos 4</span>
|
|
|
|
<span class="c1"># reverse geolocation info</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"reverse_geolocation"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">25</span><span class="p">]</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"placeIDs"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span> <span class="c1"># Photos 4</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"placeNames"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span> <span class="c1"># Photos 4</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"countryCode"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span> <span class="c1"># Photos 4</span>
|
|
|
|
<span class="c1"># moment info</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"momentID"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">26</span><span class="p">]</span>
|
|
|
|
<span class="c1"># original resource choice (e.g. RAW or jpeg)</span>
|
|
<span class="c1"># for images part of a RAW/jpeg pair,</span>
|
|
<span class="c1"># ZADDITIONALASSETATTRIBUTES.ZORIGINALRESOURCECHOICE</span>
|
|
<span class="c1"># = 0 if jpeg is selected as "original" in Photos (the default)</span>
|
|
<span class="c1"># = 1 if RAW is selected as "original" in Photos</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"original_resource_choice"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">27</span><span class="p">]</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"raw_is_original"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span> <span class="k">if</span> <span class="n">row</span><span class="p">[</span><span class="mi">27</span><span class="p">]</span> <span class="o">==</span> <span class="mi">1</span> <span class="k">else</span> <span class="kc">False</span>
|
|
|
|
<span class="c1"># recently deleted items</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"intrash"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span> <span class="k">if</span> <span class="n">row</span><span class="p">[</span><span class="mi">28</span><span class="p">]</span> <span class="o">==</span> <span class="mi">1</span> <span class="k">else</span> <span class="kc">False</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"trasheddate_timestamp"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">39</span><span class="p">]</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"trasheddate"</span><span class="p">]</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">fromtimestamp</span><span class="p">(</span><span class="n">row</span><span class="p">[</span><span class="mi">39</span><span class="p">]</span> <span class="o">+</span> <span class="n">TIME_DELTA</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="p">(</span><span class="ne">ValueError</span><span class="p">,</span> <span class="ne">TypeError</span><span class="p">):</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"trasheddate"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
|
|
<span class="c1"># height/width/orientation</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"height"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">29</span><span class="p">]</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"width"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">30</span><span class="p">]</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"orientation"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">31</span><span class="p">]</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"original_height"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">32</span><span class="p">]</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"original_width"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">33</span><span class="p">]</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"original_orientation"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">34</span><span class="p">]</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"original_filesize"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">35</span><span class="p">]</span>
|
|
|
|
<span class="c1"># visibility state, visible (True) if 0, otherwise not visible (False)</span>
|
|
<span class="c1"># only values I've seen are 0 for visible, 2 for not-visible</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"visibility_state"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">38</span><span class="p">]</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"visible"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">38</span><span class="p">]</span> <span class="o">==</span> <span class="mi">0</span>
|
|
|
|
<span class="c1"># ZSAVEDASSETTYPE Values:</span>
|
|
<span class="c1"># 3: imported by copying to Photos library</span>
|
|
<span class="c1"># 4: shared iCloud photo</span>
|
|
<span class="c1"># 6: imported by iCloud (e.g. from iPhone)</span>
|
|
<span class="c1"># 10: referenced file (not copied to Photos library)</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"saved_asset_type"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">40</span><span class="p">]</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"isreference"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">40</span><span class="p">]</span> <span class="o">==</span> <span class="mi">10</span>
|
|
|
|
<span class="c1"># initialize import session info which will be filled in later</span>
|
|
<span class="c1"># not every photo has an import session so initialize all records now</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"import_session"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"fok_import_session"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"import_uuid"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
|
|
<span class="c1"># associated RAW image info</span>
|
|
<span class="c1"># will be filled in later</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"has_raw"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">False</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"raw_data_length"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"UTI_raw"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"datastore_subtype"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"resource_type"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"raw_master_uuid"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span> <span class="c1"># Photos 4</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"non_raw_master_uuid"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span> <span class="c1"># Photos 4</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"alt_master_uuid"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span> <span class="c1"># Photos 4</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"raw_info"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span> <span class="c1"># Photos 4</span>
|
|
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">]</span> <span class="o">=</span> <span class="n">info</span>
|
|
|
|
<span class="c1"># # if row[19] is not None and ((row[20] == 2) or (row[20] == 4)):</span>
|
|
<span class="c1"># # burst photo</span>
|
|
<span class="c1"># if row[19] is not None:</span>
|
|
<span class="c1"># # burst photo, add to _dbphotos_burst</span>
|
|
<span class="c1"># info["burst"] = True</span>
|
|
<span class="c1"># burst_uuid = row[19]</span>
|
|
<span class="c1"># if burst_uuid not in self._dbphotos_burst:</span>
|
|
<span class="c1"># self._dbphotos_burst[burst_uuid] = {}</span>
|
|
<span class="c1"># self._dbphotos_burst[burst_uuid][uuid] = info</span>
|
|
<span class="c1"># else:</span>
|
|
<span class="c1"># info["burst"] = False</span>
|
|
|
|
<span class="c1"># get info on import sessions</span>
|
|
<span class="c1"># 0 ZGENERICASSET.ZUUID</span>
|
|
<span class="c1"># 1 ZGENERICASSET.ZIMPORTSESSION</span>
|
|
<span class="c1"># 2 ZGENERICASSET.Z_FOK_IMPORTSESSION</span>
|
|
<span class="c1"># 3 ZGENERICALBUM.ZUUID,</span>
|
|
<span class="n">verbose</span><span class="p">(</span><span class="s2">"Processing import sessions."</span><span class="p">)</span>
|
|
<span class="n">c</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span>
|
|
<span class="sa">f</span><span class="s2">"""SELECT</span>
|
|
<span class="s2"> </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.ZUUID,</span>
|
|
<span class="s2"> </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.ZIMPORTSESSION,</span>
|
|
<span class="s2"> </span><span class="si">{</span><span class="n">import_fok</span><span class="si">}</span><span class="s2">,</span>
|
|
<span class="s2"> ZGENERICALBUM.ZUUID</span>
|
|
<span class="s2"> FROM</span>
|
|
<span class="s2"> </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2"></span>
|
|
<span class="s2"> JOIN ZGENERICALBUM ON ZGENERICALBUM.Z_PK = </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.ZIMPORTSESSION</span>
|
|
<span class="s2"> """</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">c</span><span class="p">:</span>
|
|
<span class="n">uuid</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"import_session"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"fok_import_session"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"import_uuid"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">3</span><span class="p">]</span>
|
|
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="sa">f</span><span class="s2">"No info record for uuid </span><span class="si">{</span><span class="n">uuid</span><span class="si">}</span><span class="s2"> for import session"</span><span class="p">)</span>
|
|
|
|
<span class="c1"># Get extended description</span>
|
|
<span class="n">verbose</span><span class="p">(</span><span class="s2">"Processing additional photo details."</span><span class="p">)</span>
|
|
<span class="n">c</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span>
|
|
<span class="sa">f</span><span class="s2">"""SELECT </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.ZUUID, </span>
|
|
<span class="s2"> ZASSETDESCRIPTION.ZLONGDESCRIPTION </span>
|
|
<span class="s2"> FROM </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2"> </span>
|
|
<span class="s2"> JOIN ZADDITIONALASSETATTRIBUTES ON ZADDITIONALASSETATTRIBUTES.ZASSET = </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.Z_PK </span>
|
|
<span class="s2"> JOIN ZASSETDESCRIPTION ON ZASSETDESCRIPTION.Z_PK = ZADDITIONALASSETATTRIBUTES.ZASSETDESCRIPTION </span>
|
|
<span class="s2"> ORDER BY </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.ZUUID """</span>
|
|
<span class="p">)</span>
|
|
<span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">c</span><span class="p">:</span>
|
|
<span class="n">uuid</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
|
<span class="k">if</span> <span class="n">uuid</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"extendedDescription"</span><span class="p">]</span> <span class="o">=</span> <span class="n">normalize_unicode</span><span class="p">(</span><span class="n">row</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">_debug</span><span class="p">():</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span>
|
|
<span class="sa">f</span><span class="s2">"WARNING: found description </span><span class="si">{</span><span class="n">row</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span><span class="si">}</span><span class="s2"> but no photo for </span><span class="si">{</span><span class="n">uuid</span><span class="si">}</span><span class="s2">"</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="c1"># get information about adjusted/edited photos</span>
|
|
<span class="n">c</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span>
|
|
<span class="sa">f</span><span class="s2">"""SELECT </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.ZUUID, </span>
|
|
<span class="s2"> </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.ZHASADJUSTMENTS, </span>
|
|
<span class="s2"> ZUNMANAGEDADJUSTMENT.ZADJUSTMENTFORMATIDENTIFIER </span>
|
|
<span class="s2"> FROM </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">, ZUNMANAGEDADJUSTMENT </span>
|
|
<span class="s2"> JOIN ZADDITIONALASSETATTRIBUTES ON ZADDITIONALASSETATTRIBUTES.ZASSET = </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.Z_PK </span>
|
|
<span class="s2"> WHERE ZADDITIONALASSETATTRIBUTES.ZUNMANAGEDADJUSTMENT = ZUNMANAGEDADJUSTMENT.Z_PK """</span>
|
|
<span class="p">)</span>
|
|
<span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">c</span><span class="p">:</span>
|
|
<span class="n">uuid</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
|
<span class="k">if</span> <span class="n">uuid</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"adjustmentFormatID"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">_debug</span><span class="p">():</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span>
|
|
<span class="sa">f</span><span class="s2">"WARNING: found adjustmentformatidentifier </span><span class="si">{</span><span class="n">row</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span><span class="si">}</span><span class="s2"> but no photo for uuid </span><span class="si">{</span><span class="n">row</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="si">}</span><span class="s2">"</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="c1"># Find missing photos</span>
|
|
<span class="c1"># TODO: this code is very kludgy and I had to make lots of assumptions</span>
|
|
<span class="c1"># it's probably wrong and needs to be re-worked once I figure out how to reliably</span>
|
|
<span class="c1"># determine if a photo is missing in Photos 5</span>
|
|
|
|
<span class="c1"># Get info on remote/local availability for photos in shared albums</span>
|
|
<span class="c1"># Also get UTI of original image (zdatastoresubtype = 1)</span>
|
|
<span class="n">c</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span>
|
|
<span class="sa">f</span><span class="s2">""" SELECT </span>
|
|
<span class="s2"> </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.ZUUID, </span>
|
|
<span class="s2"> ZINTERNALRESOURCE.ZLOCALAVAILABILITY, </span>
|
|
<span class="s2"> ZINTERNALRESOURCE.ZREMOTEAVAILABILITY,</span>
|
|
<span class="s2"> ZINTERNALRESOURCE.ZDATASTORESUBTYPE,</span>
|
|
<span class="s2"> ZINTERNALRESOURCE.ZUNIFORMTYPEIDENTIFIER,</span>
|
|
<span class="s2"> ZUNIFORMTYPEIDENTIFIER.ZIDENTIFIER</span>
|
|
<span class="s2"> FROM </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2"></span>
|
|
<span class="s2"> JOIN ZADDITIONALASSETATTRIBUTES ON ZADDITIONALASSETATTRIBUTES.ZASSET = </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.Z_PK </span>
|
|
<span class="s2"> JOIN ZINTERNALRESOURCE ON ZINTERNALRESOURCE.ZASSET = ZADDITIONALASSETATTRIBUTES.ZASSET </span>
|
|
<span class="s2"> JOIN ZUNIFORMTYPEIDENTIFIER ON ZUNIFORMTYPEIDENTIFIER.Z_PK = ZINTERNALRESOURCE.ZUNIFORMTYPEIDENTIFIER </span>
|
|
<span class="s2"> WHERE ZDATASTORESUBTYPE = 1 OR ZDATASTORESUBTYPE = 3 """</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="c1"># Order of results:</span>
|
|
<span class="c1"># 0 {asset_table}.ZUUID,</span>
|
|
<span class="c1"># 1 ZINTERNALRESOURCE.ZLOCALAVAILABILITY,</span>
|
|
<span class="c1"># 2 ZINTERNALRESOURCE.ZREMOTEAVAILABILITY,</span>
|
|
<span class="c1"># 3 ZINTERNALRESOURCE.ZDATASTORESUBTYPE,</span>
|
|
<span class="c1"># 4 ZINTERNALRESOURCE.ZUNIFORMTYPEIDENTIFIER,</span>
|
|
<span class="c1"># 5 ZUNIFORMTYPEIDENTIFIER.ZIDENTIFIER</span>
|
|
|
|
<span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">c</span><span class="p">:</span>
|
|
<span class="n">uuid</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
|
<span class="k">if</span> <span class="n">uuid</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"localAvailability"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"remoteAvailability"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span>
|
|
<span class="k">if</span> <span class="n">row</span><span class="p">[</span><span class="mi">3</span><span class="p">]</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"UTI_original"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">5</span><span class="p">]</span>
|
|
|
|
<span class="k">if</span> <span class="n">row</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">!=</span> <span class="mi">1</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"isMissing"</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"isMissing"</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span>
|
|
|
|
<span class="c1"># get information on local/remote availability</span>
|
|
<span class="n">c</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span>
|
|
<span class="sa">f</span><span class="s2">""" SELECT </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.ZUUID,</span>
|
|
<span class="s2"> ZINTERNALRESOURCE.ZLOCALAVAILABILITY,</span>
|
|
<span class="s2"> ZINTERNALRESOURCE.ZREMOTEAVAILABILITY</span>
|
|
<span class="s2"> FROM </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2"></span>
|
|
<span class="s2"> JOIN ZADDITIONALASSETATTRIBUTES ON ZADDITIONALASSETATTRIBUTES.ZASSET = </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.Z_PK</span>
|
|
<span class="s2"> JOIN ZINTERNALRESOURCE ON ZINTERNALRESOURCE.ZFINGERPRINT = ZADDITIONALASSETATTRIBUTES.ZMASTERFINGERPRINT """</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">c</span><span class="p">:</span>
|
|
<span class="n">uuid</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
|
<span class="k">if</span> <span class="n">uuid</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"localAvailability"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"remoteAvailability"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span>
|
|
|
|
<span class="k">if</span> <span class="n">row</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">!=</span> <span class="mi">1</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"isMissing"</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"isMissing"</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span>
|
|
|
|
<span class="c1"># get information about cloud sync state</span>
|
|
<span class="n">c</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span>
|
|
<span class="sa">f</span><span class="s2">""" SELECT</span>
|
|
<span class="s2"> </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.ZUUID,</span>
|
|
<span class="s2"> ZCLOUDMASTER.ZCLOUDLOCALSTATE</span>
|
|
<span class="s2"> FROM ZCLOUDMASTER, </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2"></span>
|
|
<span class="s2"> WHERE </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.ZMASTER = ZCLOUDMASTER.Z_PK """</span>
|
|
<span class="p">)</span>
|
|
<span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">c</span><span class="p">:</span>
|
|
<span class="n">uuid</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
|
<span class="k">if</span> <span class="n">uuid</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"cloudLocalState"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"incloud"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span> <span class="k">if</span> <span class="n">row</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="mi">3</span> <span class="k">else</span> <span class="kc">False</span>
|
|
|
|
<span class="c1"># get information about associted RAW images</span>
|
|
<span class="c1"># RAW images have ZDATASTORESUBTYPE = 17</span>
|
|
<span class="n">c</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span>
|
|
<span class="sa">f</span><span class="s2">""" SELECT</span>
|
|
<span class="s2"> </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.ZUUID,</span>
|
|
<span class="s2"> ZINTERNALRESOURCE.ZDATALENGTH, </span>
|
|
<span class="s2"> ZUNIFORMTYPEIDENTIFIER.ZIDENTIFIER,</span>
|
|
<span class="s2"> ZINTERNALRESOURCE.ZDATASTORESUBTYPE,</span>
|
|
<span class="s2"> ZINTERNALRESOURCE.ZRESOURCETYPE</span>
|
|
<span class="s2"> FROM </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2"></span>
|
|
<span class="s2"> JOIN ZINTERNALRESOURCE ON ZINTERNALRESOURCE.ZASSET = ZADDITIONALASSETATTRIBUTES.ZASSET</span>
|
|
<span class="s2"> JOIN ZADDITIONALASSETATTRIBUTES ON ZADDITIONALASSETATTRIBUTES.ZASSET = </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.Z_PK </span>
|
|
<span class="s2"> JOIN ZUNIFORMTYPEIDENTIFIER ON ZUNIFORMTYPEIDENTIFIER.Z_PK = ZINTERNALRESOURCE.ZUNIFORMTYPEIDENTIFIER</span>
|
|
<span class="s2"> WHERE ZINTERNALRESOURCE.ZDATASTORESUBTYPE = 17</span>
|
|
<span class="s2"> """</span>
|
|
<span class="p">)</span>
|
|
<span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">c</span><span class="p">:</span>
|
|
<span class="n">uuid</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
|
<span class="k">if</span> <span class="n">uuid</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"has_raw"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"raw_data_length"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"UTI_raw"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"datastore_subtype"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">3</span><span class="p">]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"resource_type"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">4</span><span class="p">]</span>
|
|
|
|
<span class="c1"># add faces and keywords to photo data</span>
|
|
<span class="k">for</span> <span class="n">uuid</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">:</span>
|
|
<span class="c1"># keywords</span>
|
|
<span class="k">if</span> <span class="n">uuid</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbkeywords_uuid</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"hasKeywords"</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"keywords"</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbkeywords_uuid</span><span class="p">[</span><span class="n">uuid</span><span class="p">]</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"hasKeywords"</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"keywords"</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>
|
|
|
|
<span class="k">if</span> <span class="n">uuid</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbfaces_uuid</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"hasPersons"</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"persons"</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbfaces_uuid</span><span class="p">[</span><span class="n">uuid</span><span class="p">]</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"hasPersons"</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"persons"</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>
|
|
|
|
<span class="k">if</span> <span class="n">uuid</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbalbums_uuid</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"albums"</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbalbums_uuid</span><span class="p">[</span><span class="n">uuid</span><span class="p">]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"hasAlbums"</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"albums"</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"hasAlbums"</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span>
|
|
|
|
<span class="c1"># build album_titles dictionary</span>
|
|
<span class="k">for</span> <span class="n">album_id</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbalbum_details</span><span class="p">:</span>
|
|
<span class="n">title</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbalbum_details</span><span class="p">[</span><span class="n">album_id</span><span class="p">][</span><span class="s2">"title"</span><span class="p">]</span>
|
|
<span class="k">if</span> <span class="n">title</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbalbum_titles</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbalbum_titles</span><span class="p">[</span><span class="n">title</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">album_id</span><span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbalbum_titles</span><span class="p">[</span><span class="n">title</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="n">album_id</span><span class="p">]</span>
|
|
|
|
<span class="c1"># country codes (only used in Photos <=4)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_db_countries</span> <span class="o">=</span> <span class="kc">None</span>
|
|
|
|
<span class="c1"># close connection and remove temporary files</span>
|
|
<span class="n">conn</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
|
|
|
|
<span class="c1"># process face info</span>
|
|
<span class="n">verbose</span><span class="p">(</span><span class="s2">"Processing face details."</span><span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_process_faceinfo</span><span class="p">()</span>
|
|
|
|
<span class="c1"># process search info</span>
|
|
<span class="n">verbose</span><span class="p">(</span><span class="s2">"Processing photo labels."</span><span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_process_searchinfo</span><span class="p">()</span>
|
|
|
|
<span class="c1"># process exif info</span>
|
|
<span class="n">verbose</span><span class="p">(</span><span class="s2">"Processing EXIF details."</span><span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_process_exifinfo</span><span class="p">()</span>
|
|
|
|
<span class="c1"># process computed scores</span>
|
|
<span class="n">verbose</span><span class="p">(</span><span class="s2">"Processing computed aesthetic scores."</span><span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_process_scoreinfo</span><span class="p">()</span>
|
|
|
|
<span class="c1"># process shared comments/likes</span>
|
|
<span class="n">verbose</span><span class="p">(</span><span class="s2">"Processing comments and likes for shared photos."</span><span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_process_comments</span><span class="p">()</span>
|
|
|
|
<span class="c1"># done processing, dump debug data if requested</span>
|
|
<span class="n">verbose</span><span class="p">(</span><span class="s2">"Done processing details from Photos library."</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">_debug</span><span class="p">():</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">"Faces (_dbfaces_uuid):"</span><span class="p">)</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">pformat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbfaces_uuid</span><span class="p">))</span>
|
|
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">"Persons (_dbpersons_pk):"</span><span class="p">)</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">pformat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbpersons_pk</span><span class="p">))</span>
|
|
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">"Keywords by uuid (_dbkeywords_uuid):"</span><span class="p">)</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">pformat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbkeywords_uuid</span><span class="p">))</span>
|
|
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">"Keywords by keyword (_dbkeywords_keywords):"</span><span class="p">)</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">pformat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbkeywords_keyword</span><span class="p">))</span>
|
|
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">"Albums by uuid (_dbalbums_uuid):"</span><span class="p">)</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">pformat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbalbums_uuid</span><span class="p">))</span>
|
|
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">"Albums by album (_dbalbums_albums):"</span><span class="p">)</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">pformat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbalbums_album</span><span class="p">))</span>
|
|
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">"Album details (_dbalbum_details):"</span><span class="p">)</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">pformat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbalbum_details</span><span class="p">))</span>
|
|
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">"Album titles (_dbalbum_titles):"</span><span class="p">)</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">pformat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbalbum_titles</span><span class="p">))</span>
|
|
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">"Album folders (_dbalbum_folders):"</span><span class="p">)</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">pformat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbalbum_folders</span><span class="p">))</span>
|
|
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">"Album parent folders (_dbalbum_parent_folders):"</span><span class="p">)</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">pformat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbalbum_parent_folders</span><span class="p">))</span>
|
|
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">"Albums pk (_dbalbums_pk):"</span><span class="p">)</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">pformat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbalbums_pk</span><span class="p">))</span>
|
|
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">"Volumes (_dbvolumes):"</span><span class="p">)</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">pformat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbvolumes</span><span class="p">))</span>
|
|
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">"Photos (_dbphotos):"</span><span class="p">)</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">pformat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">))</span>
|
|
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">"Burst Photos (dbphotos_burst:"</span><span class="p">)</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="n">pformat</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos_burst</span><span class="p">))</span>
|
|
|
|
<span class="k">def</span> <span class="nf">_build_album_folder_hierarchy_5</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">uuid</span><span class="p">,</span> <span class="n">folders</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
|
<span class="sd">""" recursively build folder/album hierarchy</span>
|
|
<span class="sd"> uuid: uuid of the album/folder being processed</span>
|
|
<span class="sd"> folders: dict holding the folder hierarchy """</span>
|
|
|
|
<span class="c1"># get parent uuid</span>
|
|
<span class="n">parent</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbalbum_details</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"parentfolder"</span><span class="p">]</span>
|
|
|
|
<span class="k">if</span> <span class="n">parent</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="n">parent_uuid</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbalbums_pk</span><span class="p">[</span><span class="n">parent</span><span class="p">]</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="c1"># folder with no parent (e.g. shared iCloud folders)</span>
|
|
<span class="k">return</span> <span class="n">folders</span>
|
|
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db_version</span> <span class="o">></span> <span class="n">_PHOTOS_4_VERSION</span> <span class="ow">and</span> <span class="n">parent</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">_folder_root_pk</span><span class="p">:</span>
|
|
<span class="c1"># at the top of the folder hierarchy, we're done</span>
|
|
<span class="k">return</span> <span class="n">folders</span>
|
|
|
|
<span class="c1"># recurse to keep building</span>
|
|
<span class="n">folders</span> <span class="o">=</span> <span class="p">{</span><span class="n">parent_uuid</span><span class="p">:</span> <span class="n">folders</span><span class="p">}</span>
|
|
<span class="n">folders</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_build_album_folder_hierarchy_5</span><span class="p">(</span><span class="n">parent_uuid</span><span class="p">,</span> <span class="n">folders</span><span class="o">=</span><span class="n">folders</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">folders</span>
|
|
|
|
<span class="k">def</span> <span class="nf">_album_folder_hierarchy_list</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">album_uuid</span><span class="p">):</span>
|
|
<span class="sd">""" return appropriate album_folder_hierarchy_list for the _db_version """</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db_version</span> <span class="o"><=</span> <span class="n">_PHOTOS_4_VERSION</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_album_folder_hierarchy_list_4</span><span class="p">(</span><span class="n">album_uuid</span><span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_album_folder_hierarchy_list_5</span><span class="p">(</span><span class="n">album_uuid</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span> <span class="nf">_album_folder_hierarchy_list_4</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">album_uuid</span><span class="p">):</span>
|
|
<span class="sd">""" return hierarchical list of folder names album_uuid is contained in</span>
|
|
<span class="sd"> the folder list is in form:</span>
|
|
<span class="sd"> ["Top level folder", "sub folder 1", "sub folder 2"]</span>
|
|
<span class="sd"> returns empty list of album is not in any folders """</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">folders</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbalbum_folders</span><span class="p">[</span><span class="n">album_uuid</span><span class="p">]</span>
|
|
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Caught _dbalbum_folders KeyError for album: </span><span class="si">{</span><span class="n">album_uuid</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="p">[]</span>
|
|
|
|
<span class="k">def</span> <span class="nf">_recurse_folder_hierarchy</span><span class="p">(</span><span class="n">folders</span><span class="p">,</span> <span class="n">hierarchy</span><span class="o">=</span><span class="p">[]):</span>
|
|
<span class="sd">""" recursively walk the folders dict to build list of folder hierarchy """</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">folders</span><span class="p">:</span>
|
|
<span class="c1"># empty folder dict (album has no folder hierarchy)</span>
|
|
<span class="k">return</span> <span class="p">[]</span>
|
|
|
|
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">folders</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">1</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">"Expected only a single key in folders dict"</span><span class="p">)</span>
|
|
|
|
<span class="n">folder_uuid</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">folders</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span> <span class="c1"># first and only key of dict</span>
|
|
|
|
<span class="n">parent_title</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbfolder_details</span><span class="p">[</span><span class="n">folder_uuid</span><span class="p">][</span><span class="s2">"name"</span><span class="p">]</span>
|
|
<span class="n">hierarchy</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">parent_title</span><span class="p">)</span>
|
|
|
|
<span class="n">folders</span> <span class="o">=</span> <span class="n">folders</span><span class="p">[</span><span class="n">folder_uuid</span><span class="p">]</span>
|
|
<span class="k">if</span> <span class="n">folders</span><span class="p">:</span>
|
|
<span class="c1"># still have elements left to recurse</span>
|
|
<span class="n">hierarchy</span> <span class="o">=</span> <span class="n">_recurse_folder_hierarchy</span><span class="p">(</span><span class="n">folders</span><span class="p">,</span> <span class="n">hierarchy</span><span class="o">=</span><span class="n">hierarchy</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">hierarchy</span>
|
|
|
|
<span class="c1"># no elements left to recurse</span>
|
|
<span class="k">return</span> <span class="n">hierarchy</span>
|
|
|
|
<span class="n">hierarchy</span> <span class="o">=</span> <span class="n">_recurse_folder_hierarchy</span><span class="p">(</span><span class="n">folders</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">hierarchy</span>
|
|
|
|
<span class="k">def</span> <span class="nf">_album_folder_hierarchy_list_5</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">album_uuid</span><span class="p">):</span>
|
|
<span class="sd">""" return hierarchical list of folder names album_uuid is contained in</span>
|
|
<span class="sd"> the folder list is in form:</span>
|
|
<span class="sd"> ["Top level folder", "sub folder 1", "sub folder 2"]</span>
|
|
<span class="sd"> returns empty list of album is not in any folders """</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">folders</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbalbum_folders</span><span class="p">[</span><span class="n">album_uuid</span><span class="p">]</span>
|
|
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Caught _dbalbum_folders KeyError for album: </span><span class="si">{</span><span class="n">album_uuid</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="p">[]</span>
|
|
|
|
<span class="k">def</span> <span class="nf">_recurse_folder_hierarchy</span><span class="p">(</span><span class="n">folders</span><span class="p">,</span> <span class="n">hierarchy</span><span class="o">=</span><span class="p">[]):</span>
|
|
<span class="sd">""" recursively walk the folders dict to build list of folder hierarchy """</span>
|
|
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">folders</span><span class="p">:</span>
|
|
<span class="c1"># empty folder dict (album has no folder hierarchy)</span>
|
|
<span class="k">return</span> <span class="p">[]</span>
|
|
|
|
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">folders</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">1</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">"Expected only a single key in folders dict"</span><span class="p">)</span>
|
|
|
|
<span class="n">folder_uuid</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">folders</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span> <span class="c1"># first and only key of dict</span>
|
|
<span class="n">parent_title</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbalbum_details</span><span class="p">[</span><span class="n">folder_uuid</span><span class="p">][</span><span class="s2">"title"</span><span class="p">]</span>
|
|
<span class="n">hierarchy</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">parent_title</span><span class="p">)</span>
|
|
|
|
<span class="n">folders</span> <span class="o">=</span> <span class="n">folders</span><span class="p">[</span><span class="n">folder_uuid</span><span class="p">]</span>
|
|
<span class="k">if</span> <span class="n">folders</span><span class="p">:</span>
|
|
<span class="c1"># still have elements left to recurse</span>
|
|
<span class="n">hierarchy</span> <span class="o">=</span> <span class="n">_recurse_folder_hierarchy</span><span class="p">(</span><span class="n">folders</span><span class="p">,</span> <span class="n">hierarchy</span><span class="o">=</span><span class="n">hierarchy</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">hierarchy</span>
|
|
|
|
<span class="c1"># no elements left to recurse</span>
|
|
<span class="k">return</span> <span class="n">hierarchy</span>
|
|
|
|
<span class="n">hierarchy</span> <span class="o">=</span> <span class="n">_recurse_folder_hierarchy</span><span class="p">(</span><span class="n">folders</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">hierarchy</span>
|
|
|
|
<span class="k">def</span> <span class="nf">_album_folder_hierarchy_folderinfo</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">album_uuid</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db_version</span> <span class="o"><=</span> <span class="n">_PHOTOS_4_VERSION</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_album_folder_hierarchy_folderinfo_4</span><span class="p">(</span><span class="n">album_uuid</span><span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_album_folder_hierarchy_folderinfo_5</span><span class="p">(</span><span class="n">album_uuid</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span> <span class="nf">_album_folder_hierarchy_folderinfo_4</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">album_uuid</span><span class="p">):</span>
|
|
<span class="sd">""" return hierarchical list of FolderInfo objects album_uuid is contained in</span>
|
|
<span class="sd"> ["Top level folder", "sub folder 1", "sub folder 2"]</span>
|
|
<span class="sd"> returns empty list of album is not in any folders """</span>
|
|
<span class="c1"># title = photosdb._dbalbum_details[album_uuid]["title"]</span>
|
|
<span class="n">folders</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbalbum_folders</span><span class="p">[</span><span class="n">album_uuid</span><span class="p">]</span>
|
|
<span class="c1"># logging.warning(f"uuid = {album_uuid}, folder = {folders}")</span>
|
|
|
|
<span class="k">def</span> <span class="nf">_recurse_folder_hierarchy</span><span class="p">(</span><span class="n">folders</span><span class="p">,</span> <span class="n">hierarchy</span><span class="o">=</span><span class="p">[]):</span>
|
|
<span class="sd">""" recursively walk the folders dict to build list of folder hierarchy """</span>
|
|
<span class="c1"># logging.warning(f"folders={folders},hierarchy = {hierarchy}")</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">folders</span><span class="p">:</span>
|
|
<span class="c1"># empty folder dict (album has no folder hierarchy)</span>
|
|
<span class="k">return</span> <span class="p">[]</span>
|
|
|
|
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">folders</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">1</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">"Expected only a single key in folders dict"</span><span class="p">)</span>
|
|
|
|
<span class="n">folder_uuid</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">folders</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span> <span class="c1"># first and only key of dict</span>
|
|
<span class="n">hierarchy</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">FolderInfo</span><span class="p">(</span><span class="n">db</span><span class="o">=</span><span class="bp">self</span><span class="p">,</span> <span class="n">uuid</span><span class="o">=</span><span class="n">folder_uuid</span><span class="p">))</span>
|
|
|
|
<span class="n">folders</span> <span class="o">=</span> <span class="n">folders</span><span class="p">[</span><span class="n">folder_uuid</span><span class="p">]</span>
|
|
<span class="k">if</span> <span class="n">folders</span><span class="p">:</span>
|
|
<span class="c1"># still have elements left to recurse</span>
|
|
<span class="n">hierarchy</span> <span class="o">=</span> <span class="n">_recurse_folder_hierarchy</span><span class="p">(</span><span class="n">folders</span><span class="p">,</span> <span class="n">hierarchy</span><span class="o">=</span><span class="n">hierarchy</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">hierarchy</span>
|
|
|
|
<span class="c1"># no elements left to recurse</span>
|
|
<span class="k">return</span> <span class="n">hierarchy</span>
|
|
|
|
<span class="n">hierarchy</span> <span class="o">=</span> <span class="n">_recurse_folder_hierarchy</span><span class="p">(</span><span class="n">folders</span><span class="p">)</span>
|
|
<span class="c1"># logging.warning(f"hierarchy = {hierarchy}")</span>
|
|
<span class="k">return</span> <span class="n">hierarchy</span>
|
|
|
|
<span class="k">def</span> <span class="nf">_album_folder_hierarchy_folderinfo_5</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">album_uuid</span><span class="p">):</span>
|
|
<span class="sd">""" return hierarchical list of FolderInfo objects album_uuid is contained in</span>
|
|
<span class="sd"> ["Top level folder", "sub folder 1", "sub folder 2"]</span>
|
|
<span class="sd"> returns empty list of album is not in any folders """</span>
|
|
<span class="c1"># title = photosdb._dbalbum_details[album_uuid]["title"]</span>
|
|
<span class="n">folders</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbalbum_folders</span><span class="p">[</span><span class="n">album_uuid</span><span class="p">]</span>
|
|
|
|
<span class="k">def</span> <span class="nf">_recurse_folder_hierarchy</span><span class="p">(</span><span class="n">folders</span><span class="p">,</span> <span class="n">hierarchy</span><span class="o">=</span><span class="p">[]):</span>
|
|
<span class="sd">""" recursively walk the folders dict to build list of folder hierarchy """</span>
|
|
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">folders</span><span class="p">:</span>
|
|
<span class="c1"># empty folder dict (album has no folder hierarchy)</span>
|
|
<span class="k">return</span> <span class="p">[]</span>
|
|
|
|
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">folders</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">1</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">"Expected only a single key in folders dict"</span><span class="p">)</span>
|
|
|
|
<span class="n">folder_uuid</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">folders</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span> <span class="c1"># first and only key of dict</span>
|
|
<span class="n">hierarchy</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">FolderInfo</span><span class="p">(</span><span class="n">db</span><span class="o">=</span><span class="bp">self</span><span class="p">,</span> <span class="n">uuid</span><span class="o">=</span><span class="n">folder_uuid</span><span class="p">))</span>
|
|
|
|
<span class="n">folders</span> <span class="o">=</span> <span class="n">folders</span><span class="p">[</span><span class="n">folder_uuid</span><span class="p">]</span>
|
|
<span class="k">if</span> <span class="n">folders</span><span class="p">:</span>
|
|
<span class="c1"># still have elements left to recurse</span>
|
|
<span class="n">hierarchy</span> <span class="o">=</span> <span class="n">_recurse_folder_hierarchy</span><span class="p">(</span><span class="n">folders</span><span class="p">,</span> <span class="n">hierarchy</span><span class="o">=</span><span class="n">hierarchy</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">hierarchy</span>
|
|
|
|
<span class="c1"># no elements left to recurse</span>
|
|
<span class="k">return</span> <span class="n">hierarchy</span>
|
|
|
|
<span class="n">hierarchy</span> <span class="o">=</span> <span class="n">_recurse_folder_hierarchy</span><span class="p">(</span><span class="n">folders</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">hierarchy</span>
|
|
|
|
<span class="k">def</span> <span class="nf">_get_album_uuids</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">shared</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">import_session</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
|
|
<span class="sd">""" Return list of album UUIDs found in photos database</span>
|
|
<span class="sd"> </span>
|
|
<span class="sd"> Filters out albums in the trash and any special album types</span>
|
|
<span class="sd"> </span>
|
|
<span class="sd"> Args:</span>
|
|
<span class="sd"> shared: boolean; if True, returns shared albums, else normal albums</span>
|
|
<span class="sd"> import_session: boolean, if True, returns import session albums, else normal or shared albums</span>
|
|
<span class="sd"> Note: flags (shared, import_session) are mutually exclusive</span>
|
|
<span class="sd"> </span>
|
|
<span class="sd"> Raises:</span>
|
|
<span class="sd"> ValueError: raised if mutually exclusive flags passed</span>
|
|
|
|
<span class="sd"> Returns: list of album UUIDs </span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="n">shared</span> <span class="ow">and</span> <span class="n">import_session</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
|
|
<span class="s2">"flags are mutually exclusive: pass zero or one of shared, import_session"</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db_version</span> <span class="o"><=</span> <span class="n">_PHOTOS_4_VERSION</span><span class="p">:</span>
|
|
<span class="n">version4</span> <span class="o">=</span> <span class="kc">True</span>
|
|
<span class="k">if</span> <span class="n">shared</span><span class="p">:</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span>
|
|
<span class="sa">f</span><span class="s2">"Shared albums not implemented for Photos library version </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">_db_version</span><span class="si">}</span><span class="s2">"</span>
|
|
<span class="p">)</span>
|
|
<span class="k">return</span> <span class="p">[]</span> <span class="c1"># not implemented for _PHOTOS_4_VERSION</span>
|
|
<span class="k">elif</span> <span class="n">import_session</span><span class="p">:</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span>
|
|
<span class="sa">f</span><span class="s2">"Import sessions not implemented for Photos library version </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">_db_version</span><span class="si">}</span><span class="s2">"</span>
|
|
<span class="p">)</span>
|
|
<span class="k">return</span> <span class="p">[]</span> <span class="c1"># not implemented for _PHOTOS_4_VERSION</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">album_kind</span> <span class="o">=</span> <span class="n">_PHOTOS_4_ALBUM_KIND</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">version4</span> <span class="o">=</span> <span class="kc">False</span>
|
|
<span class="k">if</span> <span class="n">shared</span><span class="p">:</span>
|
|
<span class="n">album_kind</span> <span class="o">=</span> <span class="n">_PHOTOS_5_SHARED_ALBUM_KIND</span>
|
|
<span class="k">elif</span> <span class="n">import_session</span><span class="p">:</span>
|
|
<span class="n">album_kind</span> <span class="o">=</span> <span class="n">_PHOTOS_5_IMPORT_SESSION_ALBUM_KIND</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">album_kind</span> <span class="o">=</span> <span class="n">_PHOTOS_5_ALBUM_KIND</span>
|
|
|
|
<span class="n">album_list</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="c1"># look through _dbalbum_details because _dbalbums_album won't have empty albums it</span>
|
|
<span class="k">for</span> <span class="n">album</span><span class="p">,</span> <span class="n">detail</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbalbum_details</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
|
|
<span class="k">if</span> <span class="p">(</span>
|
|
<span class="n">detail</span><span class="p">[</span><span class="s2">"kind"</span><span class="p">]</span> <span class="o">==</span> <span class="n">album_kind</span>
|
|
<span class="ow">and</span> <span class="ow">not</span> <span class="n">detail</span><span class="p">[</span><span class="s2">"intrash"</span><span class="p">]</span>
|
|
<span class="ow">and</span> <span class="p">(</span>
|
|
<span class="p">(</span><span class="n">shared</span> <span class="ow">and</span> <span class="n">detail</span><span class="p">[</span><span class="s2">"cloudownerhashedpersonid"</span><span class="p">]</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">)</span>
|
|
<span class="ow">or</span> <span class="p">(</span><span class="ow">not</span> <span class="n">shared</span> <span class="ow">and</span> <span class="n">detail</span><span class="p">[</span><span class="s2">"cloudownerhashedpersonid"</span><span class="p">]</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">)</span>
|
|
<span class="p">)</span>
|
|
<span class="ow">and</span> <span class="p">(</span>
|
|
<span class="ow">not</span> <span class="n">version4</span>
|
|
<span class="c1"># in Photos 4, special albums like "printAlbum" have kind _PHOTOS_4_ALBUM_KIND</span>
|
|
<span class="c1"># but should not be listed here; they can be distinguished by looking</span>
|
|
<span class="c1"># for folderUuid of _PHOTOS_4_ROOT_FOLDER as opposed to _PHOTOS_4_TOP_LEVEL_ALBUM</span>
|
|
<span class="ow">or</span> <span class="p">(</span><span class="n">version4</span> <span class="ow">and</span> <span class="n">detail</span><span class="p">[</span><span class="s2">"folderUuid"</span><span class="p">]</span> <span class="o">!=</span> <span class="n">_PHOTOS_4_ROOT_FOLDER</span><span class="p">)</span>
|
|
<span class="p">)</span>
|
|
<span class="p">):</span>
|
|
<span class="n">album_list</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">album</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">album_list</span>
|
|
|
|
<span class="k">def</span> <span class="nf">_get_albums</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">shared</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
|
|
<span class="sd">""" Return list of album titles found in photos database</span>
|
|
<span class="sd"> Albums may have duplicate titles -- these will be treated as a single album.</span>
|
|
<span class="sd"> </span>
|
|
<span class="sd"> Filters out albums in the trash and any special album types</span>
|
|
|
|
<span class="sd"> Args:</span>
|
|
<span class="sd"> shared: boolean; if True, returns shared albums, else normal albums</span>
|
|
<span class="sd"> </span>
|
|
<span class="sd"> Returns: list of album names</span>
|
|
<span class="sd"> """</span>
|
|
|
|
<span class="n">album_uuids</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_album_uuids</span><span class="p">(</span><span class="n">shared</span><span class="o">=</span><span class="n">shared</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="nb">list</span><span class="p">({</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbalbum_details</span><span class="p">[</span><span class="n">album</span><span class="p">][</span><span class="s2">"title"</span><span class="p">]</span> <span class="k">for</span> <span class="n">album</span> <span class="ow">in</span> <span class="n">album_uuids</span><span class="p">})</span>
|
|
|
|
<div class="viewcode-block" id="PhotosDB.photos"><a class="viewcode-back" href="../../../reference.html#osxphotos.PhotosDB.photos">[docs]</a> <span class="k">def</span> <span class="nf">photos</span><span class="p">(</span>
|
|
<span class="bp">self</span><span class="p">,</span>
|
|
<span class="n">keywords</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
|
|
<span class="n">uuid</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
|
|
<span class="n">persons</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
|
|
<span class="n">albums</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
|
|
<span class="n">images</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
|
|
<span class="n">movies</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
|
|
<span class="n">from_date</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
|
|
<span class="n">to_date</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
|
|
<span class="n">intrash</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
|
|
<span class="p">):</span>
|
|
<span class="sd">""" Return a list of PhotoInfo objects</span>
|
|
<span class="sd"> If called with no args, returns the entire database of photos</span>
|
|
<span class="sd"> If called with args, returns photos matching the args (e.g. keywords, persons, etc.)</span>
|
|
<span class="sd"> If more than one arg, returns photos matching all the criteria (e.g. keywords AND persons)</span>
|
|
<span class="sd"> If more than one keyword, uuid, persons, albums is passed, they are treated as "OR" criteria</span>
|
|
<span class="sd"> e.g. keywords=["wedding","vacation"] returns photos matching either keyword</span>
|
|
<span class="sd"> from_date and to_date may be either naive or timezone-aware datetime.datetime objects.</span>
|
|
<span class="sd"> If naive, timezone will be assumed to be local timezone.</span>
|
|
|
|
<span class="sd"> Args:</span>
|
|
<span class="sd"> keywords: list of keywords to search for</span>
|
|
<span class="sd"> uuid: list of UUIDs to search for</span>
|
|
<span class="sd"> persons: list of persons to search for</span>
|
|
<span class="sd"> albums: list of album names to search for</span>
|
|
<span class="sd"> images: if True, returns image files, if False, does not return images; default is True</span>
|
|
<span class="sd"> movies: if True, returns movie files, if False, does not return movies; default is True </span>
|
|
<span class="sd"> from_date: return photos with creation date >= from_date (datetime.datetime object, default None)</span>
|
|
<span class="sd"> to_date: return photos with creation date <= to_date (datetime.datetime object, default None)</span>
|
|
<span class="sd"> intrash: if True, returns only images in "Recently deleted items" folder, </span>
|
|
<span class="sd"> if False returns only photos that aren't deleted; default is False</span>
|
|
|
|
<span class="sd"> Returns:</span>
|
|
<span class="sd"> list of PhotoInfo objects</span>
|
|
<span class="sd"> """</span>
|
|
|
|
<span class="c1"># implementation is a bit kludgy but it works</span>
|
|
<span class="c1"># build a set of each search argument then compute the intersection of the sets</span>
|
|
<span class="c1"># use results to build a list of PhotoInfo objects</span>
|
|
|
|
<span class="n">photos_sets</span> <span class="o">=</span> <span class="p">[]</span> <span class="c1"># list of photo sets to perform intersection of</span>
|
|
<span class="k">if</span> <span class="n">intrash</span><span class="p">:</span>
|
|
<span class="n">photos_sets</span><span class="o">.</span><span class="n">append</span><span class="p">(</span>
|
|
<span class="p">{</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">p</span><span class="p">][</span><span class="s2">"intrash"</span><span class="p">]}</span>
|
|
<span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">photos_sets</span><span class="o">.</span><span class="n">append</span><span class="p">(</span>
|
|
<span class="p">{</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span> <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">p</span><span class="p">][</span><span class="s2">"intrash"</span><span class="p">]}</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">any</span><span class="p">([</span><span class="n">keywords</span><span class="p">,</span> <span class="n">uuid</span><span class="p">,</span> <span class="n">persons</span><span class="p">,</span> <span class="n">albums</span><span class="p">,</span> <span class="n">from_date</span><span class="p">,</span> <span class="n">to_date</span><span class="p">]):</span>
|
|
<span class="c1"># return all the photos, filtering for images and movies</span>
|
|
<span class="c1"># append keys of all photos as a single set to photos_sets</span>
|
|
<span class="n">photos_sets</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="nb">set</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="o">.</span><span class="n">keys</span><span class="p">()))</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">albums</span><span class="p">:</span>
|
|
<span class="n">album_set</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
|
|
<span class="k">for</span> <span class="n">album</span> <span class="ow">in</span> <span class="n">albums</span><span class="p">:</span>
|
|
<span class="c1"># glob together albums with same name</span>
|
|
<span class="k">if</span> <span class="n">album</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbalbum_titles</span><span class="p">:</span>
|
|
<span class="n">title_set</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
|
|
<span class="k">for</span> <span class="n">album_id</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbalbum_titles</span><span class="p">[</span><span class="n">album</span><span class="p">]:</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="c1"># _dbalbums_album value is list of tuples: [(uuid, sort order)]</span>
|
|
<span class="n">uuid_in_album</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="nb">zip</span><span class="p">(</span><span class="o">*</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbalbums_album</span><span class="p">[</span><span class="n">album_id</span><span class="p">])</span>
|
|
<span class="n">title_set</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">uuid_in_album</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
|
|
<span class="c1"># an empty album will be in _dbalbum_titles but not _dbalbums_album</span>
|
|
<span class="k">pass</span>
|
|
<span class="n">album_set</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">title_set</span><span class="p">)</span>
|
|
<span class="n">photos_sets</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">album_set</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="n">uuid</span><span class="p">:</span>
|
|
<span class="n">uuid_set</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
|
|
<span class="k">for</span> <span class="n">u</span> <span class="ow">in</span> <span class="n">uuid</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">u</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">:</span>
|
|
<span class="n">uuid_set</span><span class="o">.</span><span class="n">update</span><span class="p">([</span><span class="n">u</span><span class="p">])</span>
|
|
<span class="n">photos_sets</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">uuid_set</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="n">keywords</span><span class="p">:</span>
|
|
<span class="n">keyword_set</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
|
|
<span class="k">for</span> <span class="n">keyword</span> <span class="ow">in</span> <span class="n">keywords</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">keyword</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbkeywords_keyword</span><span class="p">:</span>
|
|
<span class="n">keyword_set</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbkeywords_keyword</span><span class="p">[</span><span class="n">keyword</span><span class="p">])</span>
|
|
<span class="n">photos_sets</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">keyword_set</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="n">persons</span><span class="p">:</span>
|
|
<span class="n">person_set</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
|
|
<span class="k">for</span> <span class="n">person</span> <span class="ow">in</span> <span class="n">persons</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">person</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbpersons_fullname</span><span class="p">:</span>
|
|
<span class="k">for</span> <span class="n">pk</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbpersons_fullname</span><span class="p">[</span><span class="n">person</span><span class="p">]:</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">person_set</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbfaces_pk</span><span class="p">[</span><span class="n">pk</span><span class="p">])</span>
|
|
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
|
|
<span class="c1"># some persons have zero photos so they won't be in _dbfaces_pk</span>
|
|
<span class="k">pass</span>
|
|
<span class="n">photos_sets</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">person_set</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="n">from_date</span> <span class="ow">or</span> <span class="n">to_date</span><span class="p">:</span> <span class="c1"># sourcery off</span>
|
|
<span class="n">dsel</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span>
|
|
<span class="k">if</span> <span class="n">from_date</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">datetime_has_tz</span><span class="p">(</span><span class="n">from_date</span><span class="p">):</span>
|
|
<span class="n">from_date</span> <span class="o">=</span> <span class="n">datetime_naive_to_local</span><span class="p">(</span><span class="n">from_date</span><span class="p">)</span>
|
|
<span class="n">dsel</span> <span class="o">=</span> <span class="p">{</span>
|
|
<span class="n">k</span><span class="p">:</span> <span class="n">v</span> <span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">dsel</span><span class="o">.</span><span class="n">items</span><span class="p">()</span> <span class="k">if</span> <span class="n">v</span><span class="p">[</span><span class="s2">"imageDate"</span><span class="p">]</span> <span class="o">>=</span> <span class="n">from_date</span>
|
|
<span class="p">}</span>
|
|
<span class="k">if</span> <span class="n">to_date</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">datetime_has_tz</span><span class="p">(</span><span class="n">to_date</span><span class="p">):</span>
|
|
<span class="n">to_date</span> <span class="o">=</span> <span class="n">datetime_naive_to_local</span><span class="p">(</span><span class="n">to_date</span><span class="p">)</span>
|
|
<span class="n">dsel</span> <span class="o">=</span> <span class="p">{</span><span class="n">k</span><span class="p">:</span> <span class="n">v</span> <span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">dsel</span><span class="o">.</span><span class="n">items</span><span class="p">()</span> <span class="k">if</span> <span class="n">v</span><span class="p">[</span><span class="s2">"imageDate"</span><span class="p">]</span> <span class="o"><=</span> <span class="n">to_date</span><span class="p">}</span>
|
|
<span class="n">photos_sets</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="nb">set</span><span class="p">(</span><span class="n">dsel</span><span class="o">.</span><span class="n">keys</span><span class="p">()))</span>
|
|
|
|
<span class="n">photoinfo</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="k">if</span> <span class="n">photos_sets</span><span class="p">:</span> <span class="c1"># found some photos</span>
|
|
<span class="c1"># get the intersection of each argument/search criteria</span>
|
|
<span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="nb">set</span><span class="o">.</span><span class="n">intersection</span><span class="p">(</span><span class="o">*</span><span class="n">photos_sets</span><span class="p">):</span>
|
|
<span class="c1"># filter for non-selected burst photos</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">p</span><span class="p">][</span><span class="s2">"burst"</span><span class="p">]</span> <span class="ow">and</span> <span class="ow">not</span> <span class="p">(</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">p</span><span class="p">][</span><span class="s2">"burstPickType"</span><span class="p">]</span> <span class="o">&</span> <span class="n">BURST_SELECTED</span>
|
|
<span class="ow">or</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">p</span><span class="p">][</span><span class="s2">"burstPickType"</span><span class="p">]</span> <span class="o">&</span> <span class="n">BURST_KEY</span>
|
|
<span class="p">):</span>
|
|
<span class="c1"># not a key/selected burst photo, don't include in returned results</span>
|
|
<span class="k">continue</span>
|
|
|
|
<span class="c1"># filter for images and/or movies</span>
|
|
<span class="k">if</span> <span class="p">(</span><span class="n">images</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">p</span><span class="p">][</span><span class="s2">"type"</span><span class="p">]</span> <span class="o">==</span> <span class="n">_PHOTO_TYPE</span><span class="p">)</span> <span class="ow">or</span> <span class="p">(</span>
|
|
<span class="n">movies</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">p</span><span class="p">][</span><span class="s2">"type"</span><span class="p">]</span> <span class="o">==</span> <span class="n">_MOVIE_TYPE</span>
|
|
<span class="p">):</span>
|
|
<span class="n">info</span> <span class="o">=</span> <span class="n">PhotoInfo</span><span class="p">(</span><span class="n">db</span><span class="o">=</span><span class="bp">self</span><span class="p">,</span> <span class="n">uuid</span><span class="o">=</span><span class="n">p</span><span class="p">,</span> <span class="n">info</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">p</span><span class="p">])</span>
|
|
<span class="n">photoinfo</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">info</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">_debug</span><span class="p">:</span>
|
|
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="sa">f</span><span class="s2">"photoinfo: </span><span class="si">{</span><span class="n">pformat</span><span class="p">(</span><span class="n">photoinfo</span><span class="p">)</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
|
|
|
|
<span class="k">return</span> <span class="n">photoinfo</span></div>
|
|
|
|
<div class="viewcode-block" id="PhotosDB.get_photo"><a class="viewcode-back" href="../../../reference.html#osxphotos.PhotosDB.get_photo">[docs]</a> <span class="k">def</span> <span class="nf">get_photo</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">uuid</span><span class="p">):</span>
|
|
<span class="sd">""" Returns a single photo matching uuid</span>
|
|
|
|
<span class="sd"> Arguments:</span>
|
|
<span class="sd"> uuid: the UUID of photo to get</span>
|
|
|
|
<span class="sd"> Returns:</span>
|
|
<span class="sd"> PhotoInfo instance for photo with UUID matching uuid or None if no match</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">PhotoInfo</span><span class="p">(</span><span class="n">db</span><span class="o">=</span><span class="bp">self</span><span class="p">,</span> <span class="n">uuid</span><span class="o">=</span><span class="n">uuid</span><span class="p">,</span> <span class="n">info</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">])</span>
|
|
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="kc">None</span></div>
|
|
|
|
<span class="c1"># TODO: add to docs and test</span>
|
|
<div class="viewcode-block" id="PhotosDB.photos_by_uuid"><a class="viewcode-back" href="../../../reference.html#osxphotos.PhotosDB.photos_by_uuid">[docs]</a> <span class="k">def</span> <span class="nf">photos_by_uuid</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">uuids</span><span class="p">):</span>
|
|
<span class="sd">""" Returns a list of photos with UUID in uuids.</span>
|
|
<span class="sd"> Does not generate error if invalid or missing UUID passed.</span>
|
|
<span class="sd"> This is faster than using PhotosDB.photos if you have list of UUIDs.</span>
|
|
<span class="sd"> Returns photos regardless of intrash state.</span>
|
|
|
|
<span class="sd"> Arguments:</span>
|
|
<span class="sd"> uuid: list of UUIDs of photos to get</span>
|
|
|
|
<span class="sd"> Returns:</span>
|
|
<span class="sd"> list of PhotoInfo instance for photo with UUID matching uuid or [] if no match</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="k">for</span> <span class="n">uuid</span> <span class="ow">in</span> <span class="n">uuids</span><span class="p">:</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">photos</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">PhotoInfo</span><span class="p">(</span><span class="n">db</span><span class="o">=</span><span class="bp">self</span><span class="p">,</span> <span class="n">uuid</span><span class="o">=</span><span class="n">uuid</span><span class="p">,</span> <span class="n">info</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">]))</span>
|
|
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
|
|
<span class="c1"># ignore missing/invlaid UUID</span>
|
|
<span class="k">pass</span>
|
|
<span class="k">return</span> <span class="n">photos</span></div>
|
|
|
|
<div class="viewcode-block" id="PhotosDB.query"><a class="viewcode-back" href="../../../reference.html#osxphotos.PhotosDB.query">[docs]</a> <span class="k">def</span> <span class="nf">query</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">options</span><span class="p">:</span> <span class="n">QueryOptions</span><span class="p">)</span> <span class="o">-></span> <span class="n">List</span><span class="p">[</span><span class="n">PhotoInfo</span><span class="p">]:</span>
|
|
<span class="sd">"""Run a query against PhotosDB to extract the photos based on user supplied options</span>
|
|
|
|
<span class="sd"> Args:</span>
|
|
<span class="sd"> options: a QueryOptions instance</span>
|
|
<span class="sd"> """</span>
|
|
|
|
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">deleted</span> <span class="ow">or</span> <span class="n">options</span><span class="o">.</span><span class="n">deleted_only</span><span class="p">:</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">photos</span><span class="p">(</span>
|
|
<span class="n">uuid</span><span class="o">=</span><span class="n">options</span><span class="o">.</span><span class="n">uuid</span><span class="p">,</span>
|
|
<span class="n">images</span><span class="o">=</span><span class="n">options</span><span class="o">.</span><span class="n">photos</span><span class="p">,</span>
|
|
<span class="n">movies</span><span class="o">=</span><span class="n">options</span><span class="o">.</span><span class="n">movies</span><span class="p">,</span>
|
|
<span class="n">from_date</span><span class="o">=</span><span class="n">options</span><span class="o">.</span><span class="n">from_date</span><span class="p">,</span>
|
|
<span class="n">to_date</span><span class="o">=</span><span class="n">options</span><span class="o">.</span><span class="n">to_date</span><span class="p">,</span>
|
|
<span class="n">intrash</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
|
|
<span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="p">[]</span>
|
|
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">options</span><span class="o">.</span><span class="n">deleted_only</span><span class="p">:</span>
|
|
<span class="n">photos</span> <span class="o">+=</span> <span class="bp">self</span><span class="o">.</span><span class="n">photos</span><span class="p">(</span>
|
|
<span class="n">uuid</span><span class="o">=</span><span class="n">options</span><span class="o">.</span><span class="n">uuid</span><span class="p">,</span>
|
|
<span class="n">images</span><span class="o">=</span><span class="n">options</span><span class="o">.</span><span class="n">photos</span><span class="p">,</span>
|
|
<span class="n">movies</span><span class="o">=</span><span class="n">options</span><span class="o">.</span><span class="n">movies</span><span class="p">,</span>
|
|
<span class="n">from_date</span><span class="o">=</span><span class="n">options</span><span class="o">.</span><span class="n">from_date</span><span class="p">,</span>
|
|
<span class="n">to_date</span><span class="o">=</span><span class="n">options</span><span class="o">.</span><span class="n">to_date</span><span class="p">,</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="n">person</span> <span class="o">=</span> <span class="n">normalize_unicode</span><span class="p">(</span><span class="n">options</span><span class="o">.</span><span class="n">person</span><span class="p">)</span>
|
|
<span class="n">keyword</span> <span class="o">=</span> <span class="n">normalize_unicode</span><span class="p">(</span><span class="n">options</span><span class="o">.</span><span class="n">keyword</span><span class="p">)</span>
|
|
<span class="n">album</span> <span class="o">=</span> <span class="n">normalize_unicode</span><span class="p">(</span><span class="n">options</span><span class="o">.</span><span class="n">album</span><span class="p">)</span>
|
|
<span class="n">folder</span> <span class="o">=</span> <span class="n">normalize_unicode</span><span class="p">(</span><span class="n">options</span><span class="o">.</span><span class="n">folder</span><span class="p">)</span>
|
|
<span class="n">title</span> <span class="o">=</span> <span class="n">normalize_unicode</span><span class="p">(</span><span class="n">options</span><span class="o">.</span><span class="n">title</span><span class="p">)</span>
|
|
<span class="n">description</span> <span class="o">=</span> <span class="n">normalize_unicode</span><span class="p">(</span><span class="n">options</span><span class="o">.</span><span class="n">description</span><span class="p">)</span>
|
|
<span class="n">place</span> <span class="o">=</span> <span class="n">normalize_unicode</span><span class="p">(</span><span class="n">options</span><span class="o">.</span><span class="n">place</span><span class="p">)</span>
|
|
<span class="n">label</span> <span class="o">=</span> <span class="n">normalize_unicode</span><span class="p">(</span><span class="n">options</span><span class="o">.</span><span class="n">label</span><span class="p">)</span>
|
|
<span class="n">name</span> <span class="o">=</span> <span class="n">normalize_unicode</span><span class="p">(</span><span class="n">options</span><span class="o">.</span><span class="n">name</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="n">album</span><span class="p">:</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="n">_get_photos_by_attribute</span><span class="p">(</span>
|
|
<span class="n">photos</span><span class="p">,</span> <span class="s2">"albums"</span><span class="p">,</span> <span class="n">album</span><span class="p">,</span> <span class="n">options</span><span class="o">.</span><span class="n">ignore_case</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="n">keyword</span><span class="p">:</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="n">_get_photos_by_attribute</span><span class="p">(</span>
|
|
<span class="n">photos</span><span class="p">,</span> <span class="s2">"keywords"</span><span class="p">,</span> <span class="n">keyword</span><span class="p">,</span> <span class="n">options</span><span class="o">.</span><span class="n">ignore_case</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="n">person</span><span class="p">:</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="n">_get_photos_by_attribute</span><span class="p">(</span>
|
|
<span class="n">photos</span><span class="p">,</span> <span class="s2">"persons"</span><span class="p">,</span> <span class="n">person</span><span class="p">,</span> <span class="n">options</span><span class="o">.</span><span class="n">ignore_case</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="n">label</span><span class="p">:</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="n">_get_photos_by_attribute</span><span class="p">(</span>
|
|
<span class="n">photos</span><span class="p">,</span> <span class="s2">"labels"</span><span class="p">,</span> <span class="n">label</span><span class="p">,</span> <span class="n">options</span><span class="o">.</span><span class="n">ignore_case</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="n">folder</span><span class="p">:</span>
|
|
<span class="c1"># search for photos in an album in folder</span>
|
|
<span class="c1"># finds photos that have albums whose top level folder matches folder</span>
|
|
<span class="n">photo_list</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">folder</span><span class="p">:</span>
|
|
<span class="n">photo_list</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span>
|
|
<span class="p">[</span>
|
|
<span class="n">p</span>
|
|
<span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span>
|
|
<span class="k">if</span> <span class="n">p</span><span class="o">.</span><span class="n">album_info</span>
|
|
<span class="ow">and</span> <span class="n">f</span>
|
|
<span class="ow">in</span> <span class="p">[</span><span class="n">a</span><span class="o">.</span><span class="n">folder_names</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">for</span> <span class="n">a</span> <span class="ow">in</span> <span class="n">p</span><span class="o">.</span><span class="n">album_info</span> <span class="k">if</span> <span class="n">a</span><span class="o">.</span><span class="n">folder_names</span><span class="p">]</span>
|
|
<span class="p">]</span>
|
|
<span class="p">)</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="n">photo_list</span>
|
|
|
|
<span class="k">if</span> <span class="n">title</span><span class="p">:</span>
|
|
<span class="c1"># search title field for text</span>
|
|
<span class="c1"># if more than one, find photos with all title values in title</span>
|
|
<span class="n">photo_list</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">ignore_case</span><span class="p">:</span>
|
|
<span class="c1"># case-insensitive</span>
|
|
<span class="k">for</span> <span class="n">t</span> <span class="ow">in</span> <span class="n">title</span><span class="p">:</span>
|
|
<span class="n">t</span> <span class="o">=</span> <span class="n">t</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
|
|
<span class="n">photo_list</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span>
|
|
<span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="n">p</span><span class="o">.</span><span class="n">title</span> <span class="ow">and</span> <span class="n">t</span> <span class="ow">in</span> <span class="n">p</span><span class="o">.</span><span class="n">title</span><span class="o">.</span><span class="n">lower</span><span class="p">()]</span>
|
|
<span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">for</span> <span class="n">t</span> <span class="ow">in</span> <span class="n">title</span><span class="p">:</span>
|
|
<span class="n">photo_list</span><span class="o">.</span><span class="n">extend</span><span class="p">([</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="n">p</span><span class="o">.</span><span class="n">title</span> <span class="ow">and</span> <span class="n">t</span> <span class="ow">in</span> <span class="n">p</span><span class="o">.</span><span class="n">title</span><span class="p">])</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="n">photo_list</span>
|
|
<span class="k">elif</span> <span class="n">options</span><span class="o">.</span><span class="n">no_title</span><span class="p">:</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">p</span><span class="o">.</span><span class="n">title</span><span class="p">]</span>
|
|
|
|
<span class="k">if</span> <span class="n">description</span><span class="p">:</span>
|
|
<span class="c1"># search description field for text</span>
|
|
<span class="c1"># if more than one, find photos with all description values in description</span>
|
|
<span class="n">photo_list</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">ignore_case</span><span class="p">:</span>
|
|
<span class="c1"># case-insensitive</span>
|
|
<span class="k">for</span> <span class="n">d</span> <span class="ow">in</span> <span class="n">description</span><span class="p">:</span>
|
|
<span class="n">d</span> <span class="o">=</span> <span class="n">d</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
|
|
<span class="n">photo_list</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span>
|
|
<span class="p">[</span>
|
|
<span class="n">p</span>
|
|
<span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span>
|
|
<span class="k">if</span> <span class="n">p</span><span class="o">.</span><span class="n">description</span> <span class="ow">and</span> <span class="n">d</span> <span class="ow">in</span> <span class="n">p</span><span class="o">.</span><span class="n">description</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
|
|
<span class="p">]</span>
|
|
<span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">for</span> <span class="n">d</span> <span class="ow">in</span> <span class="n">description</span><span class="p">:</span>
|
|
<span class="n">photo_list</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span>
|
|
<span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="n">p</span><span class="o">.</span><span class="n">description</span> <span class="ow">and</span> <span class="n">d</span> <span class="ow">in</span> <span class="n">p</span><span class="o">.</span><span class="n">description</span><span class="p">]</span>
|
|
<span class="p">)</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="n">photo_list</span>
|
|
<span class="k">elif</span> <span class="n">options</span><span class="o">.</span><span class="n">no_description</span><span class="p">:</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">p</span><span class="o">.</span><span class="n">description</span><span class="p">]</span>
|
|
|
|
<span class="k">if</span> <span class="n">place</span><span class="p">:</span>
|
|
<span class="c1"># search place.names for text matching place</span>
|
|
<span class="c1"># if more than one place, find photos with all place values in description</span>
|
|
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">ignore_case</span><span class="p">:</span>
|
|
<span class="c1"># case-insensitive</span>
|
|
<span class="k">for</span> <span class="n">place_name</span> <span class="ow">in</span> <span class="n">place</span><span class="p">:</span>
|
|
<span class="n">place_name</span> <span class="o">=</span> <span class="n">place_name</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span>
|
|
<span class="n">p</span>
|
|
<span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span>
|
|
<span class="k">if</span> <span class="n">p</span><span class="o">.</span><span class="n">place</span>
|
|
<span class="ow">and</span> <span class="nb">any</span><span class="p">(</span>
|
|
<span class="n">pname</span>
|
|
<span class="k">for</span> <span class="n">pname</span> <span class="ow">in</span> <span class="n">p</span><span class="o">.</span><span class="n">place</span><span class="o">.</span><span class="n">names</span>
|
|
<span class="k">if</span> <span class="nb">any</span><span class="p">(</span>
|
|
<span class="n">pvalue</span>
|
|
<span class="k">for</span> <span class="n">pvalue</span> <span class="ow">in</span> <span class="n">pname</span>
|
|
<span class="k">if</span> <span class="n">place_name</span> <span class="ow">in</span> <span class="n">pvalue</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
|
|
<span class="p">)</span>
|
|
<span class="p">)</span>
|
|
<span class="p">]</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">for</span> <span class="n">place_name</span> <span class="ow">in</span> <span class="n">place</span><span class="p">:</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span>
|
|
<span class="n">p</span>
|
|
<span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span>
|
|
<span class="k">if</span> <span class="n">p</span><span class="o">.</span><span class="n">place</span>
|
|
<span class="ow">and</span> <span class="nb">any</span><span class="p">(</span>
|
|
<span class="n">pname</span>
|
|
<span class="k">for</span> <span class="n">pname</span> <span class="ow">in</span> <span class="n">p</span><span class="o">.</span><span class="n">place</span><span class="o">.</span><span class="n">names</span>
|
|
<span class="k">if</span> <span class="nb">any</span><span class="p">(</span><span class="n">pvalue</span> <span class="k">for</span> <span class="n">pvalue</span> <span class="ow">in</span> <span class="n">pname</span> <span class="k">if</span> <span class="n">place_name</span> <span class="ow">in</span> <span class="n">pvalue</span><span class="p">)</span>
|
|
<span class="p">)</span>
|
|
<span class="p">]</span>
|
|
<span class="k">elif</span> <span class="n">options</span><span class="o">.</span><span class="n">no_place</span><span class="p">:</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">p</span><span class="o">.</span><span class="n">place</span><span class="p">]</span>
|
|
|
|
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">edited</span><span class="p">:</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="n">p</span><span class="o">.</span><span class="n">hasadjustments</span><span class="p">]</span>
|
|
|
|
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">external_edit</span><span class="p">:</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="n">p</span><span class="o">.</span><span class="n">external_edit</span><span class="p">]</span>
|
|
|
|
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">favorite</span><span class="p">:</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="n">p</span><span class="o">.</span><span class="n">favorite</span><span class="p">]</span>
|
|
<span class="k">elif</span> <span class="n">options</span><span class="o">.</span><span class="n">not_favorite</span><span class="p">:</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">p</span><span class="o">.</span><span class="n">favorite</span><span class="p">]</span>
|
|
|
|
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">hidden</span><span class="p">:</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="n">p</span><span class="o">.</span><span class="n">hidden</span><span class="p">]</span>
|
|
<span class="k">elif</span> <span class="n">options</span><span class="o">.</span><span class="n">not_hidden</span><span class="p">:</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">p</span><span class="o">.</span><span class="n">hidden</span><span class="p">]</span>
|
|
|
|
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">missing</span><span class="p">:</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">p</span><span class="o">.</span><span class="n">path</span><span class="p">]</span>
|
|
<span class="k">elif</span> <span class="n">options</span><span class="o">.</span><span class="n">not_missing</span><span class="p">:</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="n">p</span><span class="o">.</span><span class="n">path</span><span class="p">]</span>
|
|
|
|
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">shared</span><span class="p">:</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="n">p</span><span class="o">.</span><span class="n">shared</span><span class="p">]</span>
|
|
<span class="k">elif</span> <span class="n">options</span><span class="o">.</span><span class="n">not_shared</span><span class="p">:</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">p</span><span class="o">.</span><span class="n">shared</span><span class="p">]</span>
|
|
|
|
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">shared</span><span class="p">:</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="n">p</span><span class="o">.</span><span class="n">shared</span><span class="p">]</span>
|
|
<span class="k">elif</span> <span class="n">options</span><span class="o">.</span><span class="n">not_shared</span><span class="p">:</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">p</span><span class="o">.</span><span class="n">shared</span><span class="p">]</span>
|
|
|
|
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">uti</span><span class="p">:</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">uti</span> <span class="ow">in</span> <span class="n">p</span><span class="o">.</span><span class="n">uti_original</span><span class="p">]</span>
|
|
|
|
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">burst</span><span class="p">:</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="n">p</span><span class="o">.</span><span class="n">burst</span><span class="p">]</span>
|
|
<span class="k">elif</span> <span class="n">options</span><span class="o">.</span><span class="n">not_burst</span><span class="p">:</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">p</span><span class="o">.</span><span class="n">burst</span><span class="p">]</span>
|
|
|
|
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">live</span><span class="p">:</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="n">p</span><span class="o">.</span><span class="n">live_photo</span><span class="p">]</span>
|
|
<span class="k">elif</span> <span class="n">options</span><span class="o">.</span><span class="n">not_live</span><span class="p">:</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">p</span><span class="o">.</span><span class="n">live_photo</span><span class="p">]</span>
|
|
|
|
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">portrait</span><span class="p">:</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="n">p</span><span class="o">.</span><span class="n">portrait</span><span class="p">]</span>
|
|
<span class="k">elif</span> <span class="n">options</span><span class="o">.</span><span class="n">not_portrait</span><span class="p">:</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">p</span><span class="o">.</span><span class="n">portrait</span><span class="p">]</span>
|
|
|
|
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">screenshot</span><span class="p">:</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="n">p</span><span class="o">.</span><span class="n">screenshot</span><span class="p">]</span>
|
|
<span class="k">elif</span> <span class="n">options</span><span class="o">.</span><span class="n">not_screenshot</span><span class="p">:</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">p</span><span class="o">.</span><span class="n">screenshot</span><span class="p">]</span>
|
|
|
|
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">slow_mo</span><span class="p">:</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="n">p</span><span class="o">.</span><span class="n">slow_mo</span><span class="p">]</span>
|
|
<span class="k">elif</span> <span class="n">options</span><span class="o">.</span><span class="n">not_slow_mo</span><span class="p">:</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">p</span><span class="o">.</span><span class="n">slow_mo</span><span class="p">]</span>
|
|
|
|
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">time_lapse</span><span class="p">:</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="n">p</span><span class="o">.</span><span class="n">time_lapse</span><span class="p">]</span>
|
|
<span class="k">elif</span> <span class="n">options</span><span class="o">.</span><span class="n">not_time_lapse</span><span class="p">:</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">p</span><span class="o">.</span><span class="n">time_lapse</span><span class="p">]</span>
|
|
|
|
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">hdr</span><span class="p">:</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="n">p</span><span class="o">.</span><span class="n">hdr</span><span class="p">]</span>
|
|
<span class="k">elif</span> <span class="n">options</span><span class="o">.</span><span class="n">not_hdr</span><span class="p">:</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">p</span><span class="o">.</span><span class="n">hdr</span><span class="p">]</span>
|
|
|
|
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">selfie</span><span class="p">:</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="n">p</span><span class="o">.</span><span class="n">selfie</span><span class="p">]</span>
|
|
<span class="k">elif</span> <span class="n">options</span><span class="o">.</span><span class="n">not_selfie</span><span class="p">:</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">p</span><span class="o">.</span><span class="n">selfie</span><span class="p">]</span>
|
|
|
|
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">panorama</span><span class="p">:</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="n">p</span><span class="o">.</span><span class="n">panorama</span><span class="p">]</span>
|
|
<span class="k">elif</span> <span class="n">options</span><span class="o">.</span><span class="n">not_panorama</span><span class="p">:</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">p</span><span class="o">.</span><span class="n">panorama</span><span class="p">]</span>
|
|
|
|
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">cloudasset</span><span class="p">:</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="n">p</span><span class="o">.</span><span class="n">iscloudasset</span><span class="p">]</span>
|
|
<span class="k">elif</span> <span class="n">options</span><span class="o">.</span><span class="n">not_cloudasset</span><span class="p">:</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">p</span><span class="o">.</span><span class="n">iscloudasset</span><span class="p">]</span>
|
|
|
|
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">incloud</span><span class="p">:</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="n">p</span><span class="o">.</span><span class="n">incloud</span><span class="p">]</span>
|
|
<span class="k">elif</span> <span class="n">options</span><span class="o">.</span><span class="n">not_incloud</span><span class="p">:</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">p</span><span class="o">.</span><span class="n">incloud</span><span class="p">]</span>
|
|
|
|
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">has_raw</span><span class="p">:</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="n">p</span><span class="o">.</span><span class="n">has_raw</span><span class="p">]</span>
|
|
|
|
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">has_comment</span><span class="p">:</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="n">p</span><span class="o">.</span><span class="n">comments</span><span class="p">]</span>
|
|
<span class="k">elif</span> <span class="n">options</span><span class="o">.</span><span class="n">no_comment</span><span class="p">:</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">p</span><span class="o">.</span><span class="n">comments</span><span class="p">]</span>
|
|
|
|
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">has_likes</span><span class="p">:</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="n">p</span><span class="o">.</span><span class="n">likes</span><span class="p">]</span>
|
|
<span class="k">elif</span> <span class="n">options</span><span class="o">.</span><span class="n">no_likes</span><span class="p">:</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">p</span><span class="o">.</span><span class="n">likes</span><span class="p">]</span>
|
|
|
|
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">is_reference</span><span class="p">:</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="n">p</span><span class="o">.</span><span class="n">isreference</span><span class="p">]</span>
|
|
|
|
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">in_album</span><span class="p">:</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="n">p</span><span class="o">.</span><span class="n">albums</span><span class="p">]</span>
|
|
<span class="k">elif</span> <span class="n">options</span><span class="o">.</span><span class="n">not_in_album</span><span class="p">:</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">p</span><span class="o">.</span><span class="n">albums</span><span class="p">]</span>
|
|
|
|
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">from_time</span><span class="p">:</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="n">p</span><span class="o">.</span><span class="n">date</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o">>=</span> <span class="n">options</span><span class="o">.</span><span class="n">from_time</span><span class="p">]</span>
|
|
|
|
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">to_time</span><span class="p">:</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="n">p</span><span class="o">.</span><span class="n">date</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o"><=</span> <span class="n">options</span><span class="o">.</span><span class="n">to_time</span><span class="p">]</span>
|
|
|
|
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">burst_photos</span><span class="p">:</span>
|
|
<span class="c1"># add the burst_photos to the export set</span>
|
|
<span class="n">photos_burst</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="n">p</span><span class="o">.</span><span class="n">burst</span><span class="p">]</span>
|
|
<span class="k">for</span> <span class="n">burst</span> <span class="ow">in</span> <span class="n">photos_burst</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">missing_bursts</span><span class="p">:</span>
|
|
<span class="c1"># include burst photos that are missing</span>
|
|
<span class="n">photos</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">burst</span><span class="o">.</span><span class="n">burst_photos</span><span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="c1"># don't include missing burst images (these can't be downloaded with AppleScript)</span>
|
|
<span class="n">photos</span><span class="o">.</span><span class="n">extend</span><span class="p">([</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">burst</span><span class="o">.</span><span class="n">burst_photos</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">p</span><span class="o">.</span><span class="n">ismissing</span><span class="p">])</span>
|
|
|
|
<span class="c1"># remove duplicates as each burst photo in the set that's selected would</span>
|
|
<span class="c1"># result in the entire set being added above</span>
|
|
<span class="c1"># can't use set() because PhotoInfo not hashable</span>
|
|
<span class="n">seen_uuids</span> <span class="o">=</span> <span class="p">{}</span>
|
|
<span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">p</span><span class="o">.</span><span class="n">uuid</span> <span class="ow">in</span> <span class="n">seen_uuids</span><span class="p">:</span>
|
|
<span class="k">continue</span>
|
|
<span class="n">seen_uuids</span><span class="p">[</span><span class="n">p</span><span class="o">.</span><span class="n">uuid</span><span class="p">]</span> <span class="o">=</span> <span class="n">p</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">seen_uuids</span><span class="o">.</span><span class="n">values</span><span class="p">())</span>
|
|
|
|
<span class="k">if</span> <span class="n">name</span><span class="p">:</span>
|
|
<span class="c1"># search filename fields for text</span>
|
|
<span class="c1"># if more than one, find photos with all title values in filename</span>
|
|
<span class="n">photo_list</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">ignore_case</span><span class="p">:</span>
|
|
<span class="c1"># case-insensitive</span>
|
|
<span class="k">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="n">name</span><span class="p">:</span>
|
|
<span class="n">n</span> <span class="o">=</span> <span class="n">n</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
|
|
<span class="n">photo_list</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span>
|
|
<span class="p">[</span>
|
|
<span class="n">p</span>
|
|
<span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span>
|
|
<span class="k">if</span> <span class="n">n</span> <span class="ow">in</span> <span class="n">p</span><span class="o">.</span><span class="n">filename</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
|
|
<span class="ow">or</span> <span class="n">n</span> <span class="ow">in</span> <span class="n">p</span><span class="o">.</span><span class="n">original_filename</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
|
|
<span class="p">]</span>
|
|
<span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="n">name</span><span class="p">:</span>
|
|
<span class="n">photo_list</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span>
|
|
<span class="p">[</span>
|
|
<span class="n">p</span>
|
|
<span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span>
|
|
<span class="k">if</span> <span class="n">n</span> <span class="ow">in</span> <span class="n">p</span><span class="o">.</span><span class="n">filename</span> <span class="ow">or</span> <span class="n">n</span> <span class="ow">in</span> <span class="n">p</span><span class="o">.</span><span class="n">original_filename</span>
|
|
<span class="p">]</span>
|
|
<span class="p">)</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="n">photo_list</span>
|
|
|
|
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">min_size</span><span class="p">:</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span>
|
|
<span class="n">p</span>
|
|
<span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span>
|
|
<span class="k">if</span> <span class="n">bitmath</span><span class="o">.</span><span class="n">Byte</span><span class="p">(</span><span class="n">p</span><span class="o">.</span><span class="n">original_filesize</span><span class="p">)</span> <span class="o">>=</span> <span class="n">options</span><span class="o">.</span><span class="n">min_size</span>
|
|
<span class="p">]</span>
|
|
|
|
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">max_size</span><span class="p">:</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span>
|
|
<span class="n">p</span>
|
|
<span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span>
|
|
<span class="k">if</span> <span class="n">bitmath</span><span class="o">.</span><span class="n">Byte</span><span class="p">(</span><span class="n">p</span><span class="o">.</span><span class="n">original_filesize</span><span class="p">)</span> <span class="o"><=</span> <span class="n">options</span><span class="o">.</span><span class="n">max_size</span>
|
|
<span class="p">]</span>
|
|
|
|
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">regex</span><span class="p">:</span>
|
|
<span class="n">flags</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">IGNORECASE</span> <span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">ignore_case</span> <span class="k">else</span> <span class="mi">0</span>
|
|
<span class="k">for</span> <span class="n">regex</span><span class="p">,</span> <span class="n">template</span> <span class="ow">in</span> <span class="n">options</span><span class="o">.</span><span class="n">regex</span><span class="p">:</span>
|
|
<span class="n">regex</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="n">regex</span><span class="p">,</span> <span class="n">flags</span><span class="p">)</span>
|
|
<span class="n">photo_list</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span><span class="p">:</span>
|
|
<span class="n">rendered</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="n">p</span><span class="o">.</span><span class="n">render_template</span><span class="p">(</span><span class="n">template</span><span class="p">,</span> <span class="n">none_str</span><span class="o">=</span><span class="s2">""</span><span class="p">)</span>
|
|
<span class="k">for</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">rendered</span><span class="p">:</span>
|
|
<span class="k">if</span> <span class="n">regex</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="n">value</span><span class="p">):</span>
|
|
<span class="n">photo_list</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">p</span><span class="p">)</span>
|
|
<span class="k">break</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="n">photo_list</span>
|
|
|
|
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">query_eval</span><span class="p">:</span>
|
|
<span class="k">for</span> <span class="n">q</span> <span class="ow">in</span> <span class="n">options</span><span class="o">.</span><span class="n">query_eval</span><span class="p">:</span>
|
|
<span class="n">query_string</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">"[photo for photo in photos if </span><span class="si">{</span><span class="n">q</span><span class="si">}</span><span class="s2">]"</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="nb">eval</span><span class="p">(</span><span class="n">query_string</span><span class="p">)</span>
|
|
<span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Invalid query_eval CRITERIA: </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
|
|
|
|
<span class="k">return</span> <span class="n">photos</span></div>
|
|
|
|
<span class="k">def</span> <span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="sa">f</span><span class="s2">"osxphotos.</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__name__</span><span class="si">}</span><span class="s2">(dbfile='</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">db_path</span><span class="si">}</span><span class="s2">')"</span>
|
|
|
|
<span class="c1"># compare two PhotosDB objects for equality</span>
|
|
<span class="k">def</span> <span class="fm">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="vm">__dict__</span> <span class="o">==</span> <span class="n">other</span><span class="o">.</span><span class="vm">__dict__</span>
|
|
|
|
<span class="k">return</span> <span class="kc">False</span>
|
|
|
|
<span class="k">def</span> <span class="fm">__len__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">""" Returns number of photos in the database</span>
|
|
<span class="sd"> Includes recently deleted photos and non-selected burst images</span>
|
|
<span class="sd"> """</span>
|
|
<span class="k">return</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">)</span></div>
|
|
|
|
|
|
<span class="k">def</span> <span class="nf">_get_photos_by_attribute</span><span class="p">(</span><span class="n">photos</span><span class="p">,</span> <span class="n">attribute</span><span class="p">,</span> <span class="n">values</span><span class="p">,</span> <span class="n">ignore_case</span><span class="p">):</span>
|
|
<span class="sd">"""Search for photos based on values being in PhotoInfo.attribute</span>
|
|
|
|
<span class="sd"> Args:</span>
|
|
<span class="sd"> photos: a list of PhotoInfo objects</span>
|
|
<span class="sd"> attribute: str, name of PhotoInfo attribute to search (e.g. keywords, persons, etc)</span>
|
|
<span class="sd"> values: list of values to search in property</span>
|
|
<span class="sd"> ignore_case: ignore case when searching</span>
|
|
|
|
<span class="sd"> Returns:</span>
|
|
<span class="sd"> list of PhotoInfo objects matching search criteria</span>
|
|
<span class="sd"> """</span>
|
|
<span class="n">photos_search</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="k">if</span> <span class="n">ignore_case</span><span class="p">:</span>
|
|
<span class="c1"># case-insensitive</span>
|
|
<span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">values</span><span class="p">:</span>
|
|
<span class="n">x</span> <span class="o">=</span> <span class="n">x</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
|
|
<span class="n">photos_search</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span>
|
|
<span class="n">p</span>
|
|
<span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span>
|
|
<span class="k">if</span> <span class="n">x</span> <span class="ow">in</span> <span class="p">[</span><span class="n">attr</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="k">for</span> <span class="n">attr</span> <span class="ow">in</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">p</span><span class="p">,</span> <span class="n">attribute</span><span class="p">)]</span>
|
|
<span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">values</span><span class="p">:</span>
|
|
<span class="n">photos_search</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="n">x</span> <span class="ow">in</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">p</span><span class="p">,</span> <span class="n">attribute</span><span class="p">))</span>
|
|
<span class="k">return</span> <span class="n">photos_search</span>
|
|
</pre></div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
|
<div class="sphinxsidebarwrapper">
|
|
<h1 class="logo"><a href="../../../index.html">osxphotos</a></h1>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h3>Navigation</h3>
|
|
<ul>
|
|
<li class="toctree-l1"><a class="reference internal" href="../../../cli.html">osxphotos command line interface (CLI)</a></li>
|
|
<li class="toctree-l1"><a class="reference internal" href="../../../reference.html">osxphotos package</a></li>
|
|
</ul>
|
|
|
|
<div class="relations">
|
|
<h3>Related Topics</h3>
|
|
<ul>
|
|
<li><a href="../../../index.html">Documentation overview</a><ul>
|
|
<li><a href="../../index.html">Module code</a><ul>
|
|
</ul></li>
|
|
</ul></li>
|
|
</ul>
|
|
</div>
|
|
<div id="searchbox" style="display: none" role="search">
|
|
<h3 id="searchlabel">Quick search</h3>
|
|
<div class="searchformwrapper">
|
|
<form class="search" action="../../../search.html" method="get">
|
|
<input type="text" name="q" aria-labelledby="searchlabel" />
|
|
<input type="submit" value="Go" />
|
|
</form>
|
|
</div>
|
|
</div>
|
|
<script>$('#searchbox').show(0);</script>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</div>
|
|
</div>
|
|
<div class="clearer"></div>
|
|
</div>
|
|
<div class="footer">
|
|
©2021, Rhet Turnbull.
|
|
|
|
|
|
|
Powered by <a href="http://sphinx-doc.org/">Sphinx 3.5.2</a>
|
|
& <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
</body>
|
|
</html> |