Compare commits

...

8 Commits

Author SHA1 Message Date
Rhet Turnbull
9bc5890589 Added moment_info, #71 2022-05-03 22:12:09 -07:00
Rhet Turnbull
e9bbfeca52 Fixed metavars to be consistent, #645 2022-05-03 06:34:19 -07:00
Rhet Turnbull
f42bee84c0 Added --force to timewarp to bypass confirmation 2022-05-02 08:06:48 -07:00
Rhet Turnbull
ac67ef2384 Added confirmation for timewarp, #677 2022-05-02 07:54:39 -07:00
Rhet Turnbull
1ae4ec4851 Updated CHANGELOG.md [skip ci] 2022-05-01 22:32:29 -07:00
Rhet Turnbull
6070616717 Updated docs 2022-05-01 22:30:21 -07:00
Rhet Turnbull
70d3247e8c Feature timewarp function (#678)
* Added constraints, fixed themes for timewarp

* Updated progress to use rich_progress

* Added --function to timewarp, #676
2022-05-01 22:22:01 -07:00
Rhet Turnbull
25f35699d8 Updated CHANGELOG.md [skip ci] 2022-05-01 16:25:23 -07:00
46 changed files with 2891 additions and 1724 deletions

View File

@@ -1924,6 +1924,7 @@ cog.out(get_template_field_table())
|{exif.camera_make}|Camera make from original photo's EXIF information as imported by Photos, e.g. 'Apple'|
|{exif.camera_model}|Camera model from original photo's EXIF information as imported by Photos, e.g. 'iPhone 6s'|
|{exif.lens_model}|Lens model from original photo's EXIF information as imported by Photos, e.g. 'iPhone 6s back camera 4.15mm f/2.2'|
|{moment}|The moment title of the photo|
|{uuid}|Photo's internal universally unique identifier (UUID) for the photo, a 36-character string unique to the photo, e.g. '128FB4C6-0B16-4E7D-9108-FB2E90DA1546'|
|{id}|A unique number for the photo based on its primary key in the Photos database. A sequential integer, e.g. 1, 2, 3...etc. Each asset associated with a photo (e.g. an image and Live Photo preview) will share the same id. May be formatted using a python string format code. For example, to format as a 5-digit integer and pad with zeros, use '{id:05d}' which results in 00001, 00002, 00003...etc. |
|{album_seq}|An integer, starting at 0, indicating the photo's index (sequence) in the containing album. Only valid when used in a '--filename' template and only when '{album}' or '{folder_album}' is used in the '--directory' template. For example '--directory "{folder_album}" --filename "{album_seq}_{original_name}"'. To start counting at a value other than 0, append append a period and the starting value to the field name. For example, to start counting at 1 instead of 0: '{album_seq.1}'. May be formatted using a python string format code. For example, to format as a 5-digit integer and pad with zeros, use '{album_seq:05d}' which results in 00000, 00001, 00002...etc. This may result in incorrect sequences if you have duplicate albums with the same name; see also '{folder_album_seq}'.|
@@ -1942,7 +1943,7 @@ cog.out(get_template_field_table())
|{lf}|A line feed: '\n', alias for {newline}|
|{cr}|A carriage return: '\r'|
|{crlf}|a carriage return + line feed: '\r\n'|
|{osxphotos_version}|The osxphotos version, e.g. '0.48.0'|
|{osxphotos_version}|The osxphotos version, e.g. '0.48.2'|
|{osxphotos_cmd_line}|The full command line used to run osxphotos|
|{album}|Album(s) photo is contained in|
|{folder_album}|Folder path + album photo is contained in. e.g. 'Folder/Subfolder/Album' or just 'Album' if no enclosing folder|

View File

@@ -4,6 +4,21 @@ All notable changes to this project will be documented in this file. Dates are d
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
#### [v0.48.1](https://github.com/RhetTbull/osxphotos/compare/v0.48.0...v0.48.1)
> 1 May 2022
- Feature timewarp function [`#678`](https://github.com/RhetTbull/osxphotos/pull/678)
- Updated docs [`6070616`](https://github.com/RhetTbull/osxphotos/commit/60706167173f719d70e21193acef89f6252767e6)
#### [v0.48.0](https://github.com/RhetTbull/osxphotos/compare/v0.47.13...v0.48.0)
> 1 May 2022
- Feature timewarp [`#675`](https://github.com/RhetTbull/osxphotos/pull/675)
- Version bump [`d07aab5`](https://github.com/RhetTbull/osxphotos/commit/d07aab58d1b0ef8e8769740db089235bbc938a4e)
- Updated dependencies for rich_theme_manager [`8a3dc9b`](https://github.com/RhetTbull/osxphotos/commit/8a3dc9b3938f2363baba6dbf1f832ee55d57eb28)
#### [v0.47.13](https://github.com/RhetTbull/osxphotos/compare/v0.47.12...v0.47.13)
> 24 April 2022

905
README.md

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
# Sphinx build info version 1
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
config: 35181f6d3f1c86b23a5a5b12b47bc6b1
config: 80f83a536e4014ef4d71db9e7d4e82e8
tags: 645f666f9bcd5a90fca523b33c5a78b7

View File

@@ -5,7 +5,7 @@
<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-4.4.0, furo 2022.04.07"/>
<title>Overview: module code - osxphotos 0.48.0 documentation</title>
<title>Overview: module code - osxphotos 0.48.2 documentation</title>
<link rel="stylesheet" type="text/css" href="../_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="../_static/styles/furo.css?digest=68f4518137b9aefe99b631505a2064c3c42c9852" />
<link rel="stylesheet" type="text/css" href="../_static/copybutton.css" />
@@ -123,7 +123,7 @@
</label>
</div>
<div class="header-center">
<a href="../index.html"><div class="brand">osxphotos 0.48.0 documentation</div></a>
<a href="../index.html"><div class="brand">osxphotos 0.48.2 documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@@ -146,7 +146,7 @@
<div class="sidebar-sticky"><a class="sidebar-brand" href="../index.html">
<span class="sidebar-brand-text">osxphotos 0.48.0 documentation</span>
<span class="sidebar-brand-text">osxphotos 0.48.2 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">

View File

@@ -1,54 +1,217 @@
<!doctype html>
<html class="no-js">
<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" />
<!DOCTYPE html>
<meta name="generator" content="sphinx-4.4.0, furo 2022.04.07"/>
<title>osxphotos._constants - osxphotos 0.48.1 documentation</title>
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="../../_static/styles/furo.css?digest=68f4518137b9aefe99b631505a2064c3c42c9852" />
<link rel="stylesheet" type="text/css" href="../../_static/copybutton.css" />
<link rel="stylesheet" type="text/css" href="../../_static/styles/furo-extensions.css?digest=30d1aed668e5c3a91c3e3bf6a60b675221979f0e" />
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>osxphotos._constants &#8212; osxphotos 0.47.9 documentation</title>
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="../../_static/alabaster.css" />
<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/doctools.js"></script>
<link rel="index" title="Index" href="../../genindex.html" />
<link rel="search" title="Search" href="../../search.html" />
<link rel="stylesheet" href="../../_static/custom.css" type="text/css" />
<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.48.1 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">
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
</head><body>
<span class="sidebar-brand-text">osxphotos 0.48.1 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 API</a></li>
</ul>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
</div>
</div>
<div class="body" role="main">
<h1>Source code for osxphotos._constants</h1><div class="highlight"><pre>
<span></span><span class="sd">&quot;&quot;&quot;</span>
</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._constants</h1><div class="highlight"><pre>
<span></span><span class="sd">"""</span>
<span class="sd">Constants used by osxphotos </span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd">"""</span>
<span class="kn">import</span> <span class="nn">os.path</span>
<span class="kn">from</span> <span class="nn">datetime</span> <span class="kn">import</span> <span class="n">datetime</span>
<span class="kn">from</span> <span class="nn">enum</span> <span class="kn">import</span> <span class="n">Enum</span>
<span class="n">APP_NAME</span> <span class="o">=</span> <span class="s2">&quot;osxphotos&quot;</span>
<span class="n">APP_NAME</span> <span class="o">=</span> <span class="s2">"osxphotos"</span>
<span class="n">OSXPHOTOS_URL</span> <span class="o">=</span> <span class="s2">&quot;https://github.com/RhetTbull/osxphotos&quot;</span>
<span class="n">OSXPHOTOS_URL</span> <span class="o">=</span> <span class="s2">"https://github.com/RhetTbull/osxphotos"</span>
<span class="c1"># Time delta: add this to Photos times to get unix time</span>
<span class="c1"># Apple Epoch is Jan 1, 2001</span>
<span class="n">TIME_DELTA</span> <span class="o">=</span> <span class="p">(</span><span class="n">datetime</span><span class="p">(</span><span class="mi">2001</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="mi">0</span><span class="p">,</span> <span class="mi">0</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="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">))</span><span class="o">.</span><span class="n">total_seconds</span><span class="p">()</span>
<span class="c1"># Unicode format to use for comparing strings</span>
<span class="n">UNICODE_FORMAT</span> <span class="o">=</span> <span class="s2">&quot;NFC&quot;</span>
<span class="n">UNICODE_FORMAT</span> <span class="o">=</span> <span class="s2">"NFC"</span>
<span class="c1"># which Photos library database versions have been tested</span>
<span class="c1"># Photos 2.0 (10.12.6) == 2622</span>
@@ -56,23 +219,23 @@
<span class="c1"># Photos 4.0 (10.14.5) == 4016</span>
<span class="c1"># Photos 4.0 (10.14.6) == 4025</span>
<span class="c1"># Photos 5.0 (10.15.0) == 6000 or 5001</span>
<span class="n">_TESTED_DB_VERSIONS</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;6000&quot;</span><span class="p">,</span> <span class="s2">&quot;5001&quot;</span><span class="p">,</span> <span class="s2">&quot;4025&quot;</span><span class="p">,</span> <span class="s2">&quot;4016&quot;</span><span class="p">,</span> <span class="s2">&quot;3301&quot;</span><span class="p">,</span> <span class="s2">&quot;2622&quot;</span><span class="p">]</span>
<span class="n">_TESTED_DB_VERSIONS</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"6000"</span><span class="p">,</span> <span class="s2">"5001"</span><span class="p">,</span> <span class="s2">"4025"</span><span class="p">,</span> <span class="s2">"4016"</span><span class="p">,</span> <span class="s2">"3301"</span><span class="p">,</span> <span class="s2">"2622"</span><span class="p">]</span>
<span class="c1"># database model versions (applies to Photos 5, Photos 6)</span>
<span class="c1"># these come from PLModelVersion key in binary plist in Z_METADATA.Z_PLIST</span>
<span class="c1"># Photos 5 (10.15.1) == 13537</span>
<span class="c1"># Photos 5 (10.15.4, 10.15.5, 10.15.6) == 13703</span>
<span class="c1"># Photos 6 (10.16.0 Beta) == 14104</span>
<span class="n">_TEST_MODEL_VERSIONS</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;13537&quot;</span><span class="p">,</span> <span class="s2">&quot;13703&quot;</span><span class="p">,</span> <span class="s2">&quot;14104&quot;</span><span class="p">]</span>
<span class="n">_TEST_MODEL_VERSIONS</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"13537"</span><span class="p">,</span> <span class="s2">"13703"</span><span class="p">,</span> <span class="s2">"14104"</span><span class="p">]</span>
<span class="n">_PHOTOS_2_VERSION</span> <span class="o">=</span> <span class="s2">&quot;2622&quot;</span>
<span class="n">_PHOTOS_2_VERSION</span> <span class="o">=</span> <span class="s2">"2622"</span>
<span class="c1"># only version 3 - 4 have RKVersion.selfPortrait</span>
<span class="n">_PHOTOS_3_VERSION</span> <span class="o">=</span> <span class="s2">&quot;3301&quot;</span>
<span class="n">_PHOTOS_3_VERSION</span> <span class="o">=</span> <span class="s2">"3301"</span>
<span class="c1"># versions 5.0 and later have a different database structure</span>
<span class="n">_PHOTOS_4_VERSION</span> <span class="o">=</span> <span class="s2">&quot;4025&quot;</span> <span class="c1"># latest Mojove version on 10.14.6</span>
<span class="n">_PHOTOS_5_VERSION</span> <span class="o">=</span> <span class="s2">&quot;5000&quot;</span> <span class="c1"># I&#39;ve seen both 5001 and 6000. 6000 is most common on Catalina and up but there are some version 5001 database in the wild</span>
<span class="n">_PHOTOS_4_VERSION</span> <span class="o">=</span> <span class="s2">"4025"</span> <span class="c1"># latest Mojove version on 10.14.6</span>
<span class="n">_PHOTOS_5_VERSION</span> <span class="o">=</span> <span class="s2">"5000"</span> <span class="c1"># I've seen both 5001 and 6000. 6000 is most common on Catalina and up but there are some version 5001 database in the wild</span>
<span class="c1"># Ranges for model version by Photos version</span>
<span class="n">_PHOTOS_5_MODEL_VERSION</span> <span class="o">=</span> <span class="p">[</span><span class="mi">13000</span><span class="p">,</span> <span class="mi">13999</span><span class="p">]</span>
@@ -85,82 +248,82 @@
<span class="c1"># some table names differ between Photos 5 and Photos 6</span>
<span class="n">_DB_TABLE_NAMES</span> <span class="o">=</span> <span class="p">{</span>
<span class="mi">5</span><span class="p">:</span> <span class="p">{</span>
<span class="s2">&quot;ASSET&quot;</span><span class="p">:</span> <span class="s2">&quot;ZGENERICASSET&quot;</span><span class="p">,</span>
<span class="s2">&quot;KEYWORD_JOIN&quot;</span><span class="p">:</span> <span class="s2">&quot;Z_1KEYWORDS.Z_37KEYWORDS&quot;</span><span class="p">,</span>
<span class="s2">&quot;ALBUM_JOIN&quot;</span><span class="p">:</span> <span class="s2">&quot;Z_26ASSETS.Z_34ASSETS&quot;</span><span class="p">,</span>
<span class="s2">&quot;ALBUM_SORT_ORDER&quot;</span><span class="p">:</span> <span class="s2">&quot;Z_26ASSETS.Z_FOK_34ASSETS&quot;</span><span class="p">,</span>
<span class="s2">&quot;IMPORT_FOK&quot;</span><span class="p">:</span> <span class="s2">&quot;ZGENERICASSET.Z_FOK_IMPORTSESSION&quot;</span><span class="p">,</span>
<span class="s2">&quot;DEPTH_STATE&quot;</span><span class="p">:</span> <span class="s2">&quot;ZGENERICASSET.ZDEPTHSTATES&quot;</span><span class="p">,</span>
<span class="s2">&quot;UTI_ORIGINAL&quot;</span><span class="p">:</span> <span class="s2">&quot;ZINTERNALRESOURCE.ZUNIFORMTYPEIDENTIFIER&quot;</span><span class="p">,</span>
<span class="s2">&quot;ASSET_ALBUM_JOIN&quot;</span><span class="p">:</span> <span class="s2">&quot;Z_26ASSETS.Z_26ALBUMS&quot;</span><span class="p">,</span>
<span class="s2">&quot;ASSET_ALBUM_TABLE&quot;</span><span class="p">:</span> <span class="s2">&quot;Z_26ASSETS&quot;</span><span class="p">,</span>
<span class="s2">&quot;HDR_TYPE&quot;</span><span class="p">:</span> <span class="s2">&quot;ZCUSTOMRENDEREDVALUE&quot;</span><span class="p">,</span>
<span class="s2">"ASSET"</span><span class="p">:</span> <span class="s2">"ZGENERICASSET"</span><span class="p">,</span>
<span class="s2">"KEYWORD_JOIN"</span><span class="p">:</span> <span class="s2">"Z_1KEYWORDS.Z_37KEYWORDS"</span><span class="p">,</span>
<span class="s2">"ALBUM_JOIN"</span><span class="p">:</span> <span class="s2">"Z_26ASSETS.Z_34ASSETS"</span><span class="p">,</span>
<span class="s2">"ALBUM_SORT_ORDER"</span><span class="p">:</span> <span class="s2">"Z_26ASSETS.Z_FOK_34ASSETS"</span><span class="p">,</span>
<span class="s2">"IMPORT_FOK"</span><span class="p">:</span> <span class="s2">"ZGENERICASSET.Z_FOK_IMPORTSESSION"</span><span class="p">,</span>
<span class="s2">"DEPTH_STATE"</span><span class="p">:</span> <span class="s2">"ZGENERICASSET.ZDEPTHSTATES"</span><span class="p">,</span>
<span class="s2">"UTI_ORIGINAL"</span><span class="p">:</span> <span class="s2">"ZINTERNALRESOURCE.ZUNIFORMTYPEIDENTIFIER"</span><span class="p">,</span>
<span class="s2">"ASSET_ALBUM_JOIN"</span><span class="p">:</span> <span class="s2">"Z_26ASSETS.Z_26ALBUMS"</span><span class="p">,</span>
<span class="s2">"ASSET_ALBUM_TABLE"</span><span class="p">:</span> <span class="s2">"Z_26ASSETS"</span><span class="p">,</span>
<span class="s2">"HDR_TYPE"</span><span class="p">:</span> <span class="s2">"ZCUSTOMRENDEREDVALUE"</span><span class="p">,</span>
<span class="p">},</span>
<span class="mi">6</span><span class="p">:</span> <span class="p">{</span>
<span class="s2">&quot;ASSET&quot;</span><span class="p">:</span> <span class="s2">&quot;ZASSET&quot;</span><span class="p">,</span>
<span class="s2">&quot;KEYWORD_JOIN&quot;</span><span class="p">:</span> <span class="s2">&quot;Z_1KEYWORDS.Z_36KEYWORDS&quot;</span><span class="p">,</span>
<span class="s2">&quot;ALBUM_JOIN&quot;</span><span class="p">:</span> <span class="s2">&quot;Z_26ASSETS.Z_3ASSETS&quot;</span><span class="p">,</span>
<span class="s2">&quot;ALBUM_SORT_ORDER&quot;</span><span class="p">:</span> <span class="s2">&quot;Z_26ASSETS.Z_FOK_3ASSETS&quot;</span><span class="p">,</span>
<span class="s2">&quot;IMPORT_FOK&quot;</span><span class="p">:</span> <span class="s2">&quot;null&quot;</span><span class="p">,</span>
<span class="s2">&quot;DEPTH_STATE&quot;</span><span class="p">:</span> <span class="s2">&quot;ZASSET.ZDEPTHTYPE&quot;</span><span class="p">,</span>
<span class="s2">&quot;UTI_ORIGINAL&quot;</span><span class="p">:</span> <span class="s2">&quot;ZINTERNALRESOURCE.ZUNIFORMTYPEIDENTIFIER&quot;</span><span class="p">,</span>
<span class="s2">&quot;ASSET_ALBUM_JOIN&quot;</span><span class="p">:</span> <span class="s2">&quot;Z_26ASSETS.Z_26ALBUMS&quot;</span><span class="p">,</span>
<span class="s2">&quot;ASSET_ALBUM_TABLE&quot;</span><span class="p">:</span> <span class="s2">&quot;Z_26ASSETS&quot;</span><span class="p">,</span>
<span class="s2">&quot;HDR_TYPE&quot;</span><span class="p">:</span> <span class="s2">&quot;ZCUSTOMRENDEREDVALUE&quot;</span><span class="p">,</span>
<span class="s2">"ASSET"</span><span class="p">:</span> <span class="s2">"ZASSET"</span><span class="p">,</span>
<span class="s2">"KEYWORD_JOIN"</span><span class="p">:</span> <span class="s2">"Z_1KEYWORDS.Z_36KEYWORDS"</span><span class="p">,</span>
<span class="s2">"ALBUM_JOIN"</span><span class="p">:</span> <span class="s2">"Z_26ASSETS.Z_3ASSETS"</span><span class="p">,</span>
<span class="s2">"ALBUM_SORT_ORDER"</span><span class="p">:</span> <span class="s2">"Z_26ASSETS.Z_FOK_3ASSETS"</span><span class="p">,</span>
<span class="s2">"IMPORT_FOK"</span><span class="p">:</span> <span class="s2">"null"</span><span class="p">,</span>
<span class="s2">"DEPTH_STATE"</span><span class="p">:</span> <span class="s2">"ZASSET.ZDEPTHTYPE"</span><span class="p">,</span>
<span class="s2">"UTI_ORIGINAL"</span><span class="p">:</span> <span class="s2">"ZINTERNALRESOURCE.ZUNIFORMTYPEIDENTIFIER"</span><span class="p">,</span>
<span class="s2">"ASSET_ALBUM_JOIN"</span><span class="p">:</span> <span class="s2">"Z_26ASSETS.Z_26ALBUMS"</span><span class="p">,</span>
<span class="s2">"ASSET_ALBUM_TABLE"</span><span class="p">:</span> <span class="s2">"Z_26ASSETS"</span><span class="p">,</span>
<span class="s2">"HDR_TYPE"</span><span class="p">:</span> <span class="s2">"ZCUSTOMRENDEREDVALUE"</span><span class="p">,</span>
<span class="p">},</span>
<span class="mi">7</span><span class="p">:</span> <span class="p">{</span>
<span class="s2">&quot;ASSET&quot;</span><span class="p">:</span> <span class="s2">&quot;ZASSET&quot;</span><span class="p">,</span>
<span class="s2">&quot;KEYWORD_JOIN&quot;</span><span class="p">:</span> <span class="s2">&quot;Z_1KEYWORDS.Z_38KEYWORDS&quot;</span><span class="p">,</span>
<span class="s2">&quot;ALBUM_JOIN&quot;</span><span class="p">:</span> <span class="s2">&quot;Z_27ASSETS.Z_3ASSETS&quot;</span><span class="p">,</span>
<span class="s2">&quot;ALBUM_SORT_ORDER&quot;</span><span class="p">:</span> <span class="s2">&quot;Z_27ASSETS.Z_FOK_3ASSETS&quot;</span><span class="p">,</span>
<span class="s2">&quot;IMPORT_FOK&quot;</span><span class="p">:</span> <span class="s2">&quot;null&quot;</span><span class="p">,</span>
<span class="s2">&quot;DEPTH_STATE&quot;</span><span class="p">:</span> <span class="s2">&quot;ZASSET.ZDEPTHTYPE&quot;</span><span class="p">,</span>
<span class="s2">&quot;UTI_ORIGINAL&quot;</span><span class="p">:</span> <span class="s2">&quot;ZINTERNALRESOURCE.ZCOMPACTUTI&quot;</span><span class="p">,</span>
<span class="s2">&quot;ASSET_ALBUM_JOIN&quot;</span><span class="p">:</span> <span class="s2">&quot;Z_27ASSETS.Z_27ALBUMS&quot;</span><span class="p">,</span>
<span class="s2">&quot;ASSET_ALBUM_TABLE&quot;</span><span class="p">:</span> <span class="s2">&quot;Z_27ASSETS&quot;</span><span class="p">,</span>
<span class="s2">&quot;HDR_TYPE&quot;</span><span class="p">:</span> <span class="s2">&quot;ZHDRTYPE&quot;</span><span class="p">,</span>
<span class="s2">"ASSET"</span><span class="p">:</span> <span class="s2">"ZASSET"</span><span class="p">,</span>
<span class="s2">"KEYWORD_JOIN"</span><span class="p">:</span> <span class="s2">"Z_1KEYWORDS.Z_38KEYWORDS"</span><span class="p">,</span>
<span class="s2">"ALBUM_JOIN"</span><span class="p">:</span> <span class="s2">"Z_27ASSETS.Z_3ASSETS"</span><span class="p">,</span>
<span class="s2">"ALBUM_SORT_ORDER"</span><span class="p">:</span> <span class="s2">"Z_27ASSETS.Z_FOK_3ASSETS"</span><span class="p">,</span>
<span class="s2">"IMPORT_FOK"</span><span class="p">:</span> <span class="s2">"null"</span><span class="p">,</span>
<span class="s2">"DEPTH_STATE"</span><span class="p">:</span> <span class="s2">"ZASSET.ZDEPTHTYPE"</span><span class="p">,</span>
<span class="s2">"UTI_ORIGINAL"</span><span class="p">:</span> <span class="s2">"ZINTERNALRESOURCE.ZCOMPACTUTI"</span><span class="p">,</span>
<span class="s2">"ASSET_ALBUM_JOIN"</span><span class="p">:</span> <span class="s2">"Z_27ASSETS.Z_27ALBUMS"</span><span class="p">,</span>
<span class="s2">"ASSET_ALBUM_TABLE"</span><span class="p">:</span> <span class="s2">"Z_27ASSETS"</span><span class="p">,</span>
<span class="s2">"HDR_TYPE"</span><span class="p">:</span> <span class="s2">"ZHDRTYPE"</span><span class="p">,</span>
<span class="p">},</span>
<span class="p">}</span>
<span class="c1"># which version operating systems have been tested</span>
<span class="n">_TESTED_OS_VERSIONS</span> <span class="o">=</span> <span class="p">[</span>
<span class="p">(</span><span class="s2">&quot;10&quot;</span><span class="p">,</span> <span class="s2">&quot;12&quot;</span><span class="p">),</span>
<span class="p">(</span><span class="s2">&quot;10&quot;</span><span class="p">,</span> <span class="s2">&quot;13&quot;</span><span class="p">),</span>
<span class="p">(</span><span class="s2">&quot;10&quot;</span><span class="p">,</span> <span class="s2">&quot;14&quot;</span><span class="p">),</span>
<span class="p">(</span><span class="s2">&quot;10&quot;</span><span class="p">,</span> <span class="s2">&quot;15&quot;</span><span class="p">),</span>
<span class="p">(</span><span class="s2">&quot;10&quot;</span><span class="p">,</span> <span class="s2">&quot;16&quot;</span><span class="p">),</span>
<span class="p">(</span><span class="s2">&quot;11&quot;</span><span class="p">,</span> <span class="s2">&quot;0&quot;</span><span class="p">),</span>
<span class="p">(</span><span class="s2">&quot;11&quot;</span><span class="p">,</span> <span class="s2">&quot;1&quot;</span><span class="p">),</span>
<span class="p">(</span><span class="s2">&quot;11&quot;</span><span class="p">,</span> <span class="s2">&quot;2&quot;</span><span class="p">),</span>
<span class="p">(</span><span class="s2">&quot;11&quot;</span><span class="p">,</span> <span class="s2">&quot;3&quot;</span><span class="p">),</span>
<span class="p">(</span><span class="s2">&quot;11&quot;</span><span class="p">,</span> <span class="s2">&quot;4&quot;</span><span class="p">),</span>
<span class="p">(</span><span class="s2">&quot;11&quot;</span><span class="p">,</span> <span class="s2">&quot;5&quot;</span><span class="p">),</span>
<span class="p">(</span><span class="s2">&quot;11&quot;</span><span class="p">,</span> <span class="s2">&quot;6&quot;</span><span class="p">),</span>
<span class="p">(</span><span class="s2">&quot;12&quot;</span><span class="p">,</span> <span class="s2">&quot;0&quot;</span><span class="p">),</span>
<span class="p">(</span><span class="s2">&quot;12&quot;</span><span class="p">,</span> <span class="s2">&quot;1&quot;</span><span class="p">),</span>
<span class="p">(</span><span class="s2">&quot;12&quot;</span><span class="p">,</span> <span class="s2">&quot;2&quot;</span><span class="p">),</span>
<span class="p">(</span><span class="s2">&quot;12&quot;</span><span class="p">,</span> <span class="s2">&quot;3&quot;</span><span class="p">),</span>
<span class="p">(</span><span class="s2">"10"</span><span class="p">,</span> <span class="s2">"12"</span><span class="p">),</span>
<span class="p">(</span><span class="s2">"10"</span><span class="p">,</span> <span class="s2">"13"</span><span class="p">),</span>
<span class="p">(</span><span class="s2">"10"</span><span class="p">,</span> <span class="s2">"14"</span><span class="p">),</span>
<span class="p">(</span><span class="s2">"10"</span><span class="p">,</span> <span class="s2">"15"</span><span class="p">),</span>
<span class="p">(</span><span class="s2">"10"</span><span class="p">,</span> <span class="s2">"16"</span><span class="p">),</span>
<span class="p">(</span><span class="s2">"11"</span><span class="p">,</span> <span class="s2">"0"</span><span class="p">),</span>
<span class="p">(</span><span class="s2">"11"</span><span class="p">,</span> <span class="s2">"1"</span><span class="p">),</span>
<span class="p">(</span><span class="s2">"11"</span><span class="p">,</span> <span class="s2">"2"</span><span class="p">),</span>
<span class="p">(</span><span class="s2">"11"</span><span class="p">,</span> <span class="s2">"3"</span><span class="p">),</span>
<span class="p">(</span><span class="s2">"11"</span><span class="p">,</span> <span class="s2">"4"</span><span class="p">),</span>
<span class="p">(</span><span class="s2">"11"</span><span class="p">,</span> <span class="s2">"5"</span><span class="p">),</span>
<span class="p">(</span><span class="s2">"11"</span><span class="p">,</span> <span class="s2">"6"</span><span class="p">),</span>
<span class="p">(</span><span class="s2">"12"</span><span class="p">,</span> <span class="s2">"0"</span><span class="p">),</span>
<span class="p">(</span><span class="s2">"12"</span><span class="p">,</span> <span class="s2">"1"</span><span class="p">),</span>
<span class="p">(</span><span class="s2">"12"</span><span class="p">,</span> <span class="s2">"2"</span><span class="p">),</span>
<span class="p">(</span><span class="s2">"12"</span><span class="p">,</span> <span class="s2">"3"</span><span class="p">),</span>
<span class="p">]</span>
<span class="c1"># Photos 5 has persons who are empty string if unidentified face</span>
<span class="n">_UNKNOWN_PERSON</span> <span class="o">=</span> <span class="s2">&quot;_UNKNOWN_&quot;</span>
<span class="n">_UNKNOWN_PERSON</span> <span class="o">=</span> <span class="s2">"_UNKNOWN_"</span>
<span class="c1"># photos with no reverse geolocation info (place)</span>
<span class="n">_UNKNOWN_PLACE</span> <span class="o">=</span> <span class="s2">&quot;_UNKNOWN_&quot;</span>
<span class="n">_UNKNOWN_PLACE</span> <span class="o">=</span> <span class="s2">"_UNKNOWN_"</span>
<span class="n">_EXIF_TOOL_URL</span> <span class="o">=</span> <span class="s2">&quot;https://exiftool.org/&quot;</span>
<span class="n">_EXIF_TOOL_URL</span> <span class="o">=</span> <span class="s2">"https://exiftool.org/"</span>
<span class="c1"># Where are shared iCloud photos located?</span>
<span class="n">_PHOTOS_5_SHARED_PHOTO_PATH</span> <span class="o">=</span> <span class="s2">&quot;resources/cloudsharing/data&quot;</span>
<span class="n">_PHOTOS_5_SHARED_PHOTO_PATH</span> <span class="o">=</span> <span class="s2">"resources/cloudsharing/data"</span>
<span class="c1"># What type of file? Based on ZGENERICASSET.ZKIND in Photos 5 database</span>
<span class="n">_PHOTO_TYPE</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">_MOVIE_TYPE</span> <span class="o">=</span> <span class="mi">1</span>
<span class="c1"># Name of XMP template file</span>
<span class="n">_TEMPLATE_DIR</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">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="vm">__file__</span><span class="p">),</span> <span class="s2">&quot;templates&quot;</span><span class="p">)</span>
<span class="n">_XMP_TEMPLATE_NAME</span> <span class="o">=</span> <span class="s2">&quot;xmp_sidecar.mako&quot;</span>
<span class="n">_XMP_TEMPLATE_NAME_BETA</span> <span class="o">=</span> <span class="s2">&quot;xmp_sidecar_beta.mako&quot;</span>
<span class="n">_TEMPLATE_DIR</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">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="vm">__file__</span><span class="p">),</span> <span class="s2">"templates"</span><span class="p">)</span>
<span class="n">_XMP_TEMPLATE_NAME</span> <span class="o">=</span> <span class="s2">"xmp_sidecar.mako"</span>
<span class="n">_XMP_TEMPLATE_NAME_BETA</span> <span class="o">=</span> <span class="s2">"xmp_sidecar_beta.mako"</span>
<span class="c1"># Constants used for processing folders and albums</span>
<span class="n">_PHOTOS_5_ALBUM_KIND</span> <span class="o">=</span> <span class="mi">2</span> <span class="c1"># normal user album</span>
@@ -175,20 +338,20 @@
<span class="n">_PHOTOS_4_ALBUM_TYPE_PROJECT</span> <span class="o">=</span> <span class="mi">9</span> <span class="c1"># RKAlbum.albumType</span>
<span class="n">_PHOTOS_4_ALBUM_TYPE_SLIDESHOW</span> <span class="o">=</span> <span class="mi">8</span> <span class="c1"># RKAlbum.albumType</span>
<span class="n">_PHOTOS_4_TOP_LEVEL_ALBUMS</span> <span class="o">=</span> <span class="p">[</span>
<span class="s2">&quot;TopLevelAlbums&quot;</span><span class="p">,</span>
<span class="s2">&quot;TopLevelKeepsakes&quot;</span><span class="p">,</span>
<span class="s2">&quot;TopLevelSlideshows&quot;</span><span class="p">,</span>
<span class="s2">"TopLevelAlbums"</span><span class="p">,</span>
<span class="s2">"TopLevelKeepsakes"</span><span class="p">,</span>
<span class="s2">"TopLevelSlideshows"</span><span class="p">,</span>
<span class="p">]</span>
<span class="n">_PHOTOS_4_ROOT_FOLDER</span> <span class="o">=</span> <span class="s2">&quot;LibraryFolder&quot;</span>
<span class="n">_PHOTOS_4_ROOT_FOLDER</span> <span class="o">=</span> <span class="s2">"LibraryFolder"</span>
<span class="c1"># EXIF related constants</span>
<span class="c1"># max keyword length for IPTC:Keyword, reference</span>
<span class="c1"># https://www.iptc.org/std/photometadata/documentation/userguide/</span>
<span class="n">_MAX_IPTC_KEYWORD_LEN</span> <span class="o">=</span> <span class="mi">64</span>
<span class="c1"># Sentinel value for detecting if a template in keyword_template doesn&#39;t match</span>
<span class="c1"># Sentinel value for detecting if a template in keyword_template doesn't match</span>
<span class="c1"># If anyone has a keyword matching this, then too bad...</span>
<span class="n">_OSXPHOTOS_NONE_SENTINEL</span> <span class="o">=</span> <span class="s2">&quot;OSXPhotosXYZZY42_Sentinel$&quot;</span>
<span class="n">_OSXPHOTOS_NONE_SENTINEL</span> <span class="o">=</span> <span class="s2">"OSXPhotosXYZZY42_Sentinel$"</span>
<span class="c1"># SearchInfo categories for Photos 5, corresponds to categories in database/search/psi.sqlite</span>
<span class="n">SEARCH_CATEGORY_LABEL</span> <span class="o">=</span> <span class="mi">2024</span>
@@ -260,13 +423,13 @@
<span class="n">DEFAULT_JPEG_QUALITY</span> <span class="o">=</span> <span class="mf">1.0</span>
<span class="c1"># Default suffix to add to edited images</span>
<span class="n">DEFAULT_EDITED_SUFFIX</span> <span class="o">=</span> <span class="s2">&quot;_edited&quot;</span>
<span class="n">DEFAULT_EDITED_SUFFIX</span> <span class="o">=</span> <span class="s2">"_edited"</span>
<span class="c1"># Default suffix to add to original images</span>
<span class="n">DEFAULT_ORIGINAL_SUFFIX</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="n">DEFAULT_ORIGINAL_SUFFIX</span> <span class="o">=</span> <span class="s2">""</span>
<span class="c1"># Default suffix to add to preview images</span>
<span class="n">DEFAULT_PREVIEW_SUFFIX</span> <span class="o">=</span> <span class="s2">&quot;_preview&quot;</span>
<span class="n">DEFAULT_PREVIEW_SUFFIX</span> <span class="o">=</span> <span class="s2">"_preview"</span>
<span class="c1"># Bit masks for --sidecar</span>
<span class="n">SIDECAR_JSON</span> <span class="o">=</span> <span class="mh">0x1</span>
@@ -275,28 +438,28 @@
<span class="c1"># supported attributes for --xattr-template</span>
<span class="n">EXTENDED_ATTRIBUTE_NAMES</span> <span class="o">=</span> <span class="p">[</span>
<span class="s2">&quot;authors&quot;</span><span class="p">,</span>
<span class="s2">&quot;comment&quot;</span><span class="p">,</span>
<span class="s2">&quot;copyright&quot;</span><span class="p">,</span>
<span class="s2">&quot;creator&quot;</span><span class="p">,</span>
<span class="s2">&quot;description&quot;</span><span class="p">,</span>
<span class="s2">&quot;findercomment&quot;</span><span class="p">,</span>
<span class="s2">&quot;headline&quot;</span><span class="p">,</span>
<span class="s2">&quot;keywords&quot;</span><span class="p">,</span>
<span class="s2">&quot;participants&quot;</span><span class="p">,</span>
<span class="s2">&quot;projects&quot;</span><span class="p">,</span>
<span class="s2">&quot;rating&quot;</span><span class="p">,</span>
<span class="s2">&quot;subject&quot;</span><span class="p">,</span>
<span class="s2">&quot;title&quot;</span><span class="p">,</span>
<span class="s2">&quot;version&quot;</span><span class="p">,</span>
<span class="s2">"authors"</span><span class="p">,</span>
<span class="s2">"comment"</span><span class="p">,</span>
<span class="s2">"copyright"</span><span class="p">,</span>
<span class="s2">"creator"</span><span class="p">,</span>
<span class="s2">"description"</span><span class="p">,</span>
<span class="s2">"findercomment"</span><span class="p">,</span>
<span class="s2">"headline"</span><span class="p">,</span>
<span class="s2">"keywords"</span><span class="p">,</span>
<span class="s2">"participants"</span><span class="p">,</span>
<span class="s2">"projects"</span><span class="p">,</span>
<span class="s2">"rating"</span><span class="p">,</span>
<span class="s2">"subject"</span><span class="p">,</span>
<span class="s2">"title"</span><span class="p">,</span>
<span class="s2">"version"</span><span class="p">,</span>
<span class="p">]</span>
<span class="n">EXTENDED_ATTRIBUTE_NAMES_QUOTED</span> <span class="o">=</span> <span class="p">[</span><span class="sa">f</span><span class="s2">&quot;&#39;</span><span class="si">{</span><span class="n">x</span><span class="si">}</span><span class="s2">&#39;&quot;</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">EXTENDED_ATTRIBUTE_NAMES</span><span class="p">]</span>
<span class="n">EXTENDED_ATTRIBUTE_NAMES_QUOTED</span> <span class="o">=</span> <span class="p">[</span><span class="sa">f</span><span class="s2">"'</span><span class="si">{</span><span class="n">x</span><span class="si">}</span><span class="s2">'"</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">EXTENDED_ATTRIBUTE_NAMES</span><span class="p">]</span>
<span class="c1"># name of export DB</span>
<span class="n">OSXPHOTOS_EXPORT_DB</span> <span class="o">=</span> <span class="s2">&quot;.osxphotos_export.db&quot;</span>
<span class="n">OSXPHOTOS_EXPORT_DB</span> <span class="o">=</span> <span class="s2">".osxphotos_export.db"</span>
<span class="c1"># bit flags for burst images (&quot;burstPickType&quot;)</span>
<span class="c1"># bit flags for burst images ("burstPickType")</span>
<span class="n">BURST_PICK_TYPE_NONE</span> <span class="o">=</span> <span class="mb">0b0</span> <span class="c1"># 0: sometimes used for single images with a burst UUID</span>
<span class="n">BURST_NOT_SELECTED</span> <span class="o">=</span> <span class="mb">0b10</span> <span class="c1"># 2: burst image is not selected</span>
<span class="n">BURST_DEFAULT_PICK</span> <span class="o">=</span> <span class="mb">0b100</span> <span class="c1"># 4: burst image is the one Photos picked to be key image before any selections made</span>
@@ -304,32 +467,32 @@
<span class="n">BURST_KEY</span> <span class="o">=</span> <span class="mb">0b10000</span> <span class="c1"># 16: burst image is the key photo (top of burst stack)</span>
<span class="n">BURST_UNKNOWN</span> <span class="o">=</span> <span class="mb">0b100000</span> <span class="c1"># 32: this is almost always set with BURST_DEFAULT_PICK and never if BURST_DEFAULT_PICK is not set. I think this has something to do with what algorithm Photos used to pick the default image</span>
<span class="n">LIVE_VIDEO_EXTENSIONS</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;.mov&quot;</span><span class="p">]</span>
<span class="n">LIVE_VIDEO_EXTENSIONS</span> <span class="o">=</span> <span class="p">[</span><span class="s2">".mov"</span><span class="p">]</span>
<span class="c1"># categories that --post-command can be used with; these map to ExportResults fields</span>
<span class="n">POST_COMMAND_CATEGORIES</span> <span class="o">=</span> <span class="p">{</span>
<span class="s2">&quot;exported&quot;</span><span class="p">:</span> <span class="s2">&quot;All exported files&quot;</span><span class="p">,</span>
<span class="s2">&quot;new&quot;</span><span class="p">:</span> <span class="s2">&quot;When used with &#39;--update&#39;, all newly exported files&quot;</span><span class="p">,</span>
<span class="s2">&quot;updated&quot;</span><span class="p">:</span> <span class="s2">&quot;When used with &#39;--update&#39;, all files which were previously exported but updated this time&quot;</span><span class="p">,</span>
<span class="s2">&quot;skipped&quot;</span><span class="p">:</span> <span class="s2">&quot;When used with &#39;--update&#39;, all files which were skipped (because they were previously exported and didn&#39;t change)&quot;</span><span class="p">,</span>
<span class="s2">&quot;missing&quot;</span><span class="p">:</span> <span class="s2">&quot;All files which were not exported because they were missing from the Photos library&quot;</span><span class="p">,</span>
<span class="s2">&quot;exif_updated&quot;</span><span class="p">:</span> <span class="s2">&quot;When used with &#39;--exiftool&#39;, all files on which exiftool updated the metadata&quot;</span><span class="p">,</span>
<span class="s2">&quot;touched&quot;</span><span class="p">:</span> <span class="s2">&quot;When used with &#39;--touch-file&#39;, all files where the date was touched&quot;</span><span class="p">,</span>
<span class="s2">&quot;converted_to_jpeg&quot;</span><span class="p">:</span> <span class="s2">&quot;When used with &#39;--convert-to-jpeg&#39;, all files which were converted to jpeg&quot;</span><span class="p">,</span>
<span class="s2">&quot;sidecar_json_written&quot;</span><span class="p">:</span> <span class="s2">&quot;When used with &#39;--sidecar json&#39;, all JSON sidecar files which were written&quot;</span><span class="p">,</span>
<span class="s2">&quot;sidecar_json_skipped&quot;</span><span class="p">:</span> <span class="s2">&quot;When used with &#39;--sidecar json&#39; and &#39;--update&#39;, all JSON sidecar files which were skipped&quot;</span><span class="p">,</span>
<span class="s2">&quot;sidecar_exiftool_written&quot;</span><span class="p">:</span> <span class="s2">&quot;When used with &#39;--sidecar exiftool&#39;, all exiftool sidecar files which were written&quot;</span><span class="p">,</span>
<span class="s2">&quot;sidecar_exiftool_skipped&quot;</span><span class="p">:</span> <span class="s2">&quot;When used with &#39;--sidecar exiftool&#39; and &#39;--update, all exiftool sidecar files which were skipped&quot;</span><span class="p">,</span>
<span class="s2">&quot;sidecar_xmp_written&quot;</span><span class="p">:</span> <span class="s2">&quot;When used with &#39;--sidecar xmp&#39;, all XMP sidecar files which were written&quot;</span><span class="p">,</span>
<span class="s2">&quot;sidecar_xmp_skipped&quot;</span><span class="p">:</span> <span class="s2">&quot;When used with &#39;--sidecar xmp&#39; and &#39;--update&#39;, all XMP sidecar files which were skipped&quot;</span><span class="p">,</span>
<span class="s2">&quot;error&quot;</span><span class="p">:</span> <span class="s2">&quot;All files which produced an error during export&quot;</span><span class="p">,</span>
<span class="c1"># &quot;deleted_files&quot;: &quot;When used with &#39;--cleanup&#39;, all files deleted during the export&quot;,</span>
<span class="c1"># &quot;deleted_directories&quot;: &quot;When used with &#39;--cleanup&#39;, all directories deleted during the export&quot;,</span>
<span class="s2">"exported"</span><span class="p">:</span> <span class="s2">"All exported files"</span><span class="p">,</span>
<span class="s2">"new"</span><span class="p">:</span> <span class="s2">"When used with '--update', all newly exported files"</span><span class="p">,</span>
<span class="s2">"updated"</span><span class="p">:</span> <span class="s2">"When used with '--update', all files which were previously exported but updated this time"</span><span class="p">,</span>
<span class="s2">"skipped"</span><span class="p">:</span> <span class="s2">"When used with '--update', all files which were skipped (because they were previously exported and didn't change)"</span><span class="p">,</span>
<span class="s2">"missing"</span><span class="p">:</span> <span class="s2">"All files which were not exported because they were missing from the Photos library"</span><span class="p">,</span>
<span class="s2">"exif_updated"</span><span class="p">:</span> <span class="s2">"When used with '--exiftool', all files on which exiftool updated the metadata"</span><span class="p">,</span>
<span class="s2">"touched"</span><span class="p">:</span> <span class="s2">"When used with '--touch-file', all files where the date was touched"</span><span class="p">,</span>
<span class="s2">"converted_to_jpeg"</span><span class="p">:</span> <span class="s2">"When used with '--convert-to-jpeg', all files which were converted to jpeg"</span><span class="p">,</span>
<span class="s2">"sidecar_json_written"</span><span class="p">:</span> <span class="s2">"When used with '--sidecar json', all JSON sidecar files which were written"</span><span class="p">,</span>
<span class="s2">"sidecar_json_skipped"</span><span class="p">:</span> <span class="s2">"When used with '--sidecar json' and '--update', all JSON sidecar files which were skipped"</span><span class="p">,</span>
<span class="s2">"sidecar_exiftool_written"</span><span class="p">:</span> <span class="s2">"When used with '--sidecar exiftool', all exiftool sidecar files which were written"</span><span class="p">,</span>
<span class="s2">"sidecar_exiftool_skipped"</span><span class="p">:</span> <span class="s2">"When used with '--sidecar exiftool' and '--update, all exiftool sidecar files which were skipped"</span><span class="p">,</span>
<span class="s2">"sidecar_xmp_written"</span><span class="p">:</span> <span class="s2">"When used with '--sidecar xmp', all XMP sidecar files which were written"</span><span class="p">,</span>
<span class="s2">"sidecar_xmp_skipped"</span><span class="p">:</span> <span class="s2">"When used with '--sidecar xmp' and '--update', all XMP sidecar files which were skipped"</span><span class="p">,</span>
<span class="s2">"error"</span><span class="p">:</span> <span class="s2">"All files which produced an error during export"</span><span class="p">,</span>
<span class="c1"># "deleted_files": "When used with '--cleanup', all files deleted during the export",</span>
<span class="c1"># "deleted_directories": "When used with '--cleanup', all directories deleted during the export",</span>
<span class="p">}</span>
<div class="viewcode-block" id="AlbumSortOrder"><a class="viewcode-back" href="../../reference.html#osxphotos.AlbumSortOrder">[docs]</a><span class="k">class</span> <span class="nc">AlbumSortOrder</span><span class="p">(</span><span class="n">Enum</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Album Sort Order&quot;&quot;&quot;</span>
<span class="sd">"""Album Sort Order"""</span>
<span class="n">UNKNOWN</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">MANUAL</span> <span class="o">=</span> <span class="mi">1</span>
@@ -342,88 +505,61 @@
<span class="c1"># stat sort order for cProfile: https://docs.python.org/3/library/profile.html#pstats.Stats.sort_stats</span>
<span class="n">PROFILE_SORT_KEYS</span> <span class="o">=</span> <span class="p">[</span>
<span class="s2">&quot;calls&quot;</span><span class="p">,</span>
<span class="s2">&quot;cumulative&quot;</span><span class="p">,</span>
<span class="s2">&quot;cumtime&quot;</span><span class="p">,</span>
<span class="s2">&quot;file&quot;</span><span class="p">,</span>
<span class="s2">&quot;filename&quot;</span><span class="p">,</span>
<span class="s2">&quot;module&quot;</span><span class="p">,</span>
<span class="s2">&quot;ncalls&quot;</span><span class="p">,</span>
<span class="s2">&quot;pcalls&quot;</span><span class="p">,</span>
<span class="s2">&quot;line&quot;</span><span class="p">,</span>
<span class="s2">&quot;name&quot;</span><span class="p">,</span>
<span class="s2">&quot;nfl&quot;</span><span class="p">,</span>
<span class="s2">&quot;stdname&quot;</span><span class="p">,</span>
<span class="s2">&quot;time&quot;</span><span class="p">,</span>
<span class="s2">&quot;tottime&quot;</span><span class="p">,</span>
<span class="s2">"calls"</span><span class="p">,</span>
<span class="s2">"cumulative"</span><span class="p">,</span>
<span class="s2">"cumtime"</span><span class="p">,</span>
<span class="s2">"file"</span><span class="p">,</span>
<span class="s2">"filename"</span><span class="p">,</span>
<span class="s2">"module"</span><span class="p">,</span>
<span class="s2">"ncalls"</span><span class="p">,</span>
<span class="s2">"pcalls"</span><span class="p">,</span>
<span class="s2">"line"</span><span class="p">,</span>
<span class="s2">"name"</span><span class="p">,</span>
<span class="s2">"nfl"</span><span class="p">,</span>
<span class="s2">"stdname"</span><span class="p">,</span>
<span class="s2">"time"</span><span class="p">,</span>
<span class="s2">"tottime"</span><span class="p">,</span>
<span class="p">]</span>
</pre></div>
</div>
</article>
</div>
<footer>
<div class="related-pages">
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="../../index.html">osxphotos</a></h1>
<h3>Navigation</h3>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../overview.html">osxphotos</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../tutorial.html">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="../../reference.html">osxphotos package</a></li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="../../index.html">Documentation overview</a><ul>
<li><a href="../index.html">Module code</a><ul>
</ul></li>
</ul></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../../search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
<input type="submit" value="Go" />
</form>
</div>
</div>
<script>$('#searchbox').show(0);</script>
<div class="bottom-of-page">
<div class="left-details">
<div class="copyright">
Copyright &#169; 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>
</div>
<div class="clearer"></div>
</footer>
</div>
<div class="footer">
&copy;2021, Rhet Turnbull.
<aside class="toc-drawer no-toc">
|
Powered by <a href="http://sphinx-doc.org/">Sphinx 4.4.0</a>
&amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
</div>
</body>
</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/doctools.js"></script>
<script src="../../_static/scripts/furo.js"></script>
<script src="../../_static/clipboard.min.js"></script>
<script src="../../_static/copybutton.js"></script>
</body>
</html>

View File

@@ -1,173 +1,325 @@
<!doctype html>
<html class="no-js">
<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" />
<!DOCTYPE html>
<meta name="generator" content="sphinx-4.4.0, furo 2022.04.07"/>
<title>osxphotos.momentinfo - osxphotos 0.48.1 documentation</title>
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="../../_static/styles/furo.css?digest=68f4518137b9aefe99b631505a2064c3c42c9852" />
<link rel="stylesheet" type="text/css" href="../../_static/copybutton.css" />
<link rel="stylesheet" type="text/css" href="../../_static/styles/furo-extensions.css?digest=30d1aed668e5c3a91c3e3bf6a60b675221979f0e" />
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>osxphotos.momentinfo &#8212; osxphotos 0.47.9 documentation</title>
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="../../_static/alabaster.css" />
<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/doctools.js"></script>
<link rel="index" title="Index" href="../../genindex.html" />
<link rel="search" title="Search" href="../../search.html" />
<link rel="stylesheet" href="../../_static/custom.css" type="text/css" />
<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.48.1 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">
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
</head><body>
<span class="sidebar-brand-text">osxphotos 0.48.1 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 API</a></li>
</ul>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
</div>
</div>
<div class="body" role="main">
<h1>Source code for osxphotos.momentinfo</h1><div class="highlight"><pre>
<span></span><span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;MomentInfo&quot;</span><span class="p">]</span>
<span class="sd">&quot;&quot;&quot;MomentInfo class with details about photo moments.&quot;&quot;&quot;</span>
</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.momentinfo</h1><div class="highlight"><pre>
<span></span><span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"MomentInfo"</span><span class="p">]</span>
<span class="sd">"""MomentInfo class with details about photo moments."""</span>
<div class="viewcode-block" id="MomentInfo"><a class="viewcode-back" href="../../reference.html#osxphotos.MomentInfo">[docs]</a><span class="k">class</span> <span class="nc">MomentInfo</span><span class="p">:</span>
<span class="sd">&quot;&quot;&quot;Info about a photo moment&quot;&quot;&quot;</span>
<span class="sd">"""Info about a photo moment"""</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">db</span><span class="p">,</span> <span class="n">moment_pk</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Initialize with a moment PK; returns None if PK not found.&quot;&quot;&quot;</span>
<span class="sd">"""Initialize with a moment PK; returns None if PK not found."""</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_db</span> <span class="o">=</span> <span class="n">db</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_pk</span> <span class="o">=</span> <span class="n">moment_pk</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_moment</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_db_moment_pk</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">moment_pk</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_moment</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">&quot;No moment with PK </span><span class="si">{</span><span class="n">moment_pk</span><span class="si">}</span><span class="s2">&quot;</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">"No moment with PK </span><span class="si">{</span><span class="n">moment_pk</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
<span class="nd">@property</span>
<span class="k">def</span> <span class="nf">pk</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Primary key of the moment.&quot;&quot;&quot;</span>
<span class="sd">"""Primary key of the moment."""</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_pk</span>
<span class="nd">@property</span>
<span class="k">def</span> <span class="nf">location</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Location of the moment.&quot;&quot;&quot;</span>
<span class="k">return</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_moment</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;latitude&quot;</span><span class="p">),</span> <span class="bp">self</span><span class="o">.</span><span class="n">_moment</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;longitude&quot;</span><span class="p">))</span>
<span class="sd">"""Location of the moment."""</span>
<span class="k">return</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_moment</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"latitude"</span><span class="p">),</span> <span class="bp">self</span><span class="o">.</span><span class="n">_moment</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"longitude"</span><span class="p">))</span>
<span class="nd">@property</span>
<span class="k">def</span> <span class="nf">title</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Title of the moment.&quot;&quot;&quot;</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_moment</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;title&quot;</span><span class="p">)</span>
<span class="sd">"""Title of the moment."""</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_moment</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"title"</span><span class="p">)</span>
<span class="nd">@property</span>
<span class="k">def</span> <span class="nf">subtitle</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Subtitle of the moment.&quot;&quot;&quot;</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_moment</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;subtitle&quot;</span><span class="p">)</span>
<span class="sd">"""Subtitle of the moment."""</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_moment</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"subtitle"</span><span class="p">)</span>
<span class="nd">@property</span>
<span class="k">def</span> <span class="nf">start_date</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Start date of the moment.&quot;&quot;&quot;</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_moment</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;startDate&quot;</span><span class="p">)</span>
<span class="sd">"""Start date of the moment."""</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_moment</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"startDate"</span><span class="p">)</span>
<span class="nd">@property</span>
<span class="k">def</span> <span class="nf">end_date</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Stop date of the moment.&quot;&quot;&quot;</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_moment</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;endDate&quot;</span><span class="p">)</span>
<span class="sd">"""Stop date of the moment."""</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_moment</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"endDate"</span><span class="p">)</span>
<span class="nd">@property</span>
<span class="k">def</span> <span class="nf">date</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Date of the moment.&quot;&quot;&quot;</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_moment</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;representativeDate&quot;</span><span class="p">)</span>
<span class="sd">"""Date of the moment."""</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_moment</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"representativeDate"</span><span class="p">)</span>
<span class="nd">@property</span>
<span class="k">def</span> <span class="nf">modification_date</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Modification date of the moment.&quot;&quot;&quot;</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_moment</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;modificationDate&quot;</span><span class="p">)</span>
<span class="sd">"""Modification date of the moment."""</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_moment</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"modificationDate"</span><span class="p">)</span>
<span class="nd">@property</span>
<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="sd">&quot;&quot;&quot;All photos in this moment&quot;&quot;&quot;</span>
<span class="sd">"""All photos in this moment"""</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">_photos</span>
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
<span class="n">photo_uuids</span> <span class="o">=</span> <span class="p">[</span>
<span class="n">uuid</span>
<span class="k">for</span> <span class="n">uuid</span><span class="p">,</span> <span class="n">photo</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_dbphotos</span><span class="o">.</span><span class="n">items</span><span class="p">()</span>
<span class="k">if</span> <span class="n">photo</span><span class="p">[</span><span class="s2">&quot;momentID&quot;</span><span class="p">]</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">_pk</span>
<span class="k">if</span> <span class="n">photo</span><span class="p">[</span><span class="s2">"momentID"</span><span class="p">]</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">_pk</span>
<span class="p">]</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_photos</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">photos_by_uuid</span><span class="p">(</span><span class="n">photo_uuids</span><span class="p">)</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_photos</span></div>
</pre></div>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_photos</span>
</div>
<div class="viewcode-block" id="MomentInfo.asdict"><a class="viewcode-back" href="../../reference.html#osxphotos.MomentInfo.asdict">[docs]</a> <span class="k">def</span> <span class="nf">asdict</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">"""Returns all moment info as dictionary"""</span>
<span class="k">return</span> <span class="p">{</span>
<span class="s2">"pk"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">pk</span><span class="p">,</span>
<span class="s2">"location"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">location</span><span class="p">,</span>
<span class="s2">"title"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">title</span><span class="p">,</span>
<span class="s2">"subtitle"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">subtitle</span><span class="p">,</span>
<span class="s2">"start_date"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">start_date</span><span class="o">.</span><span class="n">isoformat</span><span class="p">()</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">start_date</span> <span class="k">else</span> <span class="kc">None</span><span class="p">,</span>
<span class="s2">"end_date"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">end_date</span><span class="o">.</span><span class="n">isoformat</span><span class="p">()</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">end_date</span> <span class="k">else</span> <span class="kc">None</span><span class="p">,</span>
<span class="s2">"date"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">date</span><span class="o">.</span><span class="n">isoformat</span><span class="p">()</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">date</span> <span class="k">else</span> <span class="kc">None</span><span class="p">,</span>
<span class="s2">"modification_date"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">modification_date</span><span class="o">.</span><span class="n">isoformat</span><span class="p">()</span>
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">modification_date</span>
<span class="k">else</span> <span class="kc">None</span><span class="p">,</span>
<span class="s2">"photos"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">photos</span><span class="p">,</span>
<span class="p">}</span></div></div>
</pre></div>
</article>
</div>
<footer>
<div class="related-pages">
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h1 class="logo"><a href="../../index.html">osxphotos</a></h1>
<h3>Navigation</h3>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../overview.html">osxphotos</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../tutorial.html">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="../../reference.html">osxphotos package</a></li>
</ul>
<div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="../../index.html">Documentation overview</a><ul>
<li><a href="../index.html">Module code</a><ul>
</ul></li>
</ul></li>
</ul>
</div>
<div id="searchbox" style="display: none" role="search">
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../../search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
<input type="submit" value="Go" />
</form>
</div>
</div>
<script>$('#searchbox').show(0);</script>
<div class="bottom-of-page">
<div class="left-details">
<div class="copyright">
Copyright &#169; 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>
</div>
<div class="clearer"></div>
</footer>
</div>
<div class="footer">
&copy;2021, Rhet Turnbull.
<aside class="toc-drawer no-toc">
|
Powered by <a href="http://sphinx-doc.org/">Sphinx 4.4.0</a>
&amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
</div>
</body>
</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/doctools.js"></script>
<script src="../../_static/scripts/furo.js"></script>
<script src="../../_static/clipboard.min.js"></script>
<script src="../../_static/copybutton.js"></script>
</body>
</html>

View File

@@ -5,7 +5,7 @@
<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-4.4.0, furo 2022.04.07"/>
<title>osxphotos.photoinfo - osxphotos 0.47.9 documentation</title>
<title>osxphotos.photoinfo - osxphotos 0.48.1 documentation</title>
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="../../_static/styles/furo.css?digest=68f4518137b9aefe99b631505a2064c3c42c9852" />
<link rel="stylesheet" type="text/css" href="../../_static/copybutton.css" />
@@ -123,7 +123,7 @@
</label>
</div>
<div class="header-center">
<a href="../../index.html"><div class="brand">osxphotos 0.47.9 documentation</div></a>
<a href="../../index.html"><div class="brand">osxphotos 0.48.1 documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@@ -146,7 +146,7 @@
<div class="sidebar-sticky"><a class="sidebar-brand" href="../../index.html">
<span class="sidebar-brand-text">osxphotos 0.47.9 documentation</span>
<span class="sidebar-brand-text">osxphotos 0.48.1 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">
@@ -155,11 +155,12 @@
</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="../../package_overview.html">Example uses of the python package</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../reference.html">osxphotos python API</a></li>
<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 API</a></li>
</ul>
</div>
@@ -674,7 +675,7 @@
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_faceinfo</span>
<span class="nd">@property</span>
<span class="k">def</span> <span class="nf">moment</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">moment_info</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">"""Moment photo belongs to"""</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">_moment</span>

File diff suppressed because it is too large Load Diff

View File

@@ -5,7 +5,7 @@
<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-4.4.0, furo 2022.04.07"/>
<title>osxphotos.phototemplate - osxphotos 0.47.10 documentation</title>
<title>osxphotos.phototemplate - osxphotos 0.48.1 documentation</title>
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="../../_static/styles/furo.css?digest=68f4518137b9aefe99b631505a2064c3c42c9852" />
<link rel="stylesheet" type="text/css" href="../../_static/copybutton.css" />
@@ -123,7 +123,7 @@
</label>
</div>
<div class="header-center">
<a href="../../index.html"><div class="brand">osxphotos 0.47.10 documentation</div></a>
<a href="../../index.html"><div class="brand">osxphotos 0.48.1 documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@@ -146,7 +146,7 @@
<div class="sidebar-sticky"><a class="sidebar-brand" href="../../index.html">
<span class="sidebar-brand-text">osxphotos 0.47.10 documentation</span>
<span class="sidebar-brand-text">osxphotos 0.48.1 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">
@@ -155,12 +155,12 @@
</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">Example uses of the python package</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../reference.html">osxphotos python API</a></li>
<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 API</a></li>
</ul>
</div>
@@ -334,6 +334,7 @@
<span class="s2">"</span><span class="si">{exif.camera_make}</span><span class="s2">"</span><span class="p">:</span> <span class="s2">"Camera make from original photo's EXIF information as imported by Photos, e.g. 'Apple'"</span><span class="p">,</span>
<span class="s2">"</span><span class="si">{exif.camera_model}</span><span class="s2">"</span><span class="p">:</span> <span class="s2">"Camera model from original photo's EXIF information as imported by Photos, e.g. 'iPhone 6s'"</span><span class="p">,</span>
<span class="s2">"</span><span class="si">{exif.lens_model}</span><span class="s2">"</span><span class="p">:</span> <span class="s2">"Lens model from original photo's EXIF information as imported by Photos, e.g. 'iPhone 6s back camera 4.15mm f/2.2'"</span><span class="p">,</span>
<span class="s2">"</span><span class="si">{moment}</span><span class="s2">"</span><span class="p">:</span> <span class="s2">"The moment title of the photo"</span><span class="p">,</span>
<span class="s2">"</span><span class="si">{uuid}</span><span class="s2">"</span><span class="p">:</span> <span class="s2">"Photo's internal universally unique identifier (UUID) for the photo, a 36-character string unique to the photo, e.g. '128FB4C6-0B16-4E7D-9108-FB2E90DA1546'"</span><span class="p">,</span>
<span class="s2">"</span><span class="si">{id}</span><span class="s2">"</span><span class="p">:</span> <span class="s2">"A unique number for the photo based on its primary key in the Photos database. "</span>
<span class="o">+</span> <span class="s2">"A sequential integer, e.g. 1, 2, 3...etc. Each asset associated with a photo (e.g. an image and Live Photo preview) will share the same id. "</span>
@@ -1170,6 +1171,8 @@
<span class="n">value</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">photo</span><span class="o">.</span><span class="n">exif_info</span><span class="o">.</span><span class="n">camera_model</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">photo</span><span class="o">.</span><span class="n">exif_info</span> <span class="k">else</span> <span class="kc">None</span>
<span class="k">elif</span> <span class="n">field</span> <span class="o">==</span> <span class="s2">"exif.lens_model"</span><span class="p">:</span>
<span class="n">value</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">photo</span><span class="o">.</span><span class="n">exif_info</span><span class="o">.</span><span class="n">lens_model</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">photo</span><span class="o">.</span><span class="n">exif_info</span> <span class="k">else</span> <span class="kc">None</span>
<span class="k">elif</span> <span class="n">field</span> <span class="o">==</span> <span class="s2">"moment"</span><span class="p">:</span>
<span class="n">value</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">photo</span><span class="o">.</span><span class="n">moment_info</span><span class="o">.</span><span class="n">title</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">photo</span><span class="o">.</span><span class="n">moment_info</span> <span class="k">else</span> <span class="kc">None</span>
<span class="k">elif</span> <span class="n">field</span> <span class="o">==</span> <span class="s2">"uuid"</span><span class="p">:</span>
<span class="n">value</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">photo</span><span class="o">.</span><span class="n">uuid</span>
<span class="k">elif</span> <span class="n">field</span> <span class="o">==</span> <span class="s2">"id"</span><span class="p">:</span>

View File

@@ -281,6 +281,8 @@ Template Substitutions
- Camera model from original photo's EXIF information as imported by Photos, e.g. 'iPhone 6s'
* - {exif.lens_model}
- Lens model from original photo's EXIF information as imported by Photos, e.g. 'iPhone 6s back camera 4.15mm f/2.2'
* - {moment}
- The moment title of the photo
* - {uuid}
- Photo's internal universally unique identifier (UUID) for the photo, a 36-character string unique to the photo, e.g. '128FB4C6-0B16-4E7D-9108-FB2E90DA1546'
* - {id}
@@ -318,7 +320,7 @@ Template Substitutions
* - {crlf}
- a carriage return + line feed: '\r\n'
* - {osxphotos_version}
- The osxphotos version, e.g. '0.48.0'
- The osxphotos version, e.g. '0.48.2'
* - {osxphotos_cmd_line}
- The full command line used to run osxphotos
* - {album}

View File

@@ -1,6 +1,6 @@
var DOCUMENTATION_OPTIONS = {
URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'),
VERSION: '0.48.0',
VERSION: '0.48.2',
LANGUAGE: 'None',
COLLAPSE_INDEX: false,
BUILDER: 'html',

View File

@@ -6,7 +6,7 @@
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="OSXPhotos Template System" href="template_help.html" /><link rel="prev" title="OSXPhotos Tutorial" href="tutorial.html" />
<meta name="generator" content="sphinx-4.4.0, furo 2022.04.07"/>
<title>OSXPhotos Command Line Interface (CLI) - osxphotos 0.48.0 documentation</title>
<title>OSXPhotos Command Line Interface (CLI) - osxphotos 0.48.2 documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=68f4518137b9aefe99b631505a2064c3c42c9852" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
@@ -124,7 +124,7 @@
</label>
</div>
<div class="header-center">
<a href="index.html"><div class="brand">osxphotos 0.48.0 documentation</div></a>
<a href="index.html"><div class="brand">osxphotos 0.48.2 documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@@ -147,7 +147,7 @@
<div class="sidebar-sticky"><a class="sidebar-brand" href="index.html">
<span class="sidebar-brand-text">osxphotos 0.48.0 documentation</span>
<span class="sidebar-brand-text">osxphotos 0.48.2 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">
@@ -205,7 +205,7 @@
<p class="rubric">Options</p>
<dl class="std option">
<dt class="sig sig-object std" id="cmdoption-osxphotos-db">
<span class="sig-name descname"><span class="pre">--db</span></span><span class="sig-prename descclassname"> <span class="pre">&lt;Photos</span> <span class="pre">database</span> <span class="pre">path&gt;</span></span><a class="headerlink" href="#cmdoption-osxphotos-db" title="Permalink to this definition">#</a></dt>
<span class="sig-name descname"><span class="pre">--db</span></span><span class="sig-prename descclassname"> <span class="pre">&lt;PHOTOS_LIBRARY_PATH&gt;</span></span><a class="headerlink" href="#cmdoption-osxphotos-db" title="Permalink to this definition">#</a></dt>
<dd><p>Specify Photos database path. Path to Photos library/database can be specified using either db or directly as PHOTOS_LIBRARY positional argument. If neither db or PHOTOS_LIBRARY provided, will attempt to find the library to use in the following order: 1. last opened library, 2. system library, 3. ~/Pictures/Photos Library.photoslibrary</p>
</dd></dl>
<dl class="std option">
@@ -234,7 +234,7 @@
<p class="rubric">Options</p>
<dl class="std option">
<dt class="sig sig-object std" id="cmdoption-osxphotos-albums-db">
<span class="sig-name descname"><span class="pre">--db</span></span><span class="sig-prename descclassname"> <span class="pre">&lt;Photos</span> <span class="pre">database</span> <span class="pre">path&gt;</span></span><a class="headerlink" href="#cmdoption-osxphotos-albums-db" title="Permalink to this definition">#</a></dt>
<span class="sig-name descname"><span class="pre">--db</span></span><span class="sig-prename descclassname"> <span class="pre">&lt;PHOTOS_LIBRARY_PATH&gt;</span></span><a class="headerlink" href="#cmdoption-osxphotos-albums-db" title="Permalink to this definition">#</a></dt>
<dd><p>Specify Photos database path. Path to Photos library/database can be specified using either db or directly as PHOTOS_LIBRARY positional argument. If neither db or PHOTOS_LIBRARY provided, will attempt to find the library to use in the following order: 1. last opened library, 2. system library, 3. ~/Pictures/Photos Library.photoslibrary</p>
</dd></dl>
<dl class="std option">
@@ -277,7 +277,7 @@ library specified by db to the database specified by DB2</p>
<p class="rubric">Options</p>
<dl class="std option">
<dt class="sig sig-object std" id="cmdoption-osxphotos-diff-db">
<span class="sig-name descname"><span class="pre">--db</span></span><span class="sig-prename descclassname"> <span class="pre">&lt;Photos</span> <span class="pre">database</span> <span class="pre">path&gt;</span></span><a class="headerlink" href="#cmdoption-osxphotos-diff-db" title="Permalink to this definition">#</a></dt>
<span class="sig-name descname"><span class="pre">--db</span></span><span class="sig-prename descclassname"> <span class="pre">&lt;PHOTOS_LIBRARY_PATH&gt;</span></span><a class="headerlink" href="#cmdoption-osxphotos-diff-db" title="Permalink to this definition">#</a></dt>
<dd><p>Specify Photos database path. Path to Photos library/database can be specified using either db or directly as PHOTOS_LIBRARY positional argument. If neither db or PHOTOS_LIBRARY provided, will attempt to find the library to use in the following order: 1. last opened library, 2. system library, 3. ~/Pictures/Photos Library.photoslibrary</p>
</dd></dl>
<dl class="std option">
@@ -318,7 +318,7 @@ library specified by db to the database specified by DB2</p>
<p class="rubric">Options</p>
<dl class="std option">
<dt class="sig sig-object std" id="cmdoption-osxphotos-dump-db">
<span class="sig-name descname"><span class="pre">--db</span></span><span class="sig-prename descclassname"> <span class="pre">&lt;Photos</span> <span class="pre">database</span> <span class="pre">path&gt;</span></span><a class="headerlink" href="#cmdoption-osxphotos-dump-db" title="Permalink to this definition">#</a></dt>
<span class="sig-name descname"><span class="pre">--db</span></span><span class="sig-prename descclassname"> <span class="pre">&lt;PHOTOS_LIBRARY_PATH&gt;</span></span><a class="headerlink" href="#cmdoption-osxphotos-dump-db" title="Permalink to this definition">#</a></dt>
<dd><p>Specify Photos database path. Path to Photos library/database can be specified using either db or directly as PHOTOS_LIBRARY positional argument. If neither db or PHOTOS_LIBRARY provided, will attempt to find the library to use in the following order: 1. last opened library, 2. system library, 3. ~/Pictures/Photos Library.photoslibrary</p>
</dd></dl>
<dl class="std option">
@@ -361,7 +361,7 @@ to modify this behavior.</p>
<p class="rubric">Options</p>
<dl class="std option">
<dt class="sig sig-object std" id="cmdoption-osxphotos-export-db">
<span class="sig-name descname"><span class="pre">--db</span></span><span class="sig-prename descclassname"> <span class="pre">&lt;Photos</span> <span class="pre">database</span> <span class="pre">path&gt;</span></span><a class="headerlink" href="#cmdoption-osxphotos-export-db" title="Permalink to this definition">#</a></dt>
<span class="sig-name descname"><span class="pre">--db</span></span><span class="sig-prename descclassname"> <span class="pre">&lt;PHOTOS_LIBRARY_PATH&gt;</span></span><a class="headerlink" href="#cmdoption-osxphotos-export-db" title="Permalink to this definition">#</a></dt>
<dd><p>Specify Photos database path. Path to Photos library/database can be specified using either db or directly as PHOTOS_LIBRARY positional argument. If neither db or PHOTOS_LIBRARY provided, will attempt to find the library to use in the following order: 1. last opened library, 2. system library, 3. ~/Pictures/Photos Library.photoslibrary</p>
</dd></dl>
<dl class="std option">
@@ -983,7 +983,7 @@ to modify this behavior.</p>
</dd></dl>
<dl class="std option">
<dt class="sig sig-object std" id="cmdoption-osxphotos-export-report">
<span class="sig-name descname"><span class="pre">--report</span></span><span class="sig-prename descclassname"> <span class="pre">&lt;path</span> <span class="pre">to</span> <span class="pre">export</span> <span class="pre">report&gt;</span></span><a class="headerlink" href="#cmdoption-osxphotos-export-report" title="Permalink to this definition">#</a></dt>
<span class="sig-name descname"><span class="pre">--report</span></span><span class="sig-prename descclassname"> <span class="pre">&lt;REPORT_FILE&gt;</span></span><a class="headerlink" href="#cmdoption-osxphotos-export-report" title="Permalink to this definition">#</a></dt>
<dd><p>Write a CSV formatted report of all files that were exported.</p>
</dd></dl>
<dl class="std option">
@@ -1033,12 +1033,12 @@ to modify this behavior.</p>
</dd></dl>
<dl class="std option">
<dt class="sig sig-object std" id="cmdoption-osxphotos-export-load-config">
<span class="sig-name descname"><span class="pre">--load-config</span></span><span class="sig-prename descclassname"> <span class="pre">&lt;config</span> <span class="pre">file</span> <span class="pre">path&gt;</span></span><a class="headerlink" href="#cmdoption-osxphotos-export-load-config" title="Permalink to this definition">#</a></dt>
<span class="sig-name descname"><span class="pre">--load-config</span></span><span class="sig-prename descclassname"> <span class="pre">&lt;CONFIG_FILE&gt;</span></span><a class="headerlink" href="#cmdoption-osxphotos-export-load-config" title="Permalink to this definition">#</a></dt>
<dd><p>Load options from file as written with save-config. This allows you to save a complex export command to file for later reuse. For example: osxphotos export &lt;lots of options here&gt; save-config osxphotos.toml then osxphotos export /path/to/export load-config osxphotos.toml. If any other command line options are used in conjunction with load-config, they will override the corresponding values in the config file.</p>
</dd></dl>
<dl class="std option">
<dt class="sig sig-object std" id="cmdoption-osxphotos-export-save-config">
<span class="sig-name descname"><span class="pre">--save-config</span></span><span class="sig-prename descclassname"> <span class="pre">&lt;config</span> <span class="pre">file</span> <span class="pre">path&gt;</span></span><a class="headerlink" href="#cmdoption-osxphotos-export-save-config" title="Permalink to this definition">#</a></dt>
<span class="sig-name descname"><span class="pre">--save-config</span></span><span class="sig-prename descclassname"> <span class="pre">&lt;CONFIG_FILE&gt;</span></span><a class="headerlink" href="#cmdoption-osxphotos-export-save-config" title="Permalink to this definition">#</a></dt>
<dd><p>Save options to file for use with load-config. File format is TOML. See also config-only.</p>
</dd></dl>
<dl class="std option">
@@ -1095,7 +1095,7 @@ to modify this behavior.</p>
<p class="rubric">Options</p>
<dl class="std option">
<dt class="sig sig-object std" id="cmdoption-osxphotos-info-db">
<span class="sig-name descname"><span class="pre">--db</span></span><span class="sig-prename descclassname"> <span class="pre">&lt;Photos</span> <span class="pre">database</span> <span class="pre">path&gt;</span></span><a class="headerlink" href="#cmdoption-osxphotos-info-db" title="Permalink to this definition">#</a></dt>
<span class="sig-name descname"><span class="pre">--db</span></span><span class="sig-prename descclassname"> <span class="pre">&lt;PHOTOS_LIBRARY_PATH&gt;</span></span><a class="headerlink" href="#cmdoption-osxphotos-info-db" title="Permalink to this definition">#</a></dt>
<dd><p>Specify Photos database path. Path to Photos library/database can be specified using either db or directly as PHOTOS_LIBRARY positional argument. If neither db or PHOTOS_LIBRARY provided, will attempt to find the library to use in the following order: 1. last opened library, 2. system library, 3. ~/Pictures/Photos Library.photoslibrary</p>
</dd></dl>
<dl class="std option">
@@ -1138,7 +1138,7 @@ to modify this behavior.</p>
<p class="rubric">Options</p>
<dl class="std option">
<dt class="sig sig-object std" id="cmdoption-osxphotos-keywords-db">
<span class="sig-name descname"><span class="pre">--db</span></span><span class="sig-prename descclassname"> <span class="pre">&lt;Photos</span> <span class="pre">database</span> <span class="pre">path&gt;</span></span><a class="headerlink" href="#cmdoption-osxphotos-keywords-db" title="Permalink to this definition">#</a></dt>
<span class="sig-name descname"><span class="pre">--db</span></span><span class="sig-prename descclassname"> <span class="pre">&lt;PHOTOS_LIBRARY_PATH&gt;</span></span><a class="headerlink" href="#cmdoption-osxphotos-keywords-db" title="Permalink to this definition">#</a></dt>
<dd><p>Specify Photos database path. Path to Photos library/database can be specified using either db or directly as PHOTOS_LIBRARY positional argument. If neither db or PHOTOS_LIBRARY provided, will attempt to find the library to use in the following order: 1. last opened library, 2. system library, 3. ~/Pictures/Photos Library.photoslibrary</p>
</dd></dl>
<dl class="std option">
@@ -1162,7 +1162,7 @@ to modify this behavior.</p>
<p class="rubric">Options</p>
<dl class="std option">
<dt class="sig sig-object std" id="cmdoption-osxphotos-labels-db">
<span class="sig-name descname"><span class="pre">--db</span></span><span class="sig-prename descclassname"> <span class="pre">&lt;Photos</span> <span class="pre">database</span> <span class="pre">path&gt;</span></span><a class="headerlink" href="#cmdoption-osxphotos-labels-db" title="Permalink to this definition">#</a></dt>
<span class="sig-name descname"><span class="pre">--db</span></span><span class="sig-prename descclassname"> <span class="pre">&lt;PHOTOS_LIBRARY_PATH&gt;</span></span><a class="headerlink" href="#cmdoption-osxphotos-labels-db" title="Permalink to this definition">#</a></dt>
<dd><p>Specify Photos database path. Path to Photos library/database can be specified using either db or directly as PHOTOS_LIBRARY positional argument. If neither db or PHOTOS_LIBRARY provided, will attempt to find the library to use in the following order: 1. last opened library, 2. system library, 3. ~/Pictures/Photos Library.photoslibrary</p>
</dd></dl>
<dl class="std option">
@@ -1199,7 +1199,7 @@ to modify this behavior.</p>
<p class="rubric">Options</p>
<dl class="std option">
<dt class="sig sig-object std" id="cmdoption-osxphotos-persons-db">
<span class="sig-name descname"><span class="pre">--db</span></span><span class="sig-prename descclassname"> <span class="pre">&lt;Photos</span> <span class="pre">database</span> <span class="pre">path&gt;</span></span><a class="headerlink" href="#cmdoption-osxphotos-persons-db" title="Permalink to this definition">#</a></dt>
<span class="sig-name descname"><span class="pre">--db</span></span><span class="sig-prename descclassname"> <span class="pre">&lt;PHOTOS_LIBRARY_PATH&gt;</span></span><a class="headerlink" href="#cmdoption-osxphotos-persons-db" title="Permalink to this definition">#</a></dt>
<dd><p>Specify Photos database path. Path to Photos library/database can be specified using either db or directly as PHOTOS_LIBRARY positional argument. If neither db or PHOTOS_LIBRARY provided, will attempt to find the library to use in the following order: 1. last opened library, 2. system library, 3. ~/Pictures/Photos Library.photoslibrary</p>
</dd></dl>
<dl class="std option">
@@ -1223,7 +1223,7 @@ to modify this behavior.</p>
<p class="rubric">Options</p>
<dl class="std option">
<dt class="sig sig-object std" id="cmdoption-osxphotos-places-db">
<span class="sig-name descname"><span class="pre">--db</span></span><span class="sig-prename descclassname"> <span class="pre">&lt;Photos</span> <span class="pre">database</span> <span class="pre">path&gt;</span></span><a class="headerlink" href="#cmdoption-osxphotos-places-db" title="Permalink to this definition">#</a></dt>
<span class="sig-name descname"><span class="pre">--db</span></span><span class="sig-prename descclassname"> <span class="pre">&lt;PHOTOS_LIBRARY_PATH&gt;</span></span><a class="headerlink" href="#cmdoption-osxphotos-places-db" title="Permalink to this definition">#</a></dt>
<dd><p>Specify Photos database path. Path to Photos library/database can be specified using either db or directly as PHOTOS_LIBRARY positional argument. If neither db or PHOTOS_LIBRARY provided, will attempt to find the library to use in the following order: 1. last opened library, 2. system library, 3. ~/Pictures/Photos Library.photoslibrary</p>
</dd></dl>
<dl class="std option">
@@ -1249,7 +1249,7 @@ if more than one option is provided, they are treated as “AND”
<p class="rubric">Options</p>
<dl class="std option">
<dt class="sig sig-object std" id="cmdoption-osxphotos-query-db">
<span class="sig-name descname"><span class="pre">--db</span></span><span class="sig-prename descclassname"> <span class="pre">&lt;Photos</span> <span class="pre">database</span> <span class="pre">path&gt;</span></span><a class="headerlink" href="#cmdoption-osxphotos-query-db" title="Permalink to this definition">#</a></dt>
<span class="sig-name descname"><span class="pre">--db</span></span><span class="sig-prename descclassname"> <span class="pre">&lt;PHOTOS_LIBRARY_PATH&gt;</span></span><a class="headerlink" href="#cmdoption-osxphotos-query-db" title="Permalink to this definition">#</a></dt>
<dd><p>Specify Photos database path. Path to Photos library/database can be specified using either db or directly as PHOTOS_LIBRARY positional argument. If neither db or PHOTOS_LIBRARY provided, will attempt to find the library to use in the following order: 1. last opened library, 2. system library, 3. ~/Pictures/Photos Library.photoslibrary</p>
</dd></dl>
<dl class="std option">
@@ -1653,7 +1653,7 @@ if more than one option is provided, they are treated as “AND”
<p class="rubric">Options</p>
<dl class="std option">
<dt class="sig sig-object std" id="cmdoption-osxphotos-repl-db">
<span class="sig-name descname"><span class="pre">--db</span></span><span class="sig-prename descclassname"> <span class="pre">&lt;Photos</span> <span class="pre">database</span> <span class="pre">path&gt;</span></span><a class="headerlink" href="#cmdoption-osxphotos-repl-db" title="Permalink to this definition">#</a></dt>
<span class="sig-name descname"><span class="pre">--db</span></span><span class="sig-prename descclassname"> <span class="pre">&lt;PHOTOS_LIBRARY_PATH&gt;</span></span><a class="headerlink" href="#cmdoption-osxphotos-repl-db" title="Permalink to this definition">#</a></dt>
<dd><p>Specify Photos database path. Path to Photos library/database can be specified using either db or directly as PHOTOS_LIBRARY positional argument. If neither db or PHOTOS_LIBRARY provided, will attempt to find the library to use in the following order: 1. last opened library, 2. system library, 3. ~/Pictures/Photos Library.photoslibrary</p>
</dd></dl>
<dl class="std option">
@@ -2063,7 +2063,7 @@ uses /private/tmp/osxphotos_snapshots</p>
<p class="rubric">Options</p>
<dl class="std option">
<dt class="sig sig-object std" id="cmdoption-osxphotos-snap-db">
<span class="sig-name descname"><span class="pre">--db</span></span><span class="sig-prename descclassname"> <span class="pre">&lt;Photos</span> <span class="pre">database</span> <span class="pre">path&gt;</span></span><a class="headerlink" href="#cmdoption-osxphotos-snap-db" title="Permalink to this definition">#</a></dt>
<span class="sig-name descname"><span class="pre">--db</span></span><span class="sig-prename descclassname"> <span class="pre">&lt;PHOTOS_LIBRARY_PATH&gt;</span></span><a class="headerlink" href="#cmdoption-osxphotos-snap-db" title="Permalink to this definition">#</a></dt>
<dd><p>Specify Photos database path. Path to Photos library/database can be specified using either db or directly as PHOTOS_LIBRARY positional argument. If neither db or PHOTOS_LIBRARY provided, will attempt to find the library to use in the following order: 1. last opened library, 2. system library, 3. ~/Pictures/Photos Library.photoslibrary</p>
</dd></dl>
</section>
@@ -2167,13 +2167,18 @@ See Timewarp Overview below for additional information.</p>
<dd><p>Pull date/time and timezone for selected photos from EXIF metadata in the original file into Photos and update the associated data in Photos to match the EXIF data. pull-exif will be executed before any other updates are performed on the photo. It is possible for images to have missing EXIF data, for example the date/time could be set but there might be no timezone set in the EXIF metadata. Missing data will be handled thusly: if date/time/timezone are all present in the EXIF data, the photos date/time/timezone will be updated. If timezone is missing but date/time is present, only the photos date/time will be updated. If date/time is missing but the timezone is present, only the photos timezone will be updated unless use-file-time is set in which case, the photos file modification date/time will be used in place of EXIF date/time. If the date is present but the time is missing, the time will be set to 00:00:00. Requires the third-party exiftool utility be installed (see <a class="reference external" href="https://exiftool.org/">https://exiftool.org/</a>). See also push-exif.</p>
</dd></dl>
<dl class="std option">
<dt class="sig sig-object std" id="cmdoption-osxphotos-timewarp-F">
<span id="cmdoption-osxphotos-timewarp-f"></span><span id="cmdoption-osxphotos-timewarp-function"></span><span class="sig-name descname"><span class="pre">-F</span></span><span class="sig-prename descclassname"></span><span class="sig-prename descclassname"><span class="pre">,</span> </span><span class="sig-name descname"><span class="pre">--function</span></span><span class="sig-prename descclassname"> <span class="pre">&lt;filename.py::function&gt;</span></span><a class="headerlink" href="#cmdoption-osxphotos-timewarp-F" title="Permalink to this definition">#</a></dt>
<dd><p>Run python function to determine the date/time/timezone to apply to a photo. Use this in format: function filename.py::function where filename.py is a python file youve created and function is the name of the function in the python file you want to call. The function will be passed information about the photo being processed and is expected to return a naive datetime.datetime object with time in local time and UTC timezone offset in seconds. See example function at https://github.com/RhetTbull/osxphotos/blob/master/examples/timewarp_function_example.py</p>
</dd></dl>
<dl class="std option">
<dt class="sig sig-object std" id="cmdoption-osxphotos-timewarp-m">
<span id="cmdoption-osxphotos-timewarp-match-time"></span><span class="sig-name descname"><span class="pre">-m</span></span><span class="sig-prename descclassname"></span><span class="sig-prename descclassname"><span class="pre">,</span> </span><span class="sig-name descname"><span class="pre">--match-time</span></span><span class="sig-prename descclassname"></span><a class="headerlink" href="#cmdoption-osxphotos-timewarp-m" title="Permalink to this definition">#</a></dt>
<dd><p>When used with timezone, adjusts the photo time so that the timestamp in the new timezone matches the timestamp in the old timezone. For example, if photo has time of 12:00 and timezone of GMT+01:00 and new timezone is specified as timezone +02:00 (one hour ahead of current GMT+01:00 timezone), the photos new time will be 12:00 GMT+02:00. That is, the timezone will have changed but the timestamp of the photo will match the previous timestamp. Use match-time when the cameras time was correct for the time the photo was taken but the timezone was missing or wrong and you want to adjust the timezone while preserving the photos time. See also timezone.</p>
</dd></dl>
<dl class="std option">
<dt class="sig sig-object std" id="cmdoption-osxphotos-timewarp-f">
<span id="cmdoption-osxphotos-timewarp-use-file-time"></span><span class="sig-name descname"><span class="pre">-f</span></span><span class="sig-prename descclassname"></span><span class="sig-prename descclassname"><span class="pre">,</span> </span><span class="sig-name descname"><span class="pre">--use-file-time</span></span><span class="sig-prename descclassname"></span><a class="headerlink" href="#cmdoption-osxphotos-timewarp-f" title="Permalink to this definition">#</a></dt>
<dt class="sig sig-object std" id="cmdoption-osxphotos-timewarp-0">
<span id="cmdoption-osxphotos-timewarp-use-file-time"></span><span class="sig-name descname"><span class="pre">-f</span></span><span class="sig-prename descclassname"></span><span class="sig-prename descclassname"><span class="pre">,</span> </span><span class="sig-name descname"><span class="pre">--use-file-time</span></span><span class="sig-prename descclassname"></span><a class="headerlink" href="#cmdoption-osxphotos-timewarp-0" title="Permalink to this definition">#</a></dt>
<dd><p>When used with pull-exif, the file modification date/time will be used if date/time is missing from the EXIF data.</p>
</dd></dl>
<dl class="std option">
@@ -2221,6 +2226,11 @@ See Timewarp Overview below for additional information.</p>
<span class="sig-name descname"><span class="pre">--plain</span></span><span class="sig-prename descclassname"></span><a class="headerlink" href="#cmdoption-osxphotos-timewarp-plain" title="Permalink to this definition">#</a></dt>
<dd><p>Plain text mode. Do not use rich output.</p>
</dd></dl>
<dl class="std option">
<dt class="sig sig-object std" id="cmdoption-osxphotos-timewarp-force">
<span class="sig-name descname"><span class="pre">--force</span></span><span class="sig-prename descclassname"></span><a class="headerlink" href="#cmdoption-osxphotos-timewarp-force" title="Permalink to this definition">#</a></dt>
<dd><p>Bypass confirmation prompt. Use with caution.</p>
</dd></dl>
</section>
<section id="osxphotos-tutorial">
<h3>tutorial<a class="headerlink" href="#osxphotos-tutorial" title="Permalink to this headline">#</a></h3>

View File

@@ -4,7 +4,7 @@
<meta name="viewport" content="width=device-width,initial-scale=1"/>
<meta name="color-scheme" content="light dark"><link rel="index" title="Index" href="#" /><link rel="search" title="Search" href="search.html" />
<meta name="generator" content="sphinx-4.4.0, furo 2022.04.07"/><title>Index - osxphotos 0.48.0 documentation</title>
<meta name="generator" content="sphinx-4.4.0, furo 2022.04.07"/><title>Index - osxphotos 0.48.2 documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=68f4518137b9aefe99b631505a2064c3c42c9852" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
@@ -122,7 +122,7 @@
</label>
</div>
<div class="header-center">
<a href="index.html"><div class="brand">osxphotos 0.48.0 documentation</div></a>
<a href="index.html"><div class="brand">osxphotos 0.48.2 documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@@ -145,7 +145,7 @@
<div class="sidebar-sticky"><a class="sidebar-brand" href="index.html">
<span class="sidebar-brand-text">osxphotos 0.48.0 documentation</span>
<span class="sidebar-brand-text">osxphotos 0.48.2 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">
@@ -608,6 +608,13 @@
<li><a href="cli.html#cmdoption-osxphotos-query-folder">osxphotos-query command line option</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-repl-folder">osxphotos-repl command line option</a>
</li>
</ul></li>
<li>
--force
<ul>
<li><a href="cli.html#cmdoption-osxphotos-timewarp-force">osxphotos-timewarp command line option</a>
</li>
</ul></li>
<li>
@@ -637,6 +644,13 @@
<li><a href="cli.html#cmdoption-osxphotos-query-from-time">osxphotos-query command line option</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-repl-from-time">osxphotos-repl command line option</a>
</li>
</ul></li>
<li>
--function
<ul>
<li><a href="cli.html#cmdoption-osxphotos-timewarp-F">osxphotos-timewarp command line option</a>
</li>
</ul></li>
<li>
@@ -1652,7 +1666,7 @@
--use-file-time
<ul>
<li><a href="cli.html#cmdoption-osxphotos-timewarp-f">osxphotos-timewarp command line option</a>
<li><a href="cli.html#cmdoption-osxphotos-timewarp-0">osxphotos-timewarp command line option</a>
</li>
</ul></li>
<li>
@@ -1778,13 +1792,20 @@
<ul>
<li><a href="cli.html#cmdoption-osxphotos-timewarp-e">osxphotos-timewarp command line option</a>
</li>
</ul></li>
<li>
-F
<ul>
<li><a href="cli.html#cmdoption-osxphotos-timewarp-F">osxphotos-timewarp command line option</a>
</li>
</ul></li>
<li>
-f
<ul>
<li><a href="cli.html#cmdoption-osxphotos-timewarp-f">osxphotos-timewarp command line option</a>
<li><a href="cli.html#cmdoption-osxphotos-timewarp-0">osxphotos-timewarp command line option</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-uuid-f">osxphotos-uuid command line option</a>
</li>
@@ -1955,6 +1976,8 @@
<li><a href="reference.html#osxphotos.ExifTool.asdict">asdict() (osxphotos.ExifTool method)</a>
<ul>
<li><a href="reference.html#osxphotos.MomentInfo.asdict">(osxphotos.MomentInfo method)</a>
</li>
<li><a href="reference.html#osxphotos.PersonInfo.asdict">(osxphotos.PersonInfo method)</a>
</li>
<li><a href="reference.html#osxphotos.PhotoInfo.asdict">(osxphotos.PhotoInfo method)</a>
@@ -2467,7 +2490,7 @@
<li><a href="reference.html#module-osxphotos">osxphotos</a>
</li>
</ul></li>
<li><a href="reference.html#osxphotos.PhotoInfo.moment">moment (osxphotos.PhotoInfo property)</a>
<li><a href="reference.html#osxphotos.PhotoInfo.moment_info">moment_info (osxphotos.PhotoInfo property)</a>
</li>
<li><a href="reference.html#osxphotos.MomentInfo">MomentInfo (class in osxphotos)</a>
</li>
@@ -3361,6 +3384,10 @@
<li><a href="cli.html#cmdoption-osxphotos-timewarp-D">--date-delta</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-timewarp-e">--exiftool-path</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-timewarp-force">--force</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-timewarp-F">--function</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-timewarp-i">--inspect</a>
</li>
@@ -3386,7 +3413,7 @@
</li>
<li><a href="cli.html#cmdoption-osxphotos-timewarp-z">--timezone</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-timewarp-f">--use-file-time</a>
<li><a href="cli.html#cmdoption-osxphotos-timewarp-0">--use-file-time</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-timewarp-V">--verbose</a>
</li>
@@ -3400,7 +3427,9 @@
</li>
<li><a href="cli.html#cmdoption-osxphotos-timewarp-e">-e</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-timewarp-f">-f</a>
<li><a href="cli.html#cmdoption-osxphotos-timewarp-F">-F</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-timewarp-0">-f</a>
</li>
<li><a href="cli.html#cmdoption-osxphotos-timewarp-i">-i</a>
</li>

View File

@@ -6,7 +6,7 @@
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="OSXPhotos" href="overview.html" />
<meta name="generator" content="sphinx-4.4.0, furo 2022.04.07"/>
<title>osxphotos 0.48.0 documentation</title>
<title>osxphotos 0.48.2 documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=68f4518137b9aefe99b631505a2064c3c42c9852" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
@@ -124,7 +124,7 @@
</label>
</div>
<div class="header-center">
<a href="#"><div class="brand">osxphotos 0.48.0 documentation</div></a>
<a href="#"><div class="brand">osxphotos 0.48.2 documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@@ -147,7 +147,7 @@
<div class="sidebar-sticky"><a class="sidebar-brand" href="#">
<span class="sidebar-brand-text">osxphotos 0.48.0 documentation</span>
<span class="sidebar-brand-text">osxphotos 0.48.2 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">

Binary file not shown.

View File

@@ -6,7 +6,7 @@
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="OSXPhotos Tutorial" href="tutorial.html" /><link rel="prev" title="Welcome to OSXPhotoss documentation!" href="index.html" />
<meta name="generator" content="sphinx-4.4.0, furo 2022.04.07"/>
<title>OSXPhotos - osxphotos 0.48.0 documentation</title>
<title>OSXPhotos - osxphotos 0.48.2 documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=68f4518137b9aefe99b631505a2064c3c42c9852" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
@@ -124,7 +124,7 @@
</label>
</div>
<div class="header-center">
<a href="index.html"><div class="brand">osxphotos 0.48.0 documentation</div></a>
<a href="index.html"><div class="brand">osxphotos 0.48.2 documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@@ -147,7 +147,7 @@
<div class="sidebar-sticky"><a class="sidebar-brand" href="index.html">
<span class="sidebar-brand-text">osxphotos 0.48.0 documentation</span>
<span class="sidebar-brand-text">osxphotos 0.48.2 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">

View File

@@ -6,7 +6,7 @@
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="OSXPhotos python API" href="reference.html" /><link rel="prev" title="OSXPhotos Template System" href="template_help.html" />
<meta name="generator" content="sphinx-4.4.0, furo 2022.04.07"/>
<title>OSXPhotos Python Package Overview - osxphotos 0.48.0 documentation</title>
<title>OSXPhotos Python Package Overview - osxphotos 0.48.2 documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=68f4518137b9aefe99b631505a2064c3c42c9852" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
@@ -124,7 +124,7 @@
</label>
</div>
<div class="header-center">
<a href="index.html"><div class="brand">osxphotos 0.48.0 documentation</div></a>
<a href="index.html"><div class="brand">osxphotos 0.48.2 documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@@ -147,7 +147,7 @@
<div class="sidebar-sticky"><a class="sidebar-brand" href="index.html">
<span class="sidebar-brand-text">osxphotos 0.48.0 documentation</span>
<span class="sidebar-brand-text">osxphotos 0.48.2 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">

View File

@@ -4,7 +4,7 @@
<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-4.4.0, furo 2022.04.07"/><title>Python Module Index - osxphotos 0.48.0 documentation</title>
<meta name="generator" content="sphinx-4.4.0, furo 2022.04.07"/><title>Python Module Index - osxphotos 0.48.2 documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=68f4518137b9aefe99b631505a2064c3c42c9852" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
@@ -122,7 +122,7 @@
</label>
</div>
<div class="header-center">
<a href="index.html"><div class="brand">osxphotos 0.48.0 documentation</div></a>
<a href="index.html"><div class="brand">osxphotos 0.48.2 documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@@ -145,7 +145,7 @@
<div class="sidebar-sticky"><a class="sidebar-brand" href="index.html">
<span class="sidebar-brand-text">osxphotos 0.48.0 documentation</span>
<span class="sidebar-brand-text">osxphotos 0.48.2 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">

View File

@@ -6,7 +6,7 @@
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="prev" title="OSXPhotos Python Package Overview" href="package_overview.html" />
<meta name="generator" content="sphinx-4.4.0, furo 2022.04.07"/>
<title>OSXPhotos python API - osxphotos 0.48.0 documentation</title>
<title>OSXPhotos python API - osxphotos 0.48.2 documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=68f4518137b9aefe99b631505a2064c3c42c9852" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
@@ -124,7 +124,7 @@
</label>
</div>
<div class="header-center">
<a href="index.html"><div class="brand">osxphotos 0.48.0 documentation</div></a>
<a href="index.html"><div class="brand">osxphotos 0.48.2 documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@@ -147,7 +147,7 @@
<div class="sidebar-sticky"><a class="sidebar-brand" href="index.html">
<span class="sidebar-brand-text">osxphotos 0.48.0 documentation</span>
<span class="sidebar-brand-text">osxphotos 0.48.2 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">
@@ -1031,6 +1031,11 @@ including folders, albums, etc</p>
<dt class="sig sig-object py" id="osxphotos.MomentInfo">
<em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">osxphotos.</span></span><span class="sig-name descname"><span class="pre">MomentInfo</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">db</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">moment_pk</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/osxphotos/momentinfo.html#MomentInfo"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#osxphotos.MomentInfo" title="Permalink to this definition">#</a></dt>
<dd><p>Info about a photo moment</p>
<dl class="py method">
<dt class="sig sig-object py" id="osxphotos.MomentInfo.asdict">
<span class="sig-name descname"><span class="pre">asdict</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/osxphotos/momentinfo.html#MomentInfo.asdict"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#osxphotos.MomentInfo.asdict" title="Permalink to this definition">#</a></dt>
<dd><p>Returns all moment info as dictionary</p>
</dd></dl>
<dl class="py property">
<dt class="sig sig-object py" id="osxphotos.MomentInfo.date">
<em class="property"><span class="pre">property</span><span class="w"> </span></em><span class="sig-name descname"><span class="pre">date</span></span><a class="headerlink" href="#osxphotos.MomentInfo.date" title="Permalink to this definition">#</a></dt>
@@ -1453,8 +1458,8 @@ only valid on Photos 5, on older libraries returns empty list</p>
<dd><p>returns (latitude, longitude) as float in degrees or None</p>
</dd></dl>
<dl class="py property">
<dt class="sig sig-object py" id="osxphotos.PhotoInfo.moment">
<em class="property"><span class="pre">property</span><span class="w"> </span></em><span class="sig-name descname"><span class="pre">moment</span></span><a class="headerlink" href="#osxphotos.PhotoInfo.moment" title="Permalink to this definition">#</a></dt>
<dt class="sig sig-object py" id="osxphotos.PhotoInfo.moment_info">
<em class="property"><span class="pre">property</span><span class="w"> </span></em><span class="sig-name descname"><span class="pre">moment_info</span></span><a class="headerlink" href="#osxphotos.PhotoInfo.moment_info" title="Permalink to this definition">#</a></dt>
<dd><p>Moment photo belongs to</p>
</dd></dl>
<dl class="py property">

View File

@@ -4,7 +4,7 @@
<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="#" />
<meta name="generator" content="sphinx-4.4.0, furo 2022.04.07"/><title>Search - osxphotos 0.48.0 documentation</title><link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<meta name="generator" content="sphinx-4.4.0, furo 2022.04.07"/><title>Search - osxphotos 0.48.2 documentation</title><link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=68f4518137b9aefe99b631505a2064c3c42c9852" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo-extensions.css?digest=30d1aed668e5c3a91c3e3bf6a60b675221979f0e" />
@@ -121,7 +121,7 @@
</label>
</div>
<div class="header-center">
<a href="index.html"><div class="brand">osxphotos 0.48.0 documentation</div></a>
<a href="index.html"><div class="brand">osxphotos 0.48.2 documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@@ -144,7 +144,7 @@
<div class="sidebar-sticky"><a class="sidebar-brand" href="index.html">
<span class="sidebar-brand-text">osxphotos 0.48.0 documentation</span>
<span class="sidebar-brand-text">osxphotos 0.48.2 documentation</span>
</a><form class="sidebar-search-container" method="get" action="#" role="search">
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">

File diff suppressed because one or more lines are too long

View File

@@ -6,7 +6,7 @@
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="OSXPhotos Python Package Overview" href="package_overview.html" /><link rel="prev" title="OSXPhotos Command Line Interface (CLI)" href="cli.html" />
<meta name="generator" content="sphinx-4.4.0, furo 2022.04.07"/>
<title>OSXPhotos Template System - osxphotos 0.48.0 documentation</title>
<title>OSXPhotos Template System - osxphotos 0.48.2 documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=68f4518137b9aefe99b631505a2064c3c42c9852" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
@@ -124,7 +124,7 @@
</label>
</div>
<div class="header-center">
<a href="index.html"><div class="brand">osxphotos 0.48.0 documentation</div></a>
<a href="index.html"><div class="brand">osxphotos 0.48.2 documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@@ -147,7 +147,7 @@
<div class="sidebar-sticky"><a class="sidebar-brand" href="index.html">
<span class="sidebar-brand-text">osxphotos 0.48.0 documentation</span>
<span class="sidebar-brand-text">osxphotos 0.48.2 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">
@@ -509,124 +509,127 @@
<tr class="row-odd"><td><p>{exif.lens_model}</p></td>
<td><p>Lens model from original photos EXIF information as imported by Photos, e.g. iPhone 6s back camera 4.15mm f/2.2</p></td>
</tr>
<tr class="row-even"><td><p>{uuid}</p></td>
<tr class="row-even"><td><p>{moment}</p></td>
<td><p>The moment title of the photo</p></td>
</tr>
<tr class="row-odd"><td><p>{uuid}</p></td>
<td><p>Photos internal universally unique identifier (UUID) for the photo, a 36-character string unique to the photo, e.g. 128FB4C6-0B16-4E7D-9108-FB2E90DA1546</p></td>
</tr>
<tr class="row-odd"><td><p>{id}</p></td>
<tr class="row-even"><td><p>{id}</p></td>
<td><p>A unique number for the photo based on its primary key in the Photos database. A sequential integer, e.g. 1, 2, 3…etc. Each asset associated with a photo (e.g. an image and Live Photo preview) will share the same id. May be formatted using a python string format code. For example, to format as a 5-digit integer and pad with zeros, use {id:05d} which results in 00001, 00002, 00003…etc.</p></td>
</tr>
<tr class="row-even"><td><p>{album_seq}</p></td>
<tr class="row-odd"><td><p>{album_seq}</p></td>
<td><p>An integer, starting at 0, indicating the photos index (sequence) in the containing album. Only valid when used in a filename template and only when {album} or {folder_album} is used in the directory template. For example directory “{folder_album}” filename “{album<em>seq}</em>{original_name}”’. To start counting at a value other than 0, append append a period and the starting value to the field name. For example, to start counting at 1 instead of 0: {album_seq.1}. May be formatted using a python string format code. For example, to format as a 5-digit integer and pad with zeros, use {album_seq:05d} which results in 00000, 00001, 00002…etc. This may result in incorrect sequences if you have duplicate albums with the same name; see also {folder_album_seq}.</p></td>
</tr>
<tr class="row-odd"><td><p>{folder_album_seq}</p></td>
<tr class="row-even"><td><p>{folder_album_seq}</p></td>
<td><p>An integer, starting at 0, indicating the photos index (sequence) in the containing album and folder path. Only valid when used in a filename template and only when {folder_album} is used in the directory template. For example directory “{folder_album}” filename “{folder_album<em>seq}</em>{original_name}”’. To start counting at a value other than 0, append append a period and the starting value to the field name. For example, to start counting at 1 instead of 0: {folder_album_seq.1} May be formatted using a python string format code. For example, to format as a 5-digit integer and pad with zeros, use {folder_album_seq:05d} which results in 00000, 00001, 00002…etc. This may result in incorrect sequences if you have duplicate albums with the same name in the same folder; see also {album_seq}.</p></td>
</tr>
<tr class="row-even"><td><p>{comma}</p></td>
<tr class="row-odd"><td><p>{comma}</p></td>
<td><p>A comma: ,</p></td>
</tr>
<tr class="row-odd"><td><p>{semicolon}</p></td>
<tr class="row-even"><td><p>{semicolon}</p></td>
<td><p>A semicolon: ;</p></td>
</tr>
<tr class="row-even"><td><p>{questionmark}</p></td>
<tr class="row-odd"><td><p>{questionmark}</p></td>
<td><p>A question mark: ?</p></td>
</tr>
<tr class="row-odd"><td><p>{pipe}</p></td>
<tr class="row-even"><td><p>{pipe}</p></td>
<td><p>A vertical pipe: |</p></td>
</tr>
<tr class="row-even"><td><p>{openbrace}</p></td>
<tr class="row-odd"><td><p>{openbrace}</p></td>
<td><p>An open brace: {</p></td>
</tr>
<tr class="row-odd"><td><p>{closebrace}</p></td>
<tr class="row-even"><td><p>{closebrace}</p></td>
<td><p>A close brace: }</p></td>
</tr>
<tr class="row-even"><td><p>{openparens}</p></td>
<tr class="row-odd"><td><p>{openparens}</p></td>
<td><p>An open parentheses: (</p></td>
</tr>
<tr class="row-odd"><td><p>{closeparens}</p></td>
<tr class="row-even"><td><p>{closeparens}</p></td>
<td><p>A close parentheses: )</p></td>
</tr>
<tr class="row-even"><td><p>{openbracket}</p></td>
<tr class="row-odd"><td><p>{openbracket}</p></td>
<td><p>An open bracket: [</p></td>
</tr>
<tr class="row-odd"><td><p>{closebracket}</p></td>
<tr class="row-even"><td><p>{closebracket}</p></td>
<td><p>A close bracket: ]</p></td>
</tr>
<tr class="row-even"><td><p>{newline}</p></td>
<tr class="row-odd"><td><p>{newline}</p></td>
<td><p>A newline: n</p></td>
</tr>
<tr class="row-odd"><td><p>{lf}</p></td>
<tr class="row-even"><td><p>{lf}</p></td>
<td><p>A line feed: n, alias for {newline}</p></td>
</tr>
<tr class="row-even"><td><p>{cr}</p></td>
<tr class="row-odd"><td><p>{cr}</p></td>
<td><p>A carriage return: r</p></td>
</tr>
<tr class="row-odd"><td><p>{crlf}</p></td>
<tr class="row-even"><td><p>{crlf}</p></td>
<td><p>a carriage return + line feed: rn</p></td>
</tr>
<tr class="row-even"><td><p>{osxphotos_version}</p></td>
<td><p>The osxphotos version, e.g. 0.48.0</p></td>
<tr class="row-odd"><td><p>{osxphotos_version}</p></td>
<td><p>The osxphotos version, e.g. 0.48.2</p></td>
</tr>
<tr class="row-odd"><td><p>{osxphotos_cmd_line}</p></td>
<tr class="row-even"><td><p>{osxphotos_cmd_line}</p></td>
<td><p>The full command line used to run osxphotos</p></td>
</tr>
<tr class="row-even"><td><p>{album}</p></td>
<tr class="row-odd"><td><p>{album}</p></td>
<td><p>Album(s) photo is contained in</p></td>
</tr>
<tr class="row-odd"><td><p>{folder_album}</p></td>
<tr class="row-even"><td><p>{folder_album}</p></td>
<td><p>Folder path + album photo is contained in. e.g. Folder/Subfolder/Album or just Album if no enclosing folder</p></td>
</tr>
<tr class="row-even"><td><p>{project}</p></td>
<tr class="row-odd"><td><p>{project}</p></td>
<td><p>Project(s) photo is contained in (such as greeting cards, calendars, slideshows)</p></td>
</tr>
<tr class="row-odd"><td><p>{album_project}</p></td>
<tr class="row-even"><td><p>{album_project}</p></td>
<td><p>Album(s) and project(s) photo is contained in; treats projects as regular albums</p></td>
</tr>
<tr class="row-even"><td><p>{folder_album_project}</p></td>
<tr class="row-odd"><td><p>{folder_album_project}</p></td>
<td><p>Folder path + album (includes projects as albums) photo is contained in. e.g. Folder/Subfolder/Album or just Album if no enclosing folder</p></td>
</tr>
<tr class="row-odd"><td><p>{keyword}</p></td>
<tr class="row-even"><td><p>{keyword}</p></td>
<td><p>Keyword(s) assigned to photo</p></td>
</tr>
<tr class="row-even"><td><p>{person}</p></td>
<tr class="row-odd"><td><p>{person}</p></td>
<td><p>Person(s) / face(s) in a photo</p></td>
</tr>
<tr class="row-odd"><td><p>{label}</p></td>
<tr class="row-even"><td><p>{label}</p></td>
<td><p>Image categorization label associated with a photo (Photos 5+ only). Labels are added automatically by Photos using machine learning algorithms to categorize images. These are not the same as {keyword} which refers to the user-defined keywords/tags applied in Photos.</p></td>
</tr>
<tr class="row-even"><td><p>{label_normalized}</p></td>
<tr class="row-odd"><td><p>{label_normalized}</p></td>
<td><p>All lower case version of label (Photos 5+ only)</p></td>
</tr>
<tr class="row-odd"><td><p>{comment}</p></td>
<tr class="row-even"><td><p>{comment}</p></td>
<td><p>Comment(s) on shared Photos; format is Person name: comment text (Photos 5+ only)</p></td>
</tr>
<tr class="row-even"><td><p>{exiftool}</p></td>
<tr class="row-odd"><td><p>{exiftool}</p></td>
<td><p>Format: {exiftool:GROUP:TAGNAME}; use exiftool (https://exiftool.org) to extract metadata, in form GROUP:TAGNAME, from image. E.g. {exiftool:EXIF:Make} to get camera make, or {exiftool:IPTC:Keywords} to extract keywords. See https://exiftool.org/TagNames/ for list of valid tag names. You must specify group (e.g. EXIF, IPTC, etc) as used in <code class="docutils literal notranslate"><span class="pre">exiftool</span> <span class="pre">-G</span></code>. exiftool must be installed in the path to use this template.</p></td>
</tr>
<tr class="row-odd"><td><p>{searchinfo.holiday}</p></td>
<tr class="row-even"><td><p>{searchinfo.holiday}</p></td>
<td><p>Holiday names associated with a photo, e.g. Christmas Day; (Photos 5+ only, applied automatically by Photos image categorization algorithms).</p></td>
</tr>
<tr class="row-even"><td><p>{searchinfo.activity}</p></td>
<tr class="row-odd"><td><p>{searchinfo.activity}</p></td>
<td><p>Activities associated with a photo, e.g. Sporting Event; (Photos 5+ only, applied automatically by Photos image categorization algorithms).</p></td>
</tr>
<tr class="row-odd"><td><p>{searchinfo.venue}</p></td>
<tr class="row-even"><td><p>{searchinfo.venue}</p></td>
<td><p>Venues associated with a photo, e.g. name of restaurant; (Photos 5+ only, applied automatically by Photos image categorization algorithms).</p></td>
</tr>
<tr class="row-even"><td><p>{searchinfo.venue_type}</p></td>
<tr class="row-odd"><td><p>{searchinfo.venue_type}</p></td>
<td><p>Venue types associated with a photo, e.g. Restaurant; (Photos 5+ only, applied automatically by Photos image categorization algorithms).</p></td>
</tr>
<tr class="row-odd"><td><p>{photo}</p></td>
<tr class="row-even"><td><p>{photo}</p></td>
<td><p>Provides direct access to the PhotoInfo object for the photo. Must be used in format {photo.property} where property represents a PhotoInfo property. For example: {photo.favorite} is the same as {favorite} and {photo.place.name} is the same as {place.name}. {photo} provides access to properties that are not available as separate template fields but it assumes some knowledge of the underlying PhotoInfo class. See <a class="reference external" href="https://rhettbull.github.io/osxphotos/">https://rhettbull.github.io/osxphotos/</a> for additional documentation on the PhotoInfo class.</p></td>
</tr>
<tr class="row-even"><td><p>{detected_text}</p></td>
<tr class="row-odd"><td><p>{detected_text}</p></td>
<td><p>List of text strings found in the image after performing text detection. Using {detected_text} will cause osxphotos to perform text detection on your photos using the built-in macOS text detection algorithms which will slow down your export. The results for each photo will be cached in the export database so that future exports with update do not need to reprocess each photo. You may pass a confidence threshold value between 0.0 and 1.0 after a colon as in {detected_text:0.5}; The default confidence threshold is 0.75. {detected_text} works only on macOS Catalina (10.15) or later. Note: this feature is not the same thing as Live Text in macOS Monterey, which osxphotos does not yet support.</p></td>
</tr>
<tr class="row-odd"><td><p>{shell_quote}</p></td>
<tr class="row-even"><td><p>{shell_quote}</p></td>
<td><p>Use in form {shell_quote,TEMPLATE}; quotes the rendered TEMPLATE value(s) for safe usage in the shell, e.g. My file.jpeg =&gt; My file.jpeg; only adds quotes if needed.</p></td>
</tr>
<tr class="row-even"><td><p>{strip}</p></td>
<tr class="row-odd"><td><p>{strip}</p></td>
<td><p>Use in form {strip,TEMPLATE}; strips whitespace from begining and end of rendered TEMPLATE value(s).</p></td>
</tr>
<tr class="row-odd"><td><p>{function}</p></td>
<tr class="row-even"><td><p>{function}</p></td>
<td><p>Execute a python function from an external file and use return value as template substitution. Use in format: {function:file.py::function_name} where file.py is the name of the python file and function_name is the name of the function to call. The function will be passed the PhotoInfo object for the photo. See https://github.com/RhetTbull/osxphotos/blob/master/examples/template_function.py for an example of how to implement a template function.</p></td>
</tr>
</tbody>

View File

@@ -6,7 +6,7 @@
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="OSXPhotos Command Line Interface (CLI)" href="cli.html" /><link rel="prev" title="OSXPhotos" href="overview.html" />
<meta name="generator" content="sphinx-4.4.0, furo 2022.04.07"/>
<title>OSXPhotos Tutorial - osxphotos 0.48.0 documentation</title>
<title>OSXPhotos Tutorial - osxphotos 0.48.2 documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=68f4518137b9aefe99b631505a2064c3c42c9852" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
@@ -124,7 +124,7 @@
</label>
</div>
<div class="header-center">
<a href="index.html"><div class="brand">osxphotos 0.48.0 documentation</div></a>
<a href="index.html"><div class="brand">osxphotos 0.48.2 documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@@ -147,7 +147,7 @@
<div class="sidebar-sticky"><a class="sidebar-brand" href="index.html">
<span class="sidebar-brand-text">osxphotos 0.48.0 documentation</span>
<span class="sidebar-brand-text">osxphotos 0.48.2 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">

View File

@@ -281,6 +281,8 @@ Template Substitutions
- Camera model from original photo's EXIF information as imported by Photos, e.g. 'iPhone 6s'
* - {exif.lens_model}
- Lens model from original photo's EXIF information as imported by Photos, e.g. 'iPhone 6s back camera 4.15mm f/2.2'
* - {moment}
- The moment title of the photo
* - {uuid}
- Photo's internal universally unique identifier (UUID) for the photo, a 36-character string unique to the photo, e.g. '128FB4C6-0B16-4E7D-9108-FB2E90DA1546'
* - {id}
@@ -318,7 +320,7 @@ Template Substitutions
* - {crlf}
- a carriage return + line feed: '\r\n'
* - {osxphotos_version}
- The osxphotos version, e.g. '0.48.0'
- The osxphotos version, e.g. '0.48.2'
* - {osxphotos_cmd_line}
- The full command line used to run osxphotos
* - {album}

View File

@@ -0,0 +1,46 @@
"""Example function for use with `osxphotos timewarp --function`
Call this as: `osxphotos timewarp --function timewarp_function_example.py::get_date_time_timezone`
"""
from datetime import datetime, timedelta
from typing import Callable, Optional, Tuple
from photoscript import Photo
def get_date_time_timezone(
photo: Photo, path: Optional[str], tz_sec: int, tz_name: str, verbose: Callable
) -> Tuple[datetime, int]:
"""Example function for use with `osxphotos timewarp --function`
Args:
photo: Photo object
path: path to photo, which may be None if photo is not on disk
tz_sec: timezone offset from UTC in seconds
tz_name: timezone name
verbose: function to print verbose messages
Returns:
tuple of (new date/time as datetime.datetime, and new timezone offset from UTC in seconds as int)
"""
# this example adds 3 hours to the date/time and subtracts 1 hour from the timezone
# the photo's date/time can be accessed as photo.date
# photo.date is a datetime.datetime object
# the date/time is naive (timezone unaware) as will be in local timezone
date = photo.date
# add 3 hours
date = date + timedelta(hours=3)
# subtract 1 hour from timezone
timezone = tz_sec - 3600
# verbose(msg) prints a message to the console if user used --verbose option
# otherwise it does nothing
# photo's filename can be access as photo.filename
verbose(f"Updating {photo.filename} date/time: {date} and timezone: {timezone}")
return date, timezone

View File

@@ -1,3 +1,3 @@
""" version info """
__version__ = "0.48.0"
__version__ = "0.48.2"

View File

@@ -92,7 +92,7 @@ VERSION_CHECK_OPTION = click.option("--no-version-check", required=False, is_fla
DB_OPTION = click.option(
"--db",
required=False,
metavar="<Photos database path>",
metavar="PHOTOS_LIBRARY_PATH",
default=None,
help=(
"Specify Photos database path. "

View File

@@ -505,7 +505,7 @@ from .verbose import get_verbose_console, time_stamp, verbose_print
)
@click.option(
"--report",
metavar="<path to export report>",
metavar="REPORT_FILE",
help="Write a CSV formatted report of all files that were exported.",
type=click.Path(),
)
@@ -600,7 +600,7 @@ from .verbose import get_verbose_console, time_stamp, verbose_print
@click.option(
"--load-config",
required=False,
metavar="<config file path>",
metavar="CONFIG_FILE",
default=None,
help=(
"Load options from file as written with --save-config. "
@@ -615,7 +615,7 @@ from .verbose import get_verbose_console, time_stamp, verbose_print
@click.option(
"--save-config",
required=False,
metavar="<config file path>",
metavar="CONFIG_FILE",
default=None,
help="Save options to file for use with --load-config. File format is TOML. "
"See also --config-only.",

View File

@@ -5,7 +5,7 @@ import os
import sys
from functools import partial
from textwrap import dedent
from typing import Callable
from typing import Callable, Optional
import click
from photoscript import Photo, PhotosLibrary
@@ -20,7 +20,7 @@ from osxphotos.photosalbum import PhotosAlbumPhotoScript
from osxphotos.phototz import PhotoTimeZone, PhotoTimeZoneUpdater
from osxphotos.timeutils import update_datetime
from osxphotos.timezones import Timezone
from osxphotos.utils import pluralize
from osxphotos.utils import noop, pluralize
from .click_rich_echo import (
rich_click_echo,
@@ -34,7 +34,15 @@ from .color_themes import get_theme
from .common import THEME_OPTION
from .darkmode import is_dark_mode
from .help import HELP_WIDTH, rich_text
from .param_types import DateOffset, DateTimeISO8601, TimeOffset, TimeString, UTCOffset
from .param_types import (
DateOffset,
DateTimeISO8601,
FunctionCall,
TimeOffset,
TimeString,
UTCOffset,
)
from .rich_progress import rich_progress
from .verbose import get_verbose_console, verbose_print
# format for pretty printing date/times
@@ -103,6 +111,48 @@ def update_photo_time_for_new_timezone(
)
def update_photo_from_function(
library_path: str,
function: Callable,
verbose_print: Callable,
photo: Photo,
path: Optional[str],
):
"""Update photo from function call"""
photo_tz_sec, _, photo_tz_name = PhotoTimeZone(
library_path=library_path
).get_timezone(photo)
dt_new, tz_new = function(
photo=photo,
path=path,
tz_sec=photo_tz_sec,
tz_name=photo_tz_name,
verbose=verbose_print,
)
if dt_new != photo.date:
old_date = photo.date
photo.date = dt_new
verbose_print(
f"Updated date/time for photo [filename]{photo.filename}[/filename] "
f"([uuid]{photo.uuid}[/uuid]) from: [time]{old_date}[/time] to [time]{dt_new}[/time]"
)
else:
verbose_print(
f"Skipped date/time update for photo [filename]{photo.filename}[/filename] "
f"([uuid]{photo.uuid}[/uuid]): nothing to do"
)
if tz_new != photo_tz_sec:
tz_updater = PhotoTimeZoneUpdater(
timezone=Timezone(tz_new), verbose=verbose_print, library_path=library_path
)
tz_updater.update_photo(photo)
else:
verbose_print(
f"Skipped timezone update for photo [filename]{photo.filename}[/filename] "
f"([uuid]{photo.uuid}[/uuid]): nothing to do"
)
class TimeWarpCommand(click.Command):
"""Custom click.Command that overrides get_help() to show additional help info for export"""
@@ -168,6 +218,11 @@ For this to work, you'll need to install the third-party exiftool (https://exift
`osxphotos timewarp --compare-exif`
**Read the date/time/timezone from the photos' original EXIF metadata to update the photos' date/time/timezone;
if the EXIF data is missing, use the file modification date/time; show verbose output**
`osxphotos timewarp --pull-exif --use-file-time --verbose`
"""
),
width=formatter.width,
@@ -267,9 +322,20 @@ For this to work, you'll need to install the third-party exiftool (https://exift
"Requires the third-party exiftool utility be installed (see https://exiftool.org/). "
"See also --push-exif.",
)
# constraint=RequireAtLeast(1),
# @constraint(mutually_exclusive, ["date", "date_delta"])
# @constraint(mutually_exclusive, ["time", "time_delta"])
@click.option(
"--function",
"-F",
metavar="filename.py::function",
nargs=1,
type=FunctionCall(),
multiple=False,
help="Run python function to determine the date/time/timezone to apply to a photo. "
"Use this in format: --function filename.py::function where filename.py is a python "
"file you've created and function is the name of the function in the python file you want to call. The function will be "
"passed information about the photo being processed and is expected to return "
"a naive datetime.datetime object with time in local time and UTC timezone offset in seconds. "
"See example function at https://github.com/RhetTbull/osxphotos/blob/master/examples/timewarp_function_example.py",
)
@click.option(
"--match-time",
"-m",
@@ -326,9 +392,6 @@ For this to work, you'll need to install the third-party exiftool (https://exift
help="Terminal width in characters.",
hidden=True,
)
# @constraint(mutually_exclusive, ["plain", "mono", "dark", "light"])
# @constraint(If("match_time", then=requires_one), ["timezone"])
# @constraint(If("add_to_album", then=requires_one), ["compare_exif"])
@click.option("--timestamp", is_flag=True, help="Add time stamp to verbose output")
@THEME_OPTION
@click.option(
@@ -336,6 +399,11 @@ For this to work, you'll need to install the third-party exiftool (https://exift
is_flag=True,
help="Plain text mode. Do not use rich output.",
)
@click.option(
"--force",
is_flag=True,
help="Bypass confirmation prompt. Use with caution.",
)
def timewarp(
date,
date_delta,
@@ -346,6 +414,7 @@ def timewarp(
compare_exif,
push_exif,
pull_exif,
function,
match_time,
use_file_time,
add_to_album,
@@ -357,15 +426,51 @@ def timewarp(
output_file,
terminal_width,
timestamp,
force,
):
"""Adjust date/time/timezone of photos in Apple Photos.
Changes will be applied to all photos currently selected in Photos.
timewarp cannot operate on photos selected in a Smart Album;
select photos in a regular album or in the 'All Photos' view.
select photos in a regular album or in the 'All Photos' view.
See Timewarp Overview below for additional information.
"""
# check constraints
if not any(
[
date,
date_delta,
time,
time_delta,
timezone,
inspect,
compare_exif,
push_exif,
pull_exif,
function,
]
):
raise click.UsageError(
"At least one of --date, --date-delta, --time, --time-delta, "
"--timezone, --inspect, --compare-exif, --push-exif, --pull-exif, --function "
"must be specified."
)
if date and date_delta:
raise click.UsageError("--date and --date-delta are mutually exclusive.")
if time and time_delta:
raise click.UsageError("--time and --time-delta are mutually exclusive.")
if match_time and not timezone:
raise click.UsageError("--match-time must be used with --timezone.")
if add_to_album and not compare_exif:
raise click.UsageError("--add-to-album must be used with --compare-exif.")
# configure colored rich output
# TODO: this is all a little hacky, find a better way to do this
color_theme = get_theme(theme)
verbose_ = verbose_print(
verbose,
@@ -381,10 +486,15 @@ def timewarp(
set_rich_console(Console(file=output_file, width=terminal_width))
elif terminal_width:
set_rich_console(
Console(file=sys.stdout, force_terminal=True, width=terminal_width)
Console(
file=sys.stdout,
theme=color_theme,
force_terminal=True,
width=terminal_width,
)
)
else:
set_rich_console(get_verbose_console())
set_rich_console(get_verbose_console(theme=color_theme))
set_rich_theme(color_theme)
if any([compare_exif, push_exif, pull_exif]):
@@ -411,6 +521,35 @@ def timewarp(
)
sys.exit(1)
# confirm with user before proceeding
if (
any(
[
date,
date_delta,
time,
time_delta,
timezone,
push_exif,
pull_exif,
function,
]
)
and not force
):
click.confirm(
rich_text(
f":warning-emoji: About to process [num]{len(photos)}[/] {pluralize(len(photos), 'photo', 'photos')} with timewarp. "
"This will directly modify your Photos library database using undocumented features. "
"While this functionality has been well tested, it is possible this may "
"corrupt, damage, or destroy your Photos library. [bold]Use at your own caution. No warranty is implied or provided.[/] "
"It is strongly recommended you make a backup of your Photos library before using the timewarp command "
"(for example, using Time Machine).\n\n"
"Proceed with timewarp?"
),
abort=True,
)
update_photo_date_time_ = partial(
update_photo_date_time,
date=date,
@@ -426,6 +565,16 @@ def timewarp(
verbose_print=verbose_,
)
if function:
update_photo_from_function_ = partial(
update_photo_from_function,
library_path=library,
function=function[0],
verbose_print=verbose_,
)
else:
update_photo_from_function_ = noop
if inspect:
tzinfo = PhotoTimeZone(library_path=library)
if photos:
@@ -456,10 +605,11 @@ def timewarp(
)
for photo in photos:
diff_results = (
photocomp.compare_exif_with_markup(photo)
if not plain
else photocomp.compare_exif_no_markup(photo)
photocomp.compare_exif_no_markup(photo)
if plain
else photocomp.compare_exif_with_markup(photo)
)
if not plain:
filename = (
f"[change]{photo.filename}[/change]"
@@ -497,7 +647,8 @@ def timewarp(
timezone, verbose=verbose_, library_path=library
)
if any([push_exif, pull_exif]):
if any([push_exif, pull_exif, function]):
# ExifDateTimeUpdater used to get photo path for --function
exif_updater = ExifDateTimeUpdater(
library_path=library,
verbose=verbose_,
@@ -505,11 +656,13 @@ def timewarp(
plain=plain,
)
rich_echo(f"Processing {len(photos)} {pluralize(len(photos), 'photo', 'photos')}")
# send progress bar output to /dev/null if verbose to hide the progress bar
fp = open(os.devnull, "w") if verbose else None
with click.progressbar(photos, file=fp) as bar:
for p in bar:
num_photos = len(photos)
with rich_progress(console=get_verbose_console(), mock=verbose) as progress:
task = progress.add_task(
f"Processing [num]{num_photos}[/] {pluralize(len(photos), 'photo', 'photos')}",
total=num_photos,
)
for p in photos:
if pull_exif:
exif_updater.update_photos_from_exif(
p, use_file_modify_date=use_file_time
@@ -522,6 +675,10 @@ def timewarp(
update_photo_time_for_new_timezone_(photo=p, new_timezone=timezone)
if timezone:
tz_updater.update_photo(p)
if function:
verbose_(f"Calling function [bold]{function[1]}")
photo_path = exif_updater.get_photo_path(p)
update_photo_from_function_(photo=p, path=photo_path)
if push_exif:
# this should be the last step in the if chain to ensure all Photos data is updated
# before exiftool is run
@@ -533,10 +690,6 @@ def timewarp(
if exif_error:
rich_echo_error(f"[error]Error running exiftool: {exif_error}[/]")
if fp is not None:
fp.close()
progress.advance(task)
rich_echo("Done.")
# if output_file:
# output_file.close()

View File

@@ -43,15 +43,18 @@ def noop(*args, **kwargs):
pass
def get_verbose_console() -> Console:
"""Get console object
def get_verbose_console(theme: t.Optional[Theme] = None) -> Console:
"""Get console object or create one if not already created
Args:
theme: optional rich.theme.Theme object to use for formatting
Returns:
Console object
"""
global _console
if _console.console is None:
_console.console = Console(force_terminal=True)
_console.console = Console(force_terminal=True, theme=theme)
return _console.console

Binary file not shown.

View File

@@ -247,6 +247,18 @@ class ExifDateTimeUpdater:
exif, use_file_modify_date=use_file_modify_date
)
def get_photo_path(self, photo: Photo) -> Optional[str]:
"""Get the path to a photo
Args:
photo: photoscript.Photo object to act on
Returns:
str: path to photo or None if not found
"""
_photo = self.db.get_photo(photo.uuid)
return _photo.path if _photo else None
def get_exif_date_time_offset(
exif: Dict, use_file_modify_date: bool = False

View File

@@ -68,3 +68,19 @@ class MomentInfo:
self._photos = self._db.photos_by_uuid(photo_uuids)
return self._photos
def asdict(self):
"""Returns all moment info as dictionary"""
return {
"pk": self.pk,
"location": self.location,
"title": self.title,
"subtitle": self.subtitle,
"start_date": self.start_date.isoformat() if self.start_date else None,
"end_date": self.end_date.isoformat() if self.end_date else None,
"date": self.date.isoformat() if self.date else None,
"modification_date": self.modification_date.isoformat()
if self.modification_date
else None,
"photos": self.photos,
}

View File

@@ -479,7 +479,7 @@ class PhotoInfo:
return self._faceinfo
@property
def moment(self):
def moment_info(self):
"""Moment photo belongs to"""
try:
return self._moment

View File

@@ -14,8 +14,8 @@ import tempfile
from collections import OrderedDict
from collections.abc import Iterable
from datetime import datetime, timedelta, timezone
from pprint import pformat
from typing import List
from unicodedata import normalize
import bitmath
import photoscript
@@ -2566,8 +2566,16 @@ class PhotosDB:
moment_info[date_name] = moment_date.astimezone(tz=tz)
# process title/subtitle
moment_info["title"] = moment_info["title"] or ""
moment_info["subtitle"] = moment_info["subtitle"] or ""
# use unicodedata.normalize with KFKC instead of normalize_unicode as is done elsewhere
# to replace non-breaking whitespace chars with spaces as Photos uses \xa0 as space in Moment titles, subtitles
moment_info["title"] = (
normalize("NFKC", moment_info["title"]) if moment_info["title"] else ""
)
moment_info["subtitle"] = (
normalize("NFKC", moment_info["subtitle"])
if moment_info["subtitle"]
else ""
)
self._db_moment_pk[moment_info["pk"]] = moment_info

View File

@@ -138,6 +138,7 @@ TEMPLATE_SUBSTITUTIONS = {
"{exif.camera_make}": "Camera make from original photo's EXIF information as imported by Photos, e.g. 'Apple'",
"{exif.camera_model}": "Camera model from original photo's EXIF information as imported by Photos, e.g. 'iPhone 6s'",
"{exif.lens_model}": "Lens model from original photo's EXIF information as imported by Photos, e.g. 'iPhone 6s back camera 4.15mm f/2.2'",
"{moment}": "The moment title of the photo",
"{uuid}": "Photo's internal universally unique identifier (UUID) for the photo, a 36-character string unique to the photo, e.g. '128FB4C6-0B16-4E7D-9108-FB2E90DA1546'",
"{id}": "A unique number for the photo based on its primary key in the Photos database. "
+ "A sequential integer, e.g. 1, 2, 3...etc. Each asset associated with a photo (e.g. an image and Live Photo preview) will share the same id. "
@@ -974,6 +975,8 @@ class PhotoTemplate:
value = self.photo.exif_info.camera_model if self.photo.exif_info else None
elif field == "exif.lens_model":
value = self.photo.exif_info.lens_model if self.photo.exif_info else None
elif field == "moment":
value = self.photo.moment_info.title if self.photo.moment_info else None
elif field == "uuid":
value = self.photo.uuid
elif field == "id":

View File

@@ -149,7 +149,7 @@ class PhotoTimeZoneUpdater:
conn.commit()
self.verbose(
f"Updated timezone for photo [filename]{photo.filename}[/filename] ([uuid]{photo.uuid}[/uuid]) "
+ f"from [tz]{[tz_name]}[/tz], offset=[tz]{tz_offset}[/tz] "
+ f"from [tz]{tz_name}[/tz], offset=[tz]{tz_offset}[/tz] "
+ f"to [tz]{self.tz_name}[/tz], offset=[tz]{self.tz_offset}[/tz]"
)
except Exception as e:

View File

@@ -1,11 +1,20 @@
""" Test data for timewarp command on Catalina/Photos 5 """
import datetime
import pathlib
from tests.parse_timewarp_output import CompareValues, InspectValues
TEST_LIBRARY_TIMEWARP = "tests/TestTimeWarp-10.15.7.photoslibrary"
def get_file_timestamp(file: str) -> str:
"""Get timestamp of file"""
return datetime.datetime.fromtimestamp(pathlib.Path(file).stat().st_mtime).strftime(
"%Y-%m-%d %H:%M:%S"
)
CATALINA_PHOTOS_5 = {
"filenames": {
"pumpkins": "IMG_6522.jpeg",
@@ -258,7 +267,9 @@ CATALINA_PHOTOS_5 = {
"post": CompareValues(
"IMG_6506.jpeg",
"7E9DF2EE-A5B0-4077-80EC-30565221A3B9",
"2021-10-08 16:11:09",
get_file_timestamp(
f"{TEST_LIBRARY_TIMEWARP}/originals/7/7E9DF2EE-A5B0-4077-80EC-30565221A3B9.jpeg"
),
"",
"-0700",
"",
@@ -302,7 +313,7 @@ CATALINA_PHOTOS_5 = {
"parameters": [("-0200", "2021-10-04 23:00:00-0200")]
},
"video_push_exif": {
# IMG_6501.jpeg
# IMG_6551.mov
"pre": CompareValues(
"IMG_6551.mov",
"16BEC0BE-4188-44F1-A8F1-7250E978AD12",
@@ -321,7 +332,7 @@ CATALINA_PHOTOS_5 = {
),
},
"video_pull_exif": {
# IMG_6501.jpeg
# IMG_6551.jpeg
"pre": CompareValues(
"IMG_6551.mov",
"16BEC0BE-4188-44F1-A8F1-7250E978AD12",
@@ -339,4 +350,16 @@ CATALINA_PHOTOS_5 = {
"-0200",
),
},
"function": {
# IMG_6501.jpeg
"uuid": "2F00448D-3C0D-477A-9B10-5F21DCAB405A",
"expected": InspectValues(
"IMG_6501.jpeg",
"2F00448D-3C0D-477A-9B10-5F21DCAB405A",
"2020-09-01 18:53:02-0700",
"2020-09-01 18:53:02-0700",
"-0700",
"GMT-0700",
),
},
}

View File

@@ -175,6 +175,19 @@ PATH_HEIC_EDITED = (
UUID_IS_REFERENCE = "A1DD1F98-2ECD-431F-9AC9-5AFEFE2D3A5C"
UUID_NOT_REFERENCE = "E9BC5C36-7CD1-40A1-A72B-8B8FAC227D51"
UUID_MOMENT = {
"3DD2C897-F19E-4CA6-8C22-B027D5A71907": {
"uuid": "3DD2C897-F19E-4CA6-8C22-B027D5A71907",
"location": (-34.91889167000001, 138.59686167),
"title": "Adelaide",
"subtitle": "",
"start_date": "2017-06-20T17:18:56.518000+09:30",
"end_date": "2017-06-20T17:18:56.518000+09:30",
"date": "2017-06-20T17:18:56.518000+09:30",
"modification_date": "2020-04-06T15:22:24.595584+09:30",
}
}
@pytest.fixture(scope="module")
def photosdb():
@@ -1125,3 +1138,17 @@ def test_no_adjustments(photosdb):
photo = photosdb.get_photo(UUID_DICT["no_adjustments"])
assert photo.adjustments is None
@pytest.mark.parametrize("info", UUID_MOMENT.values())
def test_moment(photosdb, info):
"""test PhotoInfo.moment"""
photo = photosdb.get_photo(uuid=info["uuid"])
assert photo.moment_info.title == info["title"]
assert photo.moment_info.asdict()["title"] == info["title"]
assert photo.moment_info.subtitle == info["subtitle"]
assert photo.moment_info.location == info["location"]
assert photo.moment_info.start_date.isoformat() == info["start_date"]
assert photo.moment_info.end_date.isoformat() == info["end_date"]
assert photo.moment_info.date.isoformat() == info["date"]
assert photo.moment_info.modification_date.isoformat() == info["modification_date"]

View File

@@ -259,6 +259,19 @@ UUID_DETECTED_TEXT = {
"A92D9C26-3A50-4197-9388-CB5F7DB9FA91": None,
}
UUID_MOMENT = {
"7FD37B5F-6FAA-4DB1-8A29-BF9C37E38091": {
"uuid": "7FD37B5F-6FAA-4DB1-8A29-BF9C37E38091",
"location": (20.687278329999998, -156.44366333),
"title": "Hawaiian Islands",
"subtitle": "",
"start_date": "2019-09-15T18:37:17.287000-10:00",
"end_date": "2019-09-15T18:37:17.287000-10:00",
"date": "2019-09-15T18:37:17.287000-10:00",
"modification_date": "2022-02-04T03:51:25.161460-10:00",
}
}
@pytest.fixture(scope="module")
def photosdb():
@@ -1459,3 +1472,17 @@ def test_detected_text(photosdb):
assert expected_text in detected_text
else:
assert not detected_text
@pytest.mark.parametrize("info", UUID_MOMENT.values())
def test_moment(photosdb, info):
"""test PhotoInfo.moment"""
photo = photosdb.get_photo(uuid=info["uuid"])
assert photo.moment_info.title == info["title"]
assert photo.moment_info.asdict()["title"] == info["title"]
assert photo.moment_info.subtitle == info["subtitle"]
assert photo.moment_info.location == info["location"]
assert photo.moment_info.start_date.isoformat() == info["start_date"]
assert photo.moment_info.end_date.isoformat() == info["end_date"]
assert photo.moment_info.date.isoformat() == info["date"]
assert photo.moment_info.modification_date.isoformat() == info["modification_date"]

View File

@@ -90,31 +90,6 @@ UUID_DOWNLOAD_MISSING = "C6C712C5-9316-408D-A3C3-125661422DA9" # IMG_8844.JPG
UUID_FILE = "tests/uuid_from_file.txt"
SKIP_UUID_FILE = "tests/skip_uuid_from_file.txt"
CLI_OUTPUT_NO_SUBCOMMAND = [
"Options:",
"--db <Photos database path> Specify Photos database path. Path to Photos",
"library/database can be specified using either",
"--db or directly as PHOTOS_LIBRARY positional",
"argument.",
"--json Print output in JSON format.",
"-v, --version Show the version and exit.",
"-h, --help Show this message and exit.",
"Commands:",
" albums Print out albums found in the Photos library.",
" dump Print list of all photos & associated info from the Photos",
" export Export photos from the Photos database.",
" help Print help; for help on commands: help <command>.",
" info Print out descriptive info of the Photos library database.",
" install Install Python packages into the same environment as osxphotos",
" keywords Print out keywords found in the Photos library",
" labels Print out image classification labels found in the Photos",
" list Print list of Photos libraries found on the system.",
" persons Print out persons (faces) found in the Photos library.",
" places Print out places found in the Photos library.",
" query Query the Photos database using 1 or more search options; if",
" uninstall Uninstall Python packages from the osxphotos environment",
]
CLI_OUTPUT_QUERY_UUID = '[{"uuid": "D79B8D77-BFFC-460B-9312-034F2877D35B", "filename": "D79B8D77-BFFC-460B-9312-034F2877D35B.jpeg", "original_filename": "Pumkins2.jpg", "date": "2018-09-28T16:07:07-04:00", "description": "Girl holding pumpkin", "title": "I found one!", "keywords": ["Kids"], "albums": ["Pumpkin Farm", "Test Album", "Multi Keyword"], "persons": ["Katie"], "path": "/tests/Test-10.15.7.photoslibrary/originals/D/D79B8D77-BFFC-460B-9312-034F2877D35B.jpeg", "ismissing": false, "hasadjustments": false, "external_edit": false, "favorite": false, "hidden": false, "latitude": 41.256566, "longitude": -95.940257, "path_edited": null, "shared": false, "isphoto": true, "ismovie": false, "uti": "public.jpeg", "burst": false, "live_photo": false, "path_live_photo": null, "iscloudasset": false, "incloud": null}]'
CLI_EXPORT_FILENAMES = [
@@ -1066,11 +1041,9 @@ def test_osxphotos():
runner = CliRunner()
result = runner.invoke(cli_main, [])
output = result.output
assert result.exit_code == 0
for line in CLI_OUTPUT_NO_SUBCOMMAND:
assert line.strip() in output
assert "Print information about osxphotos" in result.output
def test_osxphotos_help_1():
@@ -1078,10 +1051,8 @@ def test_osxphotos_help_1():
runner = CliRunner()
result = runner.invoke(cli_main, ["help"])
output = result.output
assert result.exit_code == 0
for line in CLI_OUTPUT_NO_SUBCOMMAND:
assert line.strip() in output
assert "Print information about osxphotos" in result.output
def test_osxphotos_help_2():

View File

@@ -46,7 +46,7 @@ def ask_user_to_make_selection(
video: set to True if asking for a video instead of a photo
"""
# needs to be called with a suspend_capture fixture
photo_or_video = "photo" if not video else "video"
photo_or_video = "video" if video else "photo"
tries = 0
while tries < retry:
with suspend_capture:
@@ -935,3 +935,35 @@ def test_video_pull_exif(photoslib, suspend_capture, output_file):
)
output_values = parse_compare_exif(output_file)
assert output_values[0] == post_test
@pytest.mark.timewarp
def test_select_pears_3(photoslib, suspend_capture):
"""Force user to select the right photo for following tests"""
assert ask_user_to_make_selection(photoslib, suspend_capture, "pears")
@pytest.mark.timewarp
def test_function(photoslib, suspend_capture, output_file):
"""Test timewarp function"""
from osxphotos.cli.timewarp import timewarp
expected = TEST_DATA["function"]["expected"]
runner = CliRunner()
result = runner.invoke(
timewarp,
[
"--function",
"tests/timewarp_function_example.py::get_date_time_timezone",
],
terminal_width=TERMINAL_WIDTH,
)
assert result.exit_code == 0
result = runner.invoke(
timewarp,
["--inspect", "--plain", "-o", output_file],
terminal_width=TERMINAL_WIDTH,
)
output_values = parse_inspect_output(output_file)
assert output_values[0] == expected

View File

@@ -180,6 +180,19 @@ PATH_HEIC_EDITED = (
UUID_IS_REFERENCE = "A1DD1F98-2ECD-431F-9AC9-5AFEFE2D3A5C"
UUID_NOT_REFERENCE = "E9BC5C36-7CD1-40A1-A72B-8B8FAC227D51"
UUID_MOMENT = {
"3DD2C897-F19E-4CA6-8C22-B027D5A71907": {
"uuid": "3DD2C897-F19E-4CA6-8C22-B027D5A71907",
"location": (-34.91889167000001, 138.59686167),
"title": "Adelaide",
"subtitle": "",
"start_date": "2017-06-20T17:18:56.518000+09:30",
"end_date": "2017-06-20T17:18:56.518000+09:30",
"date": "2017-06-20T17:18:56.518000+09:30",
"modification_date": "2020-04-06T15:22:24.595584+09:30",
}
}
@pytest.fixture(scope="module")
def photosdb():
@@ -1130,3 +1143,17 @@ def test_no_adjustments(photosdb):
photo = photosdb.get_photo(UUID_DICT["no_adjustments"])
assert photo.adjustments is None
@pytest.mark.parametrize("info", UUID_MOMENT.values())
def test_moment(photosdb, info):
"""test PhotoInfo.moment"""
photo = photosdb.get_photo(uuid=info["uuid"])
assert photo.moment_info.title == info["title"]
assert photo.moment_info.asdict()["title"] == info["title"]
assert photo.moment_info.subtitle == info["subtitle"]
assert photo.moment_info.location == info["location"]
assert photo.moment_info.start_date.isoformat() == info["start_date"]
assert photo.moment_info.end_date.isoformat() == info["end_date"]
assert photo.moment_info.date.isoformat() == info["date"]
assert photo.moment_info.modification_date.isoformat() == info["modification_date"]

View File

@@ -333,7 +333,9 @@ UUID_CONDITIONAL = {
"{photo.score.overall >= 0.7?YES,NO}": ["NO"],
"{photo.score.overall not < 0.7?YES,NO}": ["NO"],
"{folder_album(-) contains Folder1-SubFolder2-AlbumInFolder?YES,NO}": ["YES"],
"{folder_album( - ) contains Folder1 - SubFolder2 - AlbumInFolder?YES,NO}": ["YES"],
"{folder_album( - ) contains Folder1 - SubFolder2 - AlbumInFolder?YES,NO}": [
"YES"
],
"{folder_album(-)[In,] contains Folder1-SubFolder2-AlbumFolder?YES,NO}": [
"YES"
],
@@ -395,6 +397,14 @@ UUID_ALBUM_SEQ = {
},
}
UUID_MOMENT = {
"7FD37B5F-6FAA-4DB1-8A29-BF9C37E38091": {
"templates": {
"{moment}": ["Hawaiian Islands"],
}
}
}
UUID_EMPTY_TITLE = "7783E8E6-9CAC-40F3-BE22-81FB7051C266" # IMG_3092.heic
UUID_EMPTY_TITLE_HAS_DESCRIPTION = "E9BC5C36-7CD1-40A1-A72B-8B8FAC227D51" # wedding.jpg
@@ -1243,3 +1253,12 @@ def test_no_project(photosdb_project):
for template, value in TEMPLATE_VALUES_NO_PROJECT.items():
rendered, _ = photo.render_template(template)
assert rendered == value
def test_moment(photosdb):
"""Test {moment} template"""
for uuid in UUID_MOMENT:
photo = photosdb.get_photo(uuid)
for template, value in UUID_MOMENT[uuid]["templates"].items():
rendered, _ = photo.render_template(template)
assert rendered == value

View File

@@ -0,0 +1,46 @@
"""Example function for use with `osxphotos timewarp --function`
Call this as: `osxphotos timewarp --function timewarp_function_example.py::get_date_time_timezone`
"""
from datetime import datetime, timedelta
from typing import Callable, Optional, Tuple
from photoscript import Photo
def get_date_time_timezone(
photo: Photo, path: Optional[str], tz_sec: int, tz_name: str, verbose: Callable
) -> Tuple[datetime, int]:
"""Example function for use with `osxphotos timewarp --function`
Args:
photo: Photo object
path: path to photo, which may be None if photo is not on disk
tz_sec: timezone offset from UTC in seconds
tz_name: timezone name
verbose: function to print verbose messages
Returns:
tuple of (new date/time as datetime.datetime, and new timezone offset from UTC in seconds as int)
"""
# this example adds 3 hours to the date/time and subtracts 1 hour from the timezone
# the photo's date/time can be accessed as photo.date
# photo.date is a datetime.datetime object
# the date/time is naive (timezone unaware) as will be in local timezone
date = photo.date
# add 3 hours
date = date + timedelta(hours=3)
# subtract 1 hour from timezone
timezone = tz_sec - 3600
# verbose(msg) prints a message to the console if user used --verbose option
# otherwise it does nothing
# photo's filename can be access as photo.filename
verbose(f"Updating {photo.filename} date/time: {date} and timezone: {timezone}")
return date, timezone