3868 lines
515 KiB
HTML
3868 lines
515 KiB
HTML
<!doctype html>
|
|
<html class="no-js" lang="en">
|
|
<head><meta charset="utf-8"/>
|
|
<meta name="viewport" content="width=device-width,initial-scale=1"/>
|
|
<meta name="color-scheme" content="light dark"><link rel="index" title="Index" href="../../../genindex.html" /><link rel="search" title="Search" href="../../../search.html" />
|
|
|
|
<meta name="generator" content="sphinx-5.3.0, furo 2022.09.29"/>
|
|
<title>osxphotos.photosdb.photosdb - osxphotos 0.60.8 documentation</title>
|
|
<link rel="stylesheet" type="text/css" href="../../../_static/pygments.css" />
|
|
<link rel="stylesheet" type="text/css" href="../../../_static/styles/furo.css?digest=d81277517bee4d6b0349d71bb2661d4890b5617c" />
|
|
<link rel="stylesheet" type="text/css" href="../../../_static/copybutton.css" />
|
|
<link rel="stylesheet" type="text/css" href="../../../_static/styles/furo-extensions.css?digest=30d1aed668e5c3a91c3e3bf6a60b675221979f0e" />
|
|
|
|
|
|
|
|
|
|
<style>
|
|
body {
|
|
--color-code-background: #f8f8f8;
|
|
--color-code-foreground: black;
|
|
|
|
}
|
|
@media not print {
|
|
body[data-theme="dark"] {
|
|
--color-code-background: #202020;
|
|
--color-code-foreground: #d0d0d0;
|
|
|
|
}
|
|
@media (prefers-color-scheme: dark) {
|
|
body:not([data-theme="light"]) {
|
|
--color-code-background: #202020;
|
|
--color-code-foreground: #d0d0d0;
|
|
|
|
}
|
|
}
|
|
}
|
|
</style></head>
|
|
<body>
|
|
|
|
<script>
|
|
document.body.dataset.theme = localStorage.getItem("theme") || "auto";
|
|
</script>
|
|
|
|
|
|
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
|
|
<symbol id="svg-toc" viewBox="0 0 24 24">
|
|
<title>Contents</title>
|
|
<svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 1024 1024">
|
|
<path d="M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM115.4 518.9L271.7 642c5.8 4.6 14.4.5 14.4-6.9V388.9c0-7.4-8.5-11.5-14.4-6.9L115.4 505.1a8.74 8.74 0 0 0 0 13.8z"/>
|
|
</svg>
|
|
</symbol>
|
|
<symbol id="svg-menu" viewBox="0 0 24 24">
|
|
<title>Menu</title>
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
|
stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather-menu">
|
|
<line x1="3" y1="12" x2="21" y2="12"></line>
|
|
<line x1="3" y1="6" x2="21" y2="6"></line>
|
|
<line x1="3" y1="18" x2="21" y2="18"></line>
|
|
</svg>
|
|
</symbol>
|
|
<symbol id="svg-arrow-right" viewBox="0 0 24 24">
|
|
<title>Expand</title>
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
|
stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather-chevron-right">
|
|
<polyline points="9 18 15 12 9 6"></polyline>
|
|
</svg>
|
|
</symbol>
|
|
<symbol id="svg-sun" viewBox="0 0 24 24">
|
|
<title>Light mode</title>
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
|
stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="feather-sun">
|
|
<circle cx="12" cy="12" r="5"></circle>
|
|
<line x1="12" y1="1" x2="12" y2="3"></line>
|
|
<line x1="12" y1="21" x2="12" y2="23"></line>
|
|
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
|
|
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
|
|
<line x1="1" y1="12" x2="3" y2="12"></line>
|
|
<line x1="21" y1="12" x2="23" y2="12"></line>
|
|
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
|
|
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
|
|
</svg>
|
|
</symbol>
|
|
<symbol id="svg-moon" viewBox="0 0 24 24">
|
|
<title>Dark mode</title>
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
|
stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="icon-tabler-moon">
|
|
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
|
<path d="M12 3c.132 0 .263 0 .393 0a7.5 7.5 0 0 0 7.92 12.446a9 9 0 1 1 -8.313 -12.454z" />
|
|
</svg>
|
|
</symbol>
|
|
<symbol id="svg-sun-half" viewBox="0 0 24 24">
|
|
<title>Auto light/dark mode</title>
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
|
stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="icon-tabler-shadow">
|
|
<path stroke="none" d="M0 0h24v24H0z" fill="none"/>
|
|
<circle cx="12" cy="12" r="9" />
|
|
<path d="M13 12h5" />
|
|
<path d="M13 15h4" />
|
|
<path d="M13 18h1" />
|
|
<path d="M13 9h4" />
|
|
<path d="M13 6h1" />
|
|
</svg>
|
|
</symbol>
|
|
</svg>
|
|
|
|
<input type="checkbox" class="sidebar-toggle" name="__navigation" id="__navigation">
|
|
<input type="checkbox" class="sidebar-toggle" name="__toc" id="__toc">
|
|
<label class="overlay sidebar-overlay" for="__navigation">
|
|
<div class="visually-hidden">Hide navigation sidebar</div>
|
|
</label>
|
|
<label class="overlay toc-overlay" for="__toc">
|
|
<div class="visually-hidden">Hide table of contents sidebar</div>
|
|
</label>
|
|
|
|
|
|
|
|
<div class="page">
|
|
<header class="mobile-header">
|
|
<div class="header-left">
|
|
<label class="nav-overlay-icon" for="__navigation">
|
|
<div class="visually-hidden">Toggle site navigation sidebar</div>
|
|
<i class="icon"><svg><use href="#svg-menu"></use></svg></i>
|
|
</label>
|
|
</div>
|
|
<div class="header-center">
|
|
<a href="../../../index.html"><div class="brand">osxphotos 0.60.8 documentation</div></a>
|
|
</div>
|
|
<div class="header-right">
|
|
<div class="theme-toggle-container theme-toggle-header">
|
|
<button class="theme-toggle">
|
|
<div class="visually-hidden">Toggle Light / Dark / Auto color theme</div>
|
|
<svg class="theme-icon-when-auto"><use href="#svg-sun-half"></use></svg>
|
|
<svg class="theme-icon-when-dark"><use href="#svg-moon"></use></svg>
|
|
<svg class="theme-icon-when-light"><use href="#svg-sun"></use></svg>
|
|
</button>
|
|
</div>
|
|
<label class="toc-overlay-icon toc-header-icon no-toc" for="__toc">
|
|
<div class="visually-hidden">Toggle table of contents sidebar</div>
|
|
<i class="icon"><svg><use href="#svg-toc"></use></svg></i>
|
|
</label>
|
|
</div>
|
|
</header>
|
|
<aside class="sidebar-drawer">
|
|
<div class="sidebar-container">
|
|
|
|
<div class="sidebar-sticky"><a class="sidebar-brand" href="../../../index.html">
|
|
|
|
|
|
<span class="sidebar-brand-text">osxphotos 0.60.8 documentation</span>
|
|
|
|
</a><form class="sidebar-search-container" method="get" action="../../../search.html" role="search">
|
|
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
|
|
<input type="hidden" name="check_keywords" value="yes">
|
|
<input type="hidden" name="area" value="default">
|
|
</form>
|
|
<div id="searchbox"></div><div class="sidebar-scroll"><div class="sidebar-tree">
|
|
<ul>
|
|
<li class="toctree-l1"><a class="reference internal" href="../../../overview.html">OSXPhotos</a></li>
|
|
<li class="toctree-l1"><a class="reference internal" href="../../../tutorial.html">OSXPhotos Tutorial</a></li>
|
|
<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="../../../template_help.html">OSXPhotos Template System</a></li>
|
|
<li class="toctree-l1"><a class="reference internal" href="../../../package_overview.html">OSXPhotos Python Package Overview</a></li>
|
|
<li class="toctree-l1"><a class="reference internal" href="../../../reference.html">OSXPhotos Python Reference</a></li>
|
|
</ul>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
</aside>
|
|
<div class="main">
|
|
<div class="content">
|
|
<div class="article-container">
|
|
<a href="#" class="back-to-top muted-link">
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
|
<path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8v12z"></path>
|
|
</svg>
|
|
<span>Back to top</span>
|
|
</a>
|
|
<div class="content-icon-container">
|
|
<div class="theme-toggle-container theme-toggle-content">
|
|
<button class="theme-toggle">
|
|
<div class="visually-hidden">Toggle Light / Dark / Auto color theme</div>
|
|
<svg class="theme-icon-when-auto"><use href="#svg-sun-half"></use></svg>
|
|
<svg class="theme-icon-when-dark"><use href="#svg-moon"></use></svg>
|
|
<svg class="theme-icon-when-light"><use href="#svg-sun"></use></svg>
|
|
</button>
|
|
</div>
|
|
<label class="toc-overlay-icon toc-content-icon no-toc" for="__toc">
|
|
<div class="visually-hidden">Toggle table of contents sidebar</div>
|
|
<i class="icon"><svg><use href="#svg-toc"></use></svg></i>
|
|
</label>
|
|
</div>
|
|
<article 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">from</span> <span class="nn">__future__</span> <span class="kn">import</span> <span class="n">annotations</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">sqlite3</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">collections</span> <span class="kn">import</span> <span class="n">OrderedDict</span>
|
|
<span class="kn">from</span> <span class="nn">collections.abc</span> <span class="kn">import</span> <span class="n">Iterable</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">typing</span> <span class="kn">import</span> <span class="n">Any</span><span class="p">,</span> <span class="n">List</span><span class="p">,</span> <span class="n">Optional</span>
|
|
<span class="kn">from</span> <span class="nn">unicodedata</span> <span class="kn">import</span> <span class="n">normalize</span>
|
|
|
|
<span class="kn">import</span> <span class="nn">bitmath</span>
|
|
<span class="kn">from</span> <span class="nn">rich</span> <span class="kn">import</span> <span class="nb">print</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_ALBUM_TYPE_ALBUM</span><span class="p">,</span>
|
|
<span class="n">_PHOTOS_4_ALBUM_TYPE_PROJECT</span><span class="p">,</span>
|
|
<span class="n">_PHOTOS_4_ALBUM_TYPE_SLIDESHOW</span><span class="p">,</span>
|
|
<span class="n">_PHOTOS_4_ROOT_FOLDER</span><span class="p">,</span>
|
|
<span class="n">_PHOTOS_4_TOP_LEVEL_ALBUMS</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_PROJECT_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">_PHOTOS_5_VERSION</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_PICK_TYPE_NONE</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="p">,</span> <span class="n">ProjectInfo</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">..phototemplate</span> <span class="kn">import</span> <span class="n">RenderOptions</span>
|
|
<span class="kn">from</span> <span class="nn">..platform</span> <span class="kn">import</span> <span class="n">get_macos_version</span><span class="p">,</span> <span class="n">is_macos</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">..rich_utils</span> <span class="kn">import</span> <span class="n">add_rich_markup_tag</span>
|
|
<span class="kn">from</span> <span class="nn">..sqlite_utils</span> <span class="kn">import</span> <span class="n">sqlite_db_is_locked</span><span class="p">,</span> <span class="n">sqlite_open_ro</span>
|
|
<span class="kn">from</span> <span class="nn">..unicode</span> <span class="kn">import</span> <span class="n">normalize_unicode</span>
|
|
<span class="kn">from</span> <span class="nn">..utils</span> <span class="kn">import</span> <span class="n">_check_file_exists</span><span class="p">,</span> <span class="n">get_last_library_path</span><span class="p">,</span> <span class="n">noop</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="k">if</span> <span class="n">is_macos</span><span class="p">:</span>
|
|
<span class="kn">import</span> <span class="nn">photoscript</span>
|
|
|
|
<span class="n">logger</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s2">"osxphotos"</span><span class="p">)</span>
|
|
|
|
<span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"PhotosDB"</span><span class="p">]</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_comments</span> <span class="kn">import</span> <span class="n">_process_comments</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_scoreinfo</span> <span class="kn">import</span> <span class="n">_process_scoreinfo</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_as_dict</span><span class="p">,</span>
|
|
<span class="n">labels_normalized</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_syndicationinfo</span> <span class="kn">import</span> <span class="n">_process_syndicationinfo</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="n">rich</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
|
|
<span class="n">_skip_searchinfo</span><span class="o">=</span><span class="kc">False</span><span class="p">,</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"> rich: use rich with verbose output</span>
|
|
<span class="sd"> _skip_searchinfo: if True, will not process search data from psi.sqlite; useful for processing standalone Photos.sqlite file</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_macos_version</span><span class="p">()</span> <span class="k">if</span> <span class="n">is_macos</span> <span class="k">else</span> <span class="p">(</span><span class="kc">None</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="kc">None</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">and</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="bp">self</span><span class="o">.</span><span class="n">_skip_searchinfo</span> <span class="o">=</span> <span class="n">_skip_searchinfo</span>
|
|
|
|
<span class="c1"># define functions for adding markup</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_filepath</span> <span class="o">=</span> <span class="n">add_rich_markup_tag</span><span class="p">(</span><span class="s2">"filepath"</span><span class="p">,</span> <span class="n">rich</span><span class="o">=</span><span class="n">rich</span><span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_filename</span> <span class="o">=</span> <span class="n">add_rich_markup_tag</span><span class="p">(</span><span class="s2">"filename"</span><span class="p">,</span> <span class="n">rich</span><span class="o">=</span><span class="n">rich</span><span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_uuid</span> <span class="o">=</span> <span class="n">add_rich_markup_tag</span><span class="p">(</span><span class="s2">"uuid"</span><span class="p">,</span> <span class="n">rich</span><span class="o">=</span><span class="n">rich</span><span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_num</span> <span class="o">=</span> <span class="n">add_rich_markup_tag</span><span class="p">(</span><span class="s2">"num"</span><span class="p">,</span> <span class="n">rich</span><span class="o">=</span><span class="n">rich</span><span class="p">)</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="c1"># Dict to hold signatures for finding possible duplicates</span>
|
|
<span class="c1"># key is tuple of (original_filesize, date) and value is list of uuids that match that signature</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_db_signatures</span> <span class="o">=</span> <span class="p">{}</span>
|
|
|
|
<span class="c1"># Dict to hold information on volume names (Photos 5+)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_db_filesystem_volumes</span> <span class="o">=</span> <span class="p">{}</span>
|
|
|
|
<span class="c1"># Dict to hold information on moments (Photos 5+)</span>
|
|
<span class="c1"># key is Z_PK of ZMOMENT table and values are the moment info</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_db_moment_pk</span> <span class="o">=</span> <span class="p">{}</span>
|
|
|
|
<span class="c1"># Dict to hold data on imports for Photos <= 4</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_db_import_group</span> <span class="o">=</span> <span class="p">{}</span>
|
|
|
|
<span class="c1"># Dict to hold syndication info for Photos >= 8</span>
|
|
<span class="c1"># key is UUID and value is dict of syndication info</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_db_syndication_uuid</span> <span class="o">=</span> <span class="p">{}</span>
|
|
|
|
<span class="n">logger</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="n">logger</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">_filepath</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="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">sqlite_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="c1"># _db_version is set from photos.db</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"># _photos_version is set from Photos.sqlite which only exists for Photos 5+</span>
|
|
<span class="n">db_ver_int</span> <span class="o">=</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="k">if</span> <span class="n">db_ver_int</span> <span class="o"><</span> <span class="mi">3000</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="mi">2</span>
|
|
<span class="k">elif</span> <span class="n">db_ver_int</span> <span class="o"><</span> <span class="mi">4000</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="mi">3</span>
|
|
<span class="k">elif</span> <span class="n">db_ver_int</span> <span class="o"><</span> <span class="mi">5000</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="mi">4</span>
|
|
<span class="k">else</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="mi">5</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">_filepath</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="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">sqlite_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="c1"># set the photos version to actual value based on Photos.sqlite</span>
|
|
<span class="bp">self</span><span class="o">.</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="n">logger</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="n">logger</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="bp">self</span><span class="o">.</span><span class="n">_db_connection</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_db_connection</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="ow">in</span> <span class="n">_PHOTOS_4_TOP_LEVEL_ALBUMS</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="ow">in</span> <span class="n">_PHOTOS_4_TOP_LEVEL_ALBUMS</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="sd"> """</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="sd"> """</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">project_info</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">"""return list of AlbumInfo projects for each project 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">_project_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">_project_info</span> <span class="o">=</span> <span class="p">[</span>
|
|
<span class="n">ProjectInfo</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">project</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">_project_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>
|
|
|
|
<span class="nd">@property</span>
|
|
<span class="k">def</span> <span class="nf">photos_version</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">"""returns version of Photos app that created the library"""</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_photos_ver</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">sqlite_open_ro</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="nb">str</span><span class="p">)</span> <span class="o">-></span> <span class="nb">str</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="n">logger</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="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">_num</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="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">sqlite_open_ro</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="p">(</span>
|
|
<span class="n">normalize_unicode</span><span class="p">(</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="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="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">normalize_unicode</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="s2">"type"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span> <span class="c1"># Photos 5+</span>
|
|
<span class="s2">"manualorder"</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> <span class="c1"># Photos 5+</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">logger</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="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="s2">"customsortascending"</span><span class="p">:</span> <span class="kc">None</span><span class="p">,</span> <span class="c1"># Photos 5+ only</span>
|
|
<span class="s2">"customsortkey"</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="p">(</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="n">_PHOTOS_4_TOP_LEVEL_ALBUMS</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="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_title</span><span class="p">,</span> <span class="n">keyword_uuid</span><span class="p">,</span> <span class="n">_</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_title</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">_dbkeywords_uuid</span><span class="p">[</span><span class="n">keyword_uuid</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">keyword_title</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">_dbkeywords_uuid</span><span class="p">[</span><span class="n">keyword_uuid</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="n">keyword_title</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">_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_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">_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="n">keyword_uuid</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"> RKMaster.importGroupUuid,</span>
|
|
<span class="sd"> RKMaster.fingerprint</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"> RKMaster.importGroupUuid,</span>
|
|
<span class="sd"> RKMaster.fingerprint</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="c1"># 44 RKMaster.importGroupUuid -- to get date added from RKImportGroup</span>
|
|
<span class="c1"># 45 RKMaster.fingerprint -- fingerprint / hash of the file</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">_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">normalize_unicode</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="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="p">(</span><span class="ne">ValueError</span><span class="p">,</span> <span class="ne">TypeError</span><span class="p">):</span>
|
|
<span class="c1"># sometimes the date is invalid or null</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="p">(</span><span class="ne">ValueError</span><span class="p">,</span> <span class="ne">TypeError</span><span class="p">):</span>
|
|
<span class="c1"># sometimes imageDate is invalid so use 1 Jan 1970 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="n">logger</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">"pk"</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"># same as masterModelID, to match 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">"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="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">"cloudMasterGUID"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span> <span class="c1"># Photos 5+</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="n">row</span><span class="p">[</span><span class="mi">44</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="kc">None</span>
|
|
|
|
<span class="c1"># fingerprint</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">"masterFingerprint"</span><span class="p">]</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">45</span><span class="p">]</span>
|
|
|
|
<span class="c1"># photos 5+ only, for shared photos</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">"cloudownerhashedpersonid"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
|
|
<span class="c1"># compute signatures for finding possible duplicates</span>
|
|
<span class="n">signature</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_duplicate_signature</span><span class="p">(</span><span class="n">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">_db_signatures</span><span class="p">[</span><span class="n">signature</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">_db_signatures</span><span class="p">[</span><span class="n">signature</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="n">uuid</span><span class="p">]</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">normalize_unicode</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="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">normalize_unicode</span><span class="p">(</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="sd"> ORDER BY RKModelResource.modelId</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 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 (2 = edit)</span>
|
|
<span class="c1"># 7 RKModelResource.resourceType (4 = photo, 8 = video)</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="n">resource_type</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="c1"># UTI_edited will be set to the appropriate UTI for the edited resource below</span>
|
|
<span class="c1"># a live photo that's edited will have both a photo and video resource but the photo</span>
|
|
<span class="c1"># UTI will be used for the edited live photo, see #859</span>
|
|
<span class="k">if</span> <span class="n">resource_type</span> <span class="o">==</span> <span class="mi">4</span><span class="p">:</span>
|
|
<span class="c1"># photo</span>
|
|
<span class="k">if</span> <span class="s2">"edit_resource_id_photo"</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="n">logger</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_photo 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="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_photo"</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_photo"</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">elif</span> <span class="n">resource_type</span> <span class="o">==</span> <span class="mi">8</span><span class="p">:</span>
|
|
<span class="c1"># video</span>
|
|
<span class="k">if</span> <span class="s2">"edit_resource_id_video"</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="n">logger</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_video 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="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_video"</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_video"</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="c1"># also initialized UTI_edited and edit_resource_id</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_photo"</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_photo"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="k">if</span> <span class="s2">"edit_resource_id_video"</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_video"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="k">if</span> <span class="s2">"UTI_edited_photo"</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">"UTI_edited_photo"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="k">if</span> <span class="s2">"UTI_edited_video"</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">"UTI_edited_video"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
|
<span class="c1"># UTI_edited will be set to the appropriate UTI for the edited resource below</span>
|
|
<span class="c1"># a live photo that's edited will have both a photo and video resource but the photo</span>
|
|
<span class="c1"># UTI will be used for the edited live 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">"UTI_edited"</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">"UTI_edited_photo"</span><span class="p">]</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">uuid</span><span class="p">][</span><span class="s2">"UTI_edited_video"</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">"edit_resource_id"</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">"edit_resource_id_photo"</span><span class="p">]</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">uuid</span><span class="p">][</span><span class="s2">"edit_resource_id_video"</span><span class="p">]</span>
|
|
<span class="p">)</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 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="c1"># get import data</span>
|
|
<span class="n">import_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, uuid, name, importDate from RKImportGroup"</span>
|
|
<span class="p">)</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">_db_import_group</span> <span class="o">=</span> <span class="p">{</span><span class="n">i</span><span class="p">[</span><span class="mi">1</span><span class="p">]:</span> <span class="n">i</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">import_data</span><span class="p">}</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"># add date added</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">import_session</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db_import_group</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="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">"added_date"</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">import_session</span><span class="p">[</span><span class="mi">3</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="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">"added_date"</span><span class="p">]</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="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">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="ow">in</span> <span class="n">_PHOTOS_4_TOP_LEVEL_ALBUMS</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="n">logger</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">sqlite_open_ro</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="c1"># set local var for readability</span>
|
|
<span class="n">photos_ver</span> <span class="o">=</span> <span class="bp">self</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">_num</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="si">}</span><span class="s2">, </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">_num</span><span class="p">(</span><span class="n">photos_ver</span><span class="p">)</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">asset_album_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_ALBUM_TABLE"</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">asset_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">"ASSET_ALBUM_JOIN"</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="n">uti_original_column</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">"UTI_ORIGINAL"</span><span class="p">]</span>
|
|
<span class="n">hdr_type_column</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">"HDR_TYPE"</span><span class="p">]</span>
|
|
|
|
<span class="c1"># Look for all combinations of persons and pictures</span>
|
|
<span class="n">logger</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"> ZPERSON.ZTYPE,</span>
|
|
<span class="sd"> ZPERSON.ZMANUALORDER</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="c1"># 6 ZPERSON.ZTYPE, # ZTYPE = 1 == favorite, 0 == not favorite</span>
|
|
<span class="c1"># 7 ZPERSON.ZMANUALORDER # favorites are sorted by ZMANUALORDER</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="p">(</span>
|
|
<span class="n">normalize_unicode</span><span class="p">(</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="p">(</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="ow">and</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="p">)</span>
|
|
<span class="k">else</span> <span class="n">_UNKNOWN_PERSON</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="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">normalize_unicode</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="s2">"type"</span><span class="p">:</span> <span class="n">person</span><span class="p">[</span><span class="mi">6</span><span class="p">],</span>
|
|
<span class="s2">"manualorder"</span><span class="p">:</span> <span class="n">person</span><span class="p">[</span><span class="mi">7</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">asset_fk</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">"DETECTED_FACE_ASSET_FK"</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"> 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"> </span><span class="si">{</span><span class="n">asset_fk</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"> """</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">logger</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">person_fk</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">"DETECTED_FACE_PERSON_FK"</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 </span><span class="si">{</span><span class="n">person_fk</span><span class="si">}</span><span class="s2"> = ZPERSON.Z_PK AND</span>
|
|
<span class="s2"> </span><span class="si">{</span><span class="n">asset_fk</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"> """</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="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 </span><span class="si">{</span><span class="n">asset_album_table</span><span class="si">}</span><span class="s2"> 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 = </span><span class="si">{</span><span class="n">asset_album_join</span><span class="si">}</span><span class="s2"></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">"ZCUSTOMSORTASCENDING, "</span> <span class="c1"># 13</span>
|
|
<span class="s2">"ZCUSTOMSORTKEY "</span> <span class="c1"># 14</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="ow">or</span> <span class="mi">0</span><span class="p">,</span> <span class="c1"># iPhone Photos.sqlite can have null value</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="ow">or</span> <span class="mi">0</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="ow">or</span> <span class="mi">0</span><span class="p">,</span>
|
|
<span class="s2">"customsortascending"</span><span class="p">:</span> <span class="n">album</span><span class="p">[</span><span class="mi">13</span><span class="p">],</span>
|
|
<span class="s2">"customsortkey"</span><span class="p">:</span> <span class="n">album</span><span class="p">[</span><span class="mi">14</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="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_title</span><span class="p">,</span> <span class="n">keyword_uuid</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_title</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">_dbkeywords_uuid</span><span class="p">[</span><span class="n">keyword_uuid</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">keyword_title</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">_dbkeywords_uuid</span><span class="p">[</span><span class="n">keyword_uuid</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="n">keyword_title</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">_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_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">_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="n">keyword_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="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">.</span><span class="si">{</span><span class="n">hdr_type_column</span><span class="si">}</span><span class="s2">,</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"> </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.ZADDEDDATE,</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"> </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.ZCLOUDOWNERHASHEDPERSONID</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="c1"># 41 ZGENERICASSET.ZADDEDDATE -- date item added to the library</span>
|
|
<span class="c1"># 42 ZGENERICASSET.Z_PK -- primary key</span>
|
|
<span class="c1"># 43 ZGENERICASSET.ZCLOUDOWNERHASHEDPERSONID -- used to look up owner name (for shared photos)</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="p">(</span><span class="ne">ValueError</span><span class="p">,</span> <span class="ne">TypeError</span><span class="p">):</span>
|
|
<span class="c1"># sometimes imageDate is invalid or null so use 1 Jan 1970 in UTC as image date (#1014)</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">normalize_unicode</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="n">info</span><span class="p">[</span><span class="s2">"filename"</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">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="n">logger</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="n">info</span><span class="p">[</span><span class="s2">"cloudMasterGUID"</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</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="k">try</span><span class="p">:</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"added_date"</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="n">info</span><span class="p">[</span><span class="s2">"added_date"</span><span class="p">]</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">info</span><span class="p">[</span><span class="s2">"pk"</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="n">info</span><span class="p">[</span><span class="s2">"cloudownerhashedpersonid"</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="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="c1"># Photos 4 only</span>
|
|
<span class="n">info</span><span class="p">[</span><span class="s2">"edit_resource_id_photo"</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">"edit_resource_id_video"</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_edited_photo"</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_edited_video"</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="o">=</span> <span class="n">info</span>
|
|
|
|
<span class="c1"># compute signatures for finding possible duplicates</span>
|
|
<span class="n">signature</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_duplicate_signature</span><span class="p">(</span><span class="n">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">_db_signatures</span><span class="p">[</span><span class="n">signature</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">_db_signatures</span><span class="p">[</span><span class="n">signature</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="n">uuid</span><span class="p">]</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">logger</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="n">logger</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="n">logger</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="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_photos_ver</span> <span class="o">>=</span> <span class="mi">7</span><span class="p">:</span>
|
|
<span class="n">sql_missing</span> <span class="o">=</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"> </span><span class="si">{</span><span class="n">uti_original_column</span><span class="si">}</span><span class="s2">,</span>
|
|
<span class="s2"> null </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"> WHERE ZDATASTORESUBTYPE = 1 OR ZDATASTORESUBTYPE = 3 """</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">sql_missing</span> <span class="o">=</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"> </span><span class="si">{</span><span class="n">uti_original_column</span><span class="si">}</span><span class="s2">,</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="n">c</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="n">sql_missing</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"> ZCLOUDMASTER.ZCLOUDMASTERGUID</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="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">"cloudMasterGUID"</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="c1"># get information about associted RAW images</span>
|
|
<span class="c1"># RAW images have ZDATASTORESUBTYPE = 17</span>
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_photos_ver</span> <span class="o">>=</span> <span class="mi">7</span><span class="p">:</span>
|
|
<span class="n">sql_raw</span> <span class="o">=</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"> null,</span>
|
|
<span class="s2"> ZINTERNALRESOURCE.ZDATASTORESUBTYPE,</span>
|
|
<span class="s2"> ZINTERNALRESOURCE.ZRESOURCETYPE,</span>
|
|
<span class="s2"> ZINTERNALRESOURCE.ZFILESYSTEMBOOKMARK</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"> WHERE ZINTERNALRESOURCE.ZDATASTORESUBTYPE = 17</span>
|
|
<span class="s2"> """</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">sql_raw</span> <span class="o">=</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"> ZINTERNALRESOURCE.ZFILESYSTEMBOOKMARK</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="n">c</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="n">sql_raw</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="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_bookmark"</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="c1"># get paths for the relative imports for RAW+JPEG images</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"> ZFILESYSTEMVOLUME.ZNAME,</span>
|
|
<span class="s2"> ZFILESYSTEMBOOKMARK.ZPATHRELATIVETOVOLUME</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 ZFILESYSTEMBOOKMARK ON ZFILESYSTEMBOOKMARK.ZRESOURCE = ZINTERNALRESOURCE.Z_PK</span>
|
|
<span class="s2"> JOIN ZFILESYSTEMVOLUME ON ZFILESYSTEMVOLUME.Z_PK = ZINTERNALRESOURCE.ZFILESYSTEMVOLUME</span>
|
|
<span class="s2"> WHERE ZINTERNALRESOURCE.ZDATASTORESUBTYPE = 17</span>
|
|
<span class="s2"> """</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="c1"># path to the raw image will be /Volumes/ZFILESYSTEMVOLUME.ZNAME/ZFILESYSTEMBOOKMARK.ZPATHRELATIVETOVOLUME</span>
|
|
<span class="c1"># 0: {asset_table}.ZUUID, -- UUID</span>
|
|
<span class="c1"># 1: ZFILESYSTEMVOLUME.ZNAME, -- name of the volume</span>
|
|
<span class="c1"># 2: ZFILESYSTEMBOOKMARK.ZPATHRELATIVETOVOLUME -- path to the raw image</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">"raw_volume"</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">"raw_relative_path"</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="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"># process moments</span>
|
|
<span class="n">verbose</span><span class="p">(</span><span class="s2">"Processing moments."</span><span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_process_moments</span><span class="p">()</span>
|
|
|
|
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">photos_version</span> <span class="o">>=</span> <span class="mi">8</span><span class="p">:</span>
|
|
<span class="n">verbose</span><span class="p">(</span><span class="s2">"Processing syndication info."</span><span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_process_syndicationinfo</span><span class="p">()</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">def</span> <span class="nf">_process_moments</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">"""Process data from ZMOMENT table"""</span>
|
|
<span class="c1"># _db_moment_pk is dict in form {pk: {moment info}} by ZMOMENT.Z_PK</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">raise</span> <span class="ne">NotImplementedError</span><span class="p">(</span>
|
|
<span class="sa">f</span><span class="s2">"Moment info implemented for this database version"</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_moment_5</span><span class="p">()</span>
|
|
|
|
<span class="k">def</span> <span class="nf">_process_moment_5</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">"""Process moment info for Photos 5 databases"""</span>
|
|
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_db_moment_pk</span> <span class="o">=</span> <span class="p">{}</span>
|
|
|
|
<span class="n">results</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span>
|
|
<span class="sa">f</span><span class="s2">"""</span>
|
|
<span class="s2"> SELECT </span>
|
|
<span class="s2"> Z_PK,</span>
|
|
<span class="s2"> ZTIMEZONEOFFSET,</span>
|
|
<span class="s2"> ZTRASHEDSTATE,</span>
|
|
<span class="s2"> ZAPPROXIMATELATITUDE,</span>
|
|
<span class="s2"> ZAPPROXIMATELONGITUDE,</span>
|
|
<span class="s2"> ZENDDATE,</span>
|
|
<span class="s2"> ZMODIFICATIONDATE,</span>
|
|
<span class="s2"> ZREPRESENTATIVEDATE,</span>
|
|
<span class="s2"> ZSTARTDATE,</span>
|
|
<span class="s2"> ZSUBTITLE,</span>
|
|
<span class="s2"> ZTITLE,</span>
|
|
<span class="s2"> ZUUID</span>
|
|
<span class="s2"> FROM ZMOMENT"""</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="c1"># results</span>
|
|
<span class="c1"># 0 Z_PK,</span>
|
|
<span class="c1"># 1 ZTIMEZONEOFFSET,</span>
|
|
<span class="c1"># 2 ZTRASHEDSTATE,</span>
|
|
<span class="c1"># 3 ZAPPROXIMATELATITUDE,</span>
|
|
<span class="c1"># 4 ZAPPROXIMATELONGITUDE,</span>
|
|
<span class="c1"># 5 ZENDDATE,</span>
|
|
<span class="c1"># 6 ZMODIFICATIONDATE,</span>
|
|
<span class="c1"># 7 ZREPRESENTATIVEDATE,</span>
|
|
<span class="c1"># 8 ZSTARTDATE,</span>
|
|
<span class="c1"># 9 ZSUBTITLE,</span>
|
|
<span class="c1"># 10 ZTITLE,</span>
|
|
<span class="c1"># 11 ZUUID</span>
|
|
|
|
<span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">results</span><span class="p">:</span>
|
|
<span class="n">moment_info</span> <span class="o">=</span> <span class="p">{}</span>
|
|
<span class="n">moment_info</span><span class="p">[</span><span class="s2">"pk"</span><span class="p">]</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">moment_info</span><span class="p">[</span><span class="s2">"timezoneOffset"</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">moment_info</span><span class="p">[</span><span class="s2">"trashedState"</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">moment_info</span><span class="p">[</span><span class="s2">"approximateLatitude"</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">moment_info</span><span class="p">[</span><span class="s2">"approximateLongitude"</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">moment_info</span><span class="p">[</span><span class="s2">"endDate"</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">moment_info</span><span class="p">[</span><span class="s2">"modificationDate"</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">moment_info</span><span class="p">[</span><span class="s2">"representativeDate"</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">moment_info</span><span class="p">[</span><span class="s2">"startDate"</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">moment_info</span><span class="p">[</span><span class="s2">"subtitle"</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">9</span><span class="p">])</span>
|
|
<span class="n">moment_info</span><span class="p">[</span><span class="s2">"title"</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">10</span><span class="p">])</span>
|
|
<span class="n">moment_info</span><span class="p">[</span><span class="s2">"uuid"</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"># if both lat/lon == -180, then it means location undefined</span>
|
|
<span class="k">if</span> <span class="p">(</span>
|
|
<span class="n">moment_info</span><span class="p">[</span><span class="s2">"approximateLatitude"</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">moment_info</span><span class="p">[</span><span class="s2">"approximateLongitude"</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">moment_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">moment_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">moment_info</span><span class="p">[</span><span class="s2">"latitude"</span><span class="p">]</span> <span class="o">=</span> <span class="n">moment_info</span><span class="p">[</span><span class="s2">"approximateLatitude"</span><span class="p">]</span>
|
|
<span class="n">moment_info</span><span class="p">[</span><span class="s2">"longitude"</span><span class="p">]</span> <span class="o">=</span> <span class="n">moment_info</span><span class="p">[</span><span class="s2">"approximateLongitude"</span><span class="p">]</span>
|
|
|
|
<span class="c1"># process date stamps</span>
|
|
<span class="n">offset_seconds</span> <span class="o">=</span> <span class="n">moment_info</span><span class="p">[</span><span class="s2">"timezoneOffset"</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">offset_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="k">for</span> <span class="n">date_name</span> <span class="ow">in</span> <span class="p">[</span>
|
|
<span class="s2">"startDate"</span><span class="p">,</span>
|
|
<span class="s2">"endDate"</span><span class="p">,</span>
|
|
<span class="s2">"modificationDate"</span><span class="p">,</span>
|
|
<span class="s2">"representativeDate"</span><span class="p">,</span>
|
|
<span class="p">]:</span>
|
|
<span class="n">date_stamp</span> <span class="o">=</span> <span class="n">moment_info</span><span class="p">[</span><span class="n">date_name</span><span class="p">]</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="n">moment_date</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">date_stamp</span> <span class="o">+</span> <span class="n">TIME_DELTA</span><span class="p">)</span>
|
|
<span class="c1"># save raw time stamp valu</span>
|
|
<span class="n">moment_info</span><span class="p">[</span><span class="n">date_name</span> <span class="o">+</span> <span class="s2">"_timestamp"</span><span class="p">]</span> <span class="o">=</span> <span class="n">moment_info</span><span class="p">[</span><span class="n">date_name</span><span class="p">]</span>
|
|
<span class="n">moment_info</span><span class="p">[</span><span class="n">date_name</span><span class="p">]</span> <span class="o">=</span> <span class="n">moment_date</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="p">(</span><span class="ne">ValueError</span><span class="p">,</span> <span class="ne">TypeError</span><span class="p">):</span>
|
|
<span class="c1"># sometimes imageDate is invalid or null so use 1 Jan 1970 in UTC as image date</span>
|
|
<span class="n">moment_date</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">moment_info</span><span class="p">[</span><span class="n">date_name</span> <span class="o">+</span> <span class="s2">"_timestamp"</span><span class="p">]</span> <span class="o">=</span> <span class="n">date_stamp</span>
|
|
<span class="n">moment_info</span><span class="p">[</span><span class="n">date_name</span><span class="p">]</span> <span class="o">=</span> <span class="n">moment_date</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="c1"># process title/subtitle</span>
|
|
<span class="c1"># use unicodedata.normalize with KFKC instead of normalize_unicode as is done elsewhere</span>
|
|
<span class="c1"># to replace non-breaking whitespace chars with spaces as Photos uses \xa0 as space in Moment titles, subtitles</span>
|
|
<span class="n">moment_info</span><span class="p">[</span><span class="s2">"title"</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span>
|
|
<span class="n">normalize</span><span class="p">(</span><span class="s2">"NFKC"</span><span class="p">,</span> <span class="n">moment_info</span><span class="p">[</span><span class="s2">"title"</span><span class="p">])</span> <span class="k">if</span> <span class="n">moment_info</span><span class="p">[</span><span class="s2">"title"</span><span class="p">]</span> <span class="k">else</span> <span class="s2">""</span>
|
|
<span class="p">)</span>
|
|
<span class="n">moment_info</span><span class="p">[</span><span class="s2">"subtitle"</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span>
|
|
<span class="n">normalize</span><span class="p">(</span><span class="s2">"NFKC"</span><span class="p">,</span> <span class="n">moment_info</span><span class="p">[</span><span class="s2">"subtitle"</span><span class="p">])</span>
|
|
<span class="k">if</span> <span class="n">moment_info</span><span class="p">[</span><span class="s2">"subtitle"</span><span class="p">]</span>
|
|
<span class="k">else</span> <span class="s2">""</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_db_moment_pk</span><span class="p">[</span><span class="n">moment_info</span><span class="p">[</span><span class="s2">"pk"</span><span class="p">]]</span> <span class="o">=</span> <span class="n">moment_info</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">logger</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">logger</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="n">project</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"> 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"> import_session: boolean, if True, returns import session albums, else normal or shared albums</span>
|
|
<span class="sd"> project: boolean, if True, returns albums that are part of My Projects</span>
|
|
<span class="sd"> Note: flags (shared, import_session) are mutually exclusive</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="nb">sum</span><span class="p">(</span><span class="nb">bool</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="p">[</span><span class="n">shared</span><span class="p">,</span> <span class="n">import_session</span><span class="p">,</span> <span class="n">project</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">"flags are mutually exclusive: pass zero or one of shared, import_session, projects"</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">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">elif</span> <span class="n">project</span><span class="p">:</span>
|
|
<span class="n">album_type</span> <span class="o">=</span> <span class="p">[</span>
|
|
<span class="n">_PHOTOS_4_ALBUM_TYPE_PROJECT</span><span class="p">,</span>
|
|
<span class="n">_PHOTOS_4_ALBUM_TYPE_SLIDESHOW</span><span class="p">,</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">album_type</span> <span class="o">=</span> <span class="p">[</span><span class="n">_PHOTOS_4_ALBUM_TYPE_ALBUM</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="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="n">detail</span><span class="p">[</span><span class="s2">"albumType"</span><span class="p">]</span> <span class="ow">in</span> <span class="n">album_type</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="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="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="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="c1"># Photos version 5+</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">elif</span> <span class="n">project</span><span class="p">:</span>
|
|
<span class="n">album_kind</span> <span class="o">=</span> <span class="n">_PHOTOS_5_PROJECT_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="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"> 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"> 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="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">List</span><span class="p">[</span><span class="nb">str</span><span class="p">]]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<span class="n">uuid</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">List</span><span class="p">[</span><span class="nb">str</span><span class="p">]]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<span class="n">persons</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">List</span><span class="p">[</span><span class="nb">str</span><span class="p">]]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<span class="n">albums</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">List</span><span class="p">[</span><span class="nb">str</span><span class="p">]]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<span class="n">images</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">,</span>
|
|
<span class="n">movies</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">True</span><span class="p">,</span>
|
|
<span class="n">from_date</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">datetime</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<span class="n">to_date</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">datetime</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
|
|
<span class="n">intrash</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span><span class="p">,</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">"""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="n">keyword</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="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="n">person</span> <span class="o">=</span> <span class="n">normalize_unicode</span><span class="p">(</span><span class="n">person</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="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_PICK_TYPE_NONE</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">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>
|
|
|
|
<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="k">return</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">for</span> <span class="n">uuid</span> <span class="ow">in</span> <span class="n">uuids</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></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">elif</span> <span class="n">options</span><span class="o">.</span><span class="n">no_keyword</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">keywords</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">elif</span> <span class="n">options</span><span class="o">.</span><span class="n">not_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="ow">not</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">elif</span> <span class="n">options</span><span class="o">.</span><span class="n">not_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="ow">not</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">year</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">year</span> <span class="ow">in</span> <span class="n">options</span><span class="o">.</span><span class="n">year</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="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_5_VERSION</span><span class="p">:</span>
|
|
<span class="c1"># search only original_filename (#594)</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">original_filename</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="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="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_5_VERSION</span><span class="p">:</span>
|
|
<span class="c1"># search only original_filename (#594)</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">original_filename</span><span class="p">]</span>
|
|
<span class="p">)</span>
|
|
<span class="k">else</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="nb">list</span><span class="p">(</span><span class="nb">set</span><span class="p">(</span><span class="n">photo_list</span><span class="p">))</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="n">render_options</span> <span class="o">=</span> <span class="n">RenderOptions</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="n">photo_list</span> <span class="o">=</span> <span class="p">[]</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="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">render_options</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">if</span> <span class="n">options</span><span class="o">.</span><span class="n">duplicate</span><span class="p">:</span>
|
|
<span class="n">no_date</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">no_date</span> <span class="o">=</span> <span class="n">no_date</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">photos</span> <span class="o">=</span> <span class="nb">sorted</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">duplicates</span><span class="p">],</span>
|
|
<span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">x</span><span class="p">:</span> <span class="n">x</span><span class="o">.</span><span class="n">date_added</span> <span class="ow">or</span> <span class="n">no_date</span><span class="p">,</span>
|
|
<span class="p">)</span>
|
|
<span class="c1"># gather all duplicates but ensure each uuid is only represented once</span>
|
|
<span class="n">photodict</span> <span class="o">=</span> <span class="n">OrderedDict</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">not</span> <span class="ow">in</span> <span class="n">photodict</span><span class="p">:</span>
|
|
<span class="n">photodict</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="k">for</span> <span class="n">d</span> <span class="ow">in</span> <span class="nb">sorted</span><span class="p">(</span>
|
|
<span class="n">p</span><span class="o">.</span><span class="n">duplicates</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">x</span><span class="p">:</span> <span class="n">x</span><span class="o">.</span><span class="n">date_added</span> <span class="ow">or</span> <span class="n">no_date</span>
|
|
<span class="p">):</span>
|
|
<span class="k">if</span> <span class="n">d</span><span class="o">.</span><span class="n">uuid</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">photodict</span><span class="p">:</span>
|
|
<span class="n">photodict</span><span class="p">[</span><span class="n">d</span><span class="o">.</span><span class="n">uuid</span><span class="p">]</span> <span class="o">=</span> <span class="n">d</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">photodict</span><span class="o">.</span><span class="n">values</span><span class="p">())</span>
|
|
|
|
<span class="c1"># filter for deleted as photo.duplicates will include photos in the trash</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="p">(</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="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">intrash</span><span class="p">]</span>
|
|
<span class="k">if</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="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">intrash</span><span class="p">]</span>
|
|
|
|
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">location</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">location</span> <span class="o">!=</span> <span class="p">(</span><span class="kc">None</span><span class="p">,</span> <span class="kc">None</span><span class="p">)]</span>
|
|
<span class="k">elif</span> <span class="n">options</span><span class="o">.</span><span class="n">no_location</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">location</span> <span class="o">==</span> <span class="p">(</span><span class="kc">None</span><span class="p">,</span> <span class="kc">None</span><span class="p">)]</span>
|
|
|
|
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">selected</span><span class="p">:</span>
|
|
<span class="c1"># photos selected in Photos app</span>
|
|
<span class="k">try</span><span class="p">:</span>
|
|
<span class="c1"># catch AppleScript errors as the scripting interfce to Photos is flaky</span>
|
|
<span class="n">selected</span> <span class="o">=</span> <span class="n">photoscript</span><span class="o">.</span><span class="n">PhotosLibrary</span><span class="p">()</span><span class="o">.</span><span class="n">selection</span>
|
|
<span class="n">selected_uuid</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span><span class="o">.</span><span class="n">uuid</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">selected</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">uuid</span> <span class="ow">in</span> <span class="n">selected_uuid</span><span class="p">]</span>
|
|
<span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
|
|
<span class="c1"># no photos selected or a selected photo was "open"</span>
|
|
<span class="c1"># selection only works if photos selected in main media browser</span>
|
|
<span class="n">photos</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">exif</span><span class="p">:</span>
|
|
<span class="n">matching_photos</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="ow">not</span> <span class="n">p</span><span class="o">.</span><span class="n">exiftool</span><span class="p">:</span>
|
|
<span class="k">continue</span>
|
|
<span class="n">exifdata</span> <span class="o">=</span> <span class="n">p</span><span class="o">.</span><span class="n">exiftool</span><span class="o">.</span><span class="n">asdict</span><span class="p">(</span><span class="n">normalized</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
|
|
<span class="n">exifdata</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">p</span><span class="o">.</span><span class="n">exiftool</span><span class="o">.</span><span class="n">asdict</span><span class="p">(</span><span class="n">tag_groups</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">normalized</span><span class="o">=</span><span class="kc">True</span><span class="p">))</span>
|
|
<span class="k">for</span> <span class="n">exiftag</span><span class="p">,</span> <span class="n">exifvalue</span> <span class="ow">in</span> <span class="n">options</span><span class="o">.</span><span class="n">exif</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="n">exifvalue</span> <span class="o">=</span> <span class="n">exifvalue</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
|
|
<span class="n">exifdata_value</span> <span class="o">=</span> <span class="n">exifdata</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">exiftag</span><span class="o">.</span><span class="n">lower</span><span class="p">(),</span> <span class="s2">""</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">exifdata_value</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
|
|
<span class="n">exifdata_value</span> <span class="o">=</span> <span class="n">exifdata_value</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
|
|
<span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">exifdata_value</span><span class="p">,</span> <span class="n">Iterable</span><span class="p">):</span>
|
|
<span class="n">exifdata_value</span> <span class="o">=</span> <span class="p">[</span><span class="n">v</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="k">for</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">exifdata_value</span><span class="p">]</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">exifdata_value</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">exifdata_value</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="n">exifvalue</span> <span class="ow">in</span> <span class="n">exifdata_value</span><span class="p">:</span>
|
|
<span class="n">matching_photos</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">else</span><span class="p">:</span>
|
|
<span class="n">exifdata_value</span> <span class="o">=</span> <span class="n">exifdata</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">exiftag</span><span class="o">.</span><span class="n">lower</span><span class="p">(),</span> <span class="s2">""</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">exifdata_value</span><span class="p">,</span> <span class="p">(</span><span class="nb">str</span><span class="p">,</span> <span class="n">Iterable</span><span class="p">)):</span>
|
|
<span class="n">exifdata_value</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">exifdata_value</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">exifvalue</span> <span class="ow">in</span> <span class="n">exifdata_value</span><span class="p">:</span>
|
|
<span class="n">matching_photos</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="n">photos</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="nb">set</span><span class="p">(</span><span class="n">matching_photos</span><span class="p">))</span>
|
|
|
|
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">added_after</span><span class="p">:</span>
|
|
<span class="n">added_after</span> <span class="o">=</span> <span class="n">options</span><span class="o">.</span><span class="n">added_after</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">added_after</span><span class="p">):</span>
|
|
<span class="n">added_after</span> <span class="o">=</span> <span class="n">datetime_naive_to_local</span><span class="p">(</span><span class="n">added_after</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_added</span> <span class="ow">and</span> <span class="n">p</span><span class="o">.</span><span class="n">date_added</span> <span class="o">></span> <span class="n">added_after</span><span class="p">]</span>
|
|
|
|
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">added_before</span><span class="p">:</span>
|
|
<span class="n">added_before</span> <span class="o">=</span> <span class="n">options</span><span class="o">.</span><span class="n">added_before</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">added_before</span><span class="p">):</span>
|
|
<span class="n">added_before</span> <span class="o">=</span> <span class="n">datetime_naive_to_local</span><span class="p">(</span><span class="n">added_before</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_added</span> <span class="ow">and</span> <span class="n">p</span><span class="o">.</span><span class="n">date_added</span> <span class="o"><</span> <span class="n">added_before</span><span class="p">]</span>
|
|
|
|
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">added_in_last</span><span class="p">:</span>
|
|
<span class="n">added_after</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">()</span> <span class="o">-</span> <span class="n">options</span><span class="o">.</span><span class="n">added_in_last</span>
|
|
<span class="n">added_after</span> <span class="o">=</span> <span class="n">datetime_naive_to_local</span><span class="p">(</span><span class="n">added_after</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_added</span> <span class="ow">and</span> <span class="n">p</span><span class="o">.</span><span class="n">date_added</span> <span class="o">></span> <span class="n">added_after</span><span class="p">]</span>
|
|
|
|
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">syndicated</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">syndicated</span><span class="p">]</span>
|
|
<span class="k">elif</span> <span class="n">options</span><span class="o">.</span><span class="n">not_syndicated</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">syndicated</span><span class="p">]</span>
|
|
|
|
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">saved_to_library</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">syndicated</span> <span class="ow">and</span> <span class="n">p</span><span class="o">.</span><span class="n">saved_to_library</span><span class="p">]</span>
|
|
<span class="k">elif</span> <span class="n">options</span><span class="o">.</span><span class="n">not_saved_to_library</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">syndicated</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">p</span><span class="o">.</span><span class="n">saved_to_library</span><span class="p">]</span>
|
|
|
|
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">function</span><span class="p">:</span>
|
|
<span class="k">for</span> <span class="n">function</span> <span class="ow">in</span> <span class="n">options</span><span class="o">.</span><span class="n">function</span><span class="p">:</span>
|
|
<span class="n">photos</span> <span class="o">=</span> <span class="n">function</span><span class="p">[</span><span class="mi">0</span><span class="p">](</span><span class="n">photos</span><span class="p">)</span>
|
|
|
|
<span class="c1"># burst should be checked last, ref #640</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">return</span> <span class="n">photos</span></div>
|
|
|
|
<div class="viewcode-block" id="PhotosDB.execute"><a class="viewcode-back" href="../../../reference.html#osxphotos.PhotosDB.execute">[docs]</a> <span class="k">def</span> <span class="nf">execute</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">sql</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">params</span><span class="p">:</span> <span class="n">Any</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">)</span> <span class="o">-></span> <span class="n">sqlite3</span><span class="o">.</span><span class="n">Cursor</span><span class="p">:</span>
|
|
<span class="sd">"""Execute sql statement and return cursor"""</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_db_connection</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_db_connection</span><span class="p">()</span>
|
|
<span class="n">params</span> <span class="o">=</span> <span class="n">params</span> <span class="ow">or</span> <span class="p">()</span>
|
|
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db_connection</span><span class="o">.</span><span class="n">cursor</span><span class="p">()</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="n">sql</span><span class="p">,</span> <span class="n">params</span><span class="p">)</span></div>
|
|
|
|
<span class="k">def</span> <span class="nf">_duplicate_signature</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">"""Compute a signature for finding possible duplicates"""</span>
|
|
<span class="k">return</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="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="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="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="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="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="p">)</span>
|
|
|
|
<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>
|
|
|
|
<span class="k">def</span> <span class="fm">__del__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s2">"_db_connection"</span><span class="p">,</span> <span class="kc">None</span><span class="p">):</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">_db_connection</span><span class="o">.</span><span class="n">close</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="nb">list</span><span class="p">(</span><span class="nb">set</span><span class="p">(</span><span class="n">photos_search</span><span class="p">))</span>
|
|
</pre></div>
|
|
</article>
|
|
</div>
|
|
<footer>
|
|
|
|
<div class="related-pages">
|
|
|
|
|
|
</div>
|
|
<div class="bottom-of-page">
|
|
<div class="left-details">
|
|
<div class="copyright">
|
|
Copyright © 2021, Rhet Turnbull
|
|
</div>
|
|
Made with <a href="https://www.sphinx-doc.org/">Sphinx</a> and <a class="muted-link" href="https://pradyunsg.me">@pradyunsg</a>'s
|
|
|
|
<a href="https://github.com/pradyunsg/furo">Furo</a>
|
|
|
|
</div>
|
|
<div class="right-details">
|
|
<div class="icons">
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</footer>
|
|
</div>
|
|
<aside class="toc-drawer no-toc">
|
|
|
|
|
|
|
|
</aside>
|
|
</div>
|
|
</div><script data-url_root="../../../" id="documentation_options" src="../../../_static/documentation_options.js"></script>
|
|
<script src="../../../_static/jquery.js"></script>
|
|
<script src="../../../_static/underscore.js"></script>
|
|
<script src="../../../_static/_sphinx_javascript_frameworks_compat.js"></script>
|
|
<script src="../../../_static/doctools.js"></script>
|
|
<script src="../../../_static/sphinx_highlight.js"></script>
|
|
<script src="../../../_static/scripts/furo.js"></script>
|
|
<script src="../../../_static/clipboard.min.js"></script>
|
|
<script src="../../../_static/copybutton.js"></script>
|
|
</body>
|
|
</html> |