Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ff2e810d49 | ||
|
|
026e90a8ed | ||
|
|
95103f7c8d | ||
|
|
57deb23988 | ||
|
|
4533057142 | ||
|
|
3ed658a7d0 | ||
|
|
fa991b8b48 |
@@ -1943,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.2'|
|
||||
|{osxphotos_version}|The osxphotos version, e.g. '0.48.4'|
|
||||
|{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|
|
||||
|
||||
15
CHANGELOG.md
15
CHANGELOG.md
@@ -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.3](https://github.com/RhetTbull/osxphotos/compare/v0.48.2...v0.48.3)
|
||||
|
||||
> 5 May 2022
|
||||
|
||||
- Added --added-after, --added-before, --added-in-last, #439 [`#683`](https://github.com/RhetTbull/osxphotos/pull/683)
|
||||
- Updated to pytimeparse2, added tests for custom Click param types [`3ed658a`](https://github.com/RhetTbull/osxphotos/commit/3ed658a7d018b5ac61c1054e20a59576e8613609)
|
||||
|
||||
#### [v0.48.2](https://github.com/RhetTbull/osxphotos/compare/v0.48.1...v0.48.2)
|
||||
|
||||
> 3 May 2022
|
||||
|
||||
- Added moment_info, #71 [`9bc5890`](https://github.com/RhetTbull/osxphotos/commit/9bc5890589b7ff45d7b1e8bca4f958a6b4dc5fad)
|
||||
- Added --force to timewarp to bypass confirmation [`f42bee8`](https://github.com/RhetTbull/osxphotos/commit/f42bee84c08cf8c6883058a8c2d45dfe9c3e2357)
|
||||
- Added confirmation for timewarp, #677 [`ac67ef2`](https://github.com/RhetTbull/osxphotos/commit/ac67ef23846fb2a35211be8b63f5201a5567c68e)
|
||||
|
||||
#### [v0.48.1](https://github.com/RhetTbull/osxphotos/compare/v0.48.0...v0.48.1)
|
||||
|
||||
> 1 May 2022
|
||||
|
||||
32
README.md
32
README.md
@@ -472,6 +472,10 @@ You can also export photos in a certain date range:
|
||||
|
||||
`osxphotos export /path/to/export --from-date "2020-01-01" --to-date "2020-02-28"`
|
||||
|
||||
or photos added to the library in the last week:
|
||||
|
||||
`osxphotos export /path/to/export --added-in-last "1 week"`
|
||||
|
||||
#### Converting images to JPEG on export
|
||||
|
||||
Photos can store images in many different formats. osxphotos can convert non-JPEG images (for example, RAW photos) to JPEG on export using the `--convert-to-jpeg` option. You can specify the JPEG quality (0: worst, 1.0: best) using `--jpeg-quality`. For example:
|
||||
@@ -742,6 +746,26 @@ Options:
|
||||
--year 2022 to find all photos from the year
|
||||
2022. May be repeated to search multiple
|
||||
years.
|
||||
--added-before DATE Search for items added to the library before a
|
||||
specific date/time, e.g. --added-before e.g.
|
||||
2000-01-12T12:00:00,
|
||||
2001-01-12T12:00:00-07:00, or 2000-12-31 (ISO
|
||||
8601 with/without timezone).
|
||||
--added-after DATE Search for items added to the libray after a
|
||||
specific date/time, e.g. --added-after e.g.
|
||||
2000-01-12T12:00:00,
|
||||
2001-01-12T12:00:00-07:00, or 2000-12-31 (ISO
|
||||
8601 with/without timezone).
|
||||
--added-in-last TIME_DELTA Search for items added to the library in the
|
||||
last TIME_DELTA, where TIME_DELTA is a string
|
||||
like '12 hrs', '1 day', '1d', '1 week',
|
||||
'2weeks', '1 month', '1 year'. for example,
|
||||
`--added-in-last 7d` and `--added-in-last '1
|
||||
week'` are equivalent. months are assumed to
|
||||
be 30 days and years are assumed to be 365
|
||||
days. Common English abbreviations are
|
||||
accepted, e.g. d, day, days or m, min,
|
||||
minutes.
|
||||
--has-comment Search for photos that have comments.
|
||||
--no-comment Search for photos with no comments.
|
||||
--has-likes Search for photos that have likes.
|
||||
@@ -1807,7 +1831,7 @@ Substitution Description
|
||||
{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.2'
|
||||
{osxphotos_version} The osxphotos version, e.g. '0.48.4'
|
||||
{osxphotos_cmd_line} The full command line used to run osxphotos
|
||||
|
||||
The following substitutions may result in multiple values. Thus if specified
|
||||
@@ -2957,6 +2981,9 @@ Returns a [ScoreInfo](#scoreinfo) data class object which provides access to the
|
||||
|
||||
Returns list of PhotoInfo objects for *possible* duplicates or empty list if no matching duplicates. Photos are considered possible duplicates if the photo's original file size, date created, height, and width match another those of another photo. This does not do a byte-for-byte comparison or compute a hash which makes it fast and allows for identification of possible duplicates even if originals are not downloaded from iCloud. The signature-based approach should be robust enough to match duplicates created either through the "duplicate photo" menu item or imported twice into the library but you should not rely on this 100% for identification of all duplicates.
|
||||
|
||||
#### `hexdigest`
|
||||
Returns a unique digest of the photo's properties and metadata; useful for detecting changes in any property/metadata of the photo.
|
||||
|
||||
#### `json()`
|
||||
|
||||
Returns a JSON representation of all photo info.
|
||||
@@ -3970,7 +3997,7 @@ The following template field substitutions are availabe for use the templating s
|
||||
|{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.2'|
|
||||
|{osxphotos_version}|The osxphotos version, e.g. '0.48.4'|
|
||||
|{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|
|
||||
@@ -4150,6 +4177,7 @@ Attributes:
|
||||
* exiftool_error: list of errors generated by exiftool during export
|
||||
* xattr_written: list of files with extended attributes written during export
|
||||
* xattr_skipped: list of files where extended attributes were skipped when update=True
|
||||
* metadata_changed: list of files where metadata changed since last export
|
||||
* deleted_files: reserved for use by osxphotos CLI
|
||||
* deleted_directories: reserved for use by osxphotos CLI
|
||||
* exported_album: reserved for use by osxphotos CLI
|
||||
|
||||
@@ -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: 80f83a536e4014ef4d71db9e7d4e82e8
|
||||
config: 8e75e979ef179f86aec0b772d60e05d7
|
||||
tags: 645f666f9bcd5a90fca523b33c5a78b7
|
||||
|
||||
@@ -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.2 documentation</title>
|
||||
<title>Overview: module code - osxphotos 0.48.4 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.2 documentation</div></a>
|
||||
<a href="../index.html"><div class="brand">osxphotos 0.48.4 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.2 documentation</span>
|
||||
<span class="sidebar-brand-text">osxphotos 0.48.4 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">
|
||||
|
||||
@@ -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.momentinfo - osxphotos 0.48.1 documentation</title>
|
||||
<title>osxphotos.momentinfo - osxphotos 0.48.3 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.1 documentation</div></a>
|
||||
<a href="../../index.html"><div class="brand">osxphotos 0.48.3 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.1 documentation</span>
|
||||
<span class="sidebar-brand-text">osxphotos 0.48.3 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">
|
||||
|
||||
@@ -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.photoexporter - osxphotos 0.47.9 documentation</title>
|
||||
<title>osxphotos.photoexporter - osxphotos 0.48.3 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.3 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.3 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>
|
||||
@@ -197,13 +198,11 @@
|
||||
<span class="sd">"""</span>
|
||||
|
||||
<span class="kn">import</span> <span class="nn">dataclasses</span>
|
||||
<span class="kn">import</span> <span class="nn">hashlib</span>
|
||||
<span class="kn">import</span> <span class="nn">json</span>
|
||||
<span class="kn">import</span> <span class="nn">logging</span>
|
||||
<span class="kn">import</span> <span class="nn">os</span>
|
||||
<span class="kn">import</span> <span class="nn">pathlib</span>
|
||||
<span class="kn">import</span> <span class="nn">re</span>
|
||||
<span class="kn">import</span> <span class="nn">tempfile</span>
|
||||
<span class="kn">import</span> <span class="nn">typing</span> <span class="k">as</span> <span class="nn">t</span>
|
||||
<span class="kn">from</span> <span class="nn">collections</span> <span class="kn">import</span> <span class="n">namedtuple</span> <span class="c1"># pylint: disable=syntax-error</span>
|
||||
<span class="kn">from</span> <span class="nn">dataclasses</span> <span class="kn">import</span> <span class="n">asdict</span><span class="p">,</span> <span class="n">dataclass</span>
|
||||
@@ -240,14 +239,13 @@
|
||||
<span class="kn">from</span> <span class="nn">.phototemplate</span> <span class="kn">import</span> <span class="n">RenderOptions</span>
|
||||
<span class="kn">from</span> <span class="nn">.rich_utils</span> <span class="kn">import</span> <span class="n">add_rich_markup_tag</span>
|
||||
<span class="kn">from</span> <span class="nn">.uti</span> <span class="kn">import</span> <span class="n">get_preferred_uti_extension</span>
|
||||
<span class="kn">from</span> <span class="nn">.utils</span> <span class="kn">import</span> <span class="n">increment_filename</span><span class="p">,</span> <span class="n">lineno</span><span class="p">,</span> <span class="n">list_directory</span>
|
||||
<span class="kn">from</span> <span class="nn">.utils</span> <span class="kn">import</span> <span class="n">hexdigest</span><span class="p">,</span> <span class="n">increment_filename</span><span class="p">,</span> <span class="n">lineno</span><span class="p">,</span> <span class="n">list_directory</span>
|
||||
|
||||
<span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span>
|
||||
<span class="s2">"ExportError"</span><span class="p">,</span>
|
||||
<span class="s2">"ExportOptions"</span><span class="p">,</span>
|
||||
<span class="s2">"ExportResults"</span><span class="p">,</span>
|
||||
<span class="s2">"PhotoExporter"</span><span class="p">,</span>
|
||||
<span class="s2">"hexdigest"</span><span class="p">,</span>
|
||||
<span class="s2">"rename_jpeg_files"</span><span class="p">,</span>
|
||||
<span class="p">]</span>
|
||||
|
||||
@@ -461,6 +459,7 @@
|
||||
<span class="n">exported_album</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
|
||||
<span class="n">skipped_album</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
|
||||
<span class="n">missing_album</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
|
||||
<span class="n">metadata_changed</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
|
||||
<span class="p">):</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">exported</span> <span class="o">=</span> <span class="n">exported</span> <span class="ow">or</span> <span class="p">[]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">new</span> <span class="o">=</span> <span class="n">new</span> <span class="ow">or</span> <span class="p">[]</span>
|
||||
@@ -487,6 +486,7 @@
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">exported_album</span> <span class="o">=</span> <span class="n">exported_album</span> <span class="ow">or</span> <span class="p">[]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">skipped_album</span> <span class="o">=</span> <span class="n">skipped_album</span> <span class="ow">or</span> <span class="p">[]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">missing_album</span> <span class="o">=</span> <span class="n">missing_album</span> <span class="ow">or</span> <span class="p">[]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">metadata_changed</span> <span class="o">=</span> <span class="n">metadata_changed</span> <span class="ow">or</span> <span class="p">[]</span>
|
||||
|
||||
<div class="viewcode-block" id="ExportResults.all_files"><a class="viewcode-back" href="../../reference.html#osxphotos.ExportResults.all_files">[docs]</a> <span class="k">def</span> <span class="nf">all_files</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""return all filenames contained in results"""</span>
|
||||
@@ -537,6 +537,7 @@
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">exported_album</span> <span class="o">+=</span> <span class="n">other</span><span class="o">.</span><span class="n">exported_album</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">skipped_album</span> <span class="o">+=</span> <span class="n">other</span><span class="o">.</span><span class="n">skipped_album</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">missing_album</span> <span class="o">+=</span> <span class="n">other</span><span class="o">.</span><span class="n">missing_album</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">metadata_changed</span> <span class="o">+=</span> <span class="n">other</span><span class="o">.</span><span class="n">metadata_changed</span>
|
||||
|
||||
<span class="k">return</span> <span class="bp">self</span>
|
||||
|
||||
@@ -566,12 +567,14 @@
|
||||
<span class="o">+</span> <span class="sa">f</span><span class="s2">",exported_album=</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">exported_album</span><span class="si">}</span><span class="s2">"</span>
|
||||
<span class="o">+</span> <span class="sa">f</span><span class="s2">",skipped_album=</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">skipped_album</span><span class="si">}</span><span class="s2">"</span>
|
||||
<span class="o">+</span> <span class="sa">f</span><span class="s2">",missing_album=</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">missing_album</span><span class="si">}</span><span class="s2">"</span>
|
||||
<span class="o">+</span> <span class="sa">f</span><span class="s2">",metadata_changed=</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">metadata_changed</span><span class="si">}</span><span class="s2">"</span>
|
||||
<span class="o">+</span> <span class="s2">")"</span>
|
||||
<span class="p">)</span></div>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="PhotoExporter"><a class="viewcode-back" href="../../reference.html#osxphotos.PhotoExporter">[docs]</a><span class="k">class</span> <span class="nc">PhotoExporter</span><span class="p">:</span>
|
||||
<span class="sd">"""Export a photo"""</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">photo</span><span class="p">:</span> <span class="s2">"PhotoInfo"</span><span class="p">,</span> <span class="n">tmpdir</span><span class="p">:</span> <span class="n">t</span><span class="o">.</span><span class="n">Optional</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span><span class="p">):</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">photo</span> <span class="o">=</span> <span class="n">photo</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_render_options</span> <span class="o">=</span> <span class="n">RenderOptions</span><span class="p">()</span>
|
||||
@@ -934,7 +937,7 @@
|
||||
<span class="k">return</span> <span class="n">ShouldUpdate</span><span class="o">.</span><span class="n">EDITED_SIG_DIFFERENT</span>
|
||||
|
||||
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">force_update</span><span class="p">:</span>
|
||||
<span class="n">current_digest</span> <span class="o">=</span> <span class="n">hexdigest</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">photo</span><span class="o">.</span><span class="n">json</span><span class="p">())</span>
|
||||
<span class="n">current_digest</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">hexdigest</span>
|
||||
<span class="k">if</span> <span class="n">current_digest</span> <span class="o">!=</span> <span class="n">file_record</span><span class="o">.</span><span class="n">digest</span><span class="p">:</span>
|
||||
<span class="c1"># metadata in Photos changed, force update</span>
|
||||
<span class="k">return</span> <span class="n">ShouldUpdate</span><span class="o">.</span><span class="n">DIGEST_DIFFERENT</span>
|
||||
@@ -1374,8 +1377,9 @@
|
||||
<span class="n">rec</span><span class="o">.</span><span class="n">dest_sig</span> <span class="o">=</span> <span class="n">fileutil</span><span class="o">.</span><span class="n">file_sig</span><span class="p">(</span><span class="n">dest</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">exiftool</span><span class="p">:</span>
|
||||
<span class="n">rec</span><span class="o">.</span><span class="n">exifdata</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_exiftool_json_sidecar</span><span class="p">(</span><span class="n">options</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">force_update</span><span class="p">:</span>
|
||||
<span class="n">rec</span><span class="o">.</span><span class="n">digest</span> <span class="o">=</span> <span class="n">hexdigest</span><span class="p">(</span><span class="n">photoinfo</span><span class="p">)</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">hexdigest</span> <span class="o">!=</span> <span class="n">rec</span><span class="o">.</span><span class="n">digest</span><span class="p">:</span>
|
||||
<span class="n">results</span><span class="o">.</span><span class="n">metadata_changed</span> <span class="o">=</span> <span class="p">[</span><span class="n">dest_str</span><span class="p">]</span>
|
||||
<span class="n">rec</span><span class="o">.</span><span class="n">digest</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">hexdigest</span>
|
||||
|
||||
<span class="k">return</span> <span class="n">results</span>
|
||||
|
||||
@@ -2206,13 +2210,6 @@
|
||||
<span class="n">f</span><span class="o">.</span><span class="n">close</span><span class="p">()</span></div>
|
||||
|
||||
|
||||
<span class="k">def</span> <span class="nf">hexdigest</span><span class="p">(</span><span class="n">strval</span><span class="p">):</span>
|
||||
<span class="sd">"""hexdigest of a string, using blake2b"""</span>
|
||||
<span class="n">h</span> <span class="o">=</span> <span class="n">hashlib</span><span class="o">.</span><span class="n">blake2b</span><span class="p">(</span><span class="n">digest_size</span><span class="o">=</span><span class="mi">20</span><span class="p">)</span>
|
||||
<span class="n">h</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="nb">bytes</span><span class="p">(</span><span class="n">strval</span><span class="p">,</span> <span class="s2">"utf-8"</span><span class="p">))</span>
|
||||
<span class="k">return</span> <span class="n">h</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">()</span>
|
||||
|
||||
|
||||
<span class="k">def</span> <span class="nf">_check_export_suffix</span><span class="p">(</span><span class="n">src</span><span class="p">,</span> <span class="n">dest</span><span class="p">,</span> <span class="n">edited</span><span class="p">):</span>
|
||||
<span class="sd">"""Helper function for exporting photos to check file extensions of destination path.</span>
|
||||
|
||||
|
||||
@@ -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.48.1 documentation</title>
|
||||
<title>osxphotos.photoinfo - osxphotos 0.48.3 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.1 documentation</div></a>
|
||||
<a href="../../index.html"><div class="brand">osxphotos 0.48.3 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.1 documentation</span>
|
||||
<span class="sidebar-brand-text">osxphotos 0.48.3 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">
|
||||
@@ -207,6 +207,7 @@
|
||||
<span class="kn">import</span> <span class="nn">os.path</span>
|
||||
<span class="kn">import</span> <span class="nn">pathlib</span>
|
||||
<span class="kn">from</span> <span class="nn">datetime</span> <span class="kn">import</span> <span class="n">timedelta</span><span class="p">,</span> <span class="n">timezone</span>
|
||||
<span class="kn">from</span> <span class="nn">functools</span> <span class="kn">import</span> <span class="n">cached_property</span>
|
||||
<span class="kn">from</span> <span class="nn">typing</span> <span class="kn">import</span> <span class="n">Optional</span>
|
||||
|
||||
<span class="kn">import</span> <span class="nn">yaml</span>
|
||||
@@ -250,7 +251,7 @@
|
||||
<span class="kn">from</span> <span class="nn">.searchinfo</span> <span class="kn">import</span> <span class="n">SearchInfo</span>
|
||||
<span class="kn">from</span> <span class="nn">.text_detection</span> <span class="kn">import</span> <span class="n">detect_text</span>
|
||||
<span class="kn">from</span> <span class="nn">.uti</span> <span class="kn">import</span> <span class="n">get_preferred_uti_extension</span><span class="p">,</span> <span class="n">get_uti_for_extension</span>
|
||||
<span class="kn">from</span> <span class="nn">.utils</span> <span class="kn">import</span> <span class="n">_get_resource_loc</span><span class="p">,</span> <span class="n">list_directory</span>
|
||||
<span class="kn">from</span> <span class="nn">.utils</span> <span class="kn">import</span> <span class="n">_get_resource_loc</span><span class="p">,</span> <span class="n">hexdigest</span><span class="p">,</span> <span class="n">list_directory</span>
|
||||
|
||||
<span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"PhotoInfo"</span><span class="p">,</span> <span class="s2">"PhotoInfoNone"</span><span class="p">]</span>
|
||||
|
||||
@@ -1552,6 +1553,12 @@
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_exiftool</span> <span class="o">=</span> <span class="n">exiftool</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_exiftool</span>
|
||||
|
||||
<span class="nd">@cached_property</span>
|
||||
<span class="k">def</span> <span class="nf">hexdigest</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""Returns a unique digest of the photo's properties and metadata;</span>
|
||||
<span class="sd"> useful for detecting changes in any property/metadata of the photo"""</span>
|
||||
<span class="k">return</span> <span class="n">hexdigest</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">json</span><span class="p">())</span>
|
||||
|
||||
<div class="viewcode-block" id="PhotoInfo.detected_text"><a class="viewcode-back" href="../../reference.html#osxphotos.PhotoInfo.detected_text">[docs]</a> <span class="k">def</span> <span class="nf">detected_text</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">confidence_threshold</span><span class="o">=</span><span class="n">TEXT_DETECTION_CONFIDENCE_THRESHOLD</span><span class="p">):</span>
|
||||
<span class="sd">"""Detects text in photo and returns lists of results as (detected text, confidence)</span>
|
||||
|
||||
|
||||
@@ -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.photosdb.photosdb - osxphotos 0.48.1 documentation</title>
|
||||
<title>osxphotos.photosdb.photosdb - osxphotos 0.48.3 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.1 documentation</div></a>
|
||||
<a href="../../../index.html"><div class="brand">osxphotos 0.48.3 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.1 documentation</span>
|
||||
<span class="sidebar-brand-text">osxphotos 0.48.3 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">
|
||||
@@ -3642,6 +3642,23 @@
|
||||
<span class="n">matching_photos</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">p</span><span class="p">)</span>
|
||||
<span class="n">photos</span> <span class="o">=</span> <span class="n">matching_photos</span>
|
||||
|
||||
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">added_after</span><span class="p">:</span>
|
||||
<span class="n">added_after</span> <span class="o">=</span> <span class="n">options</span><span class="o">.</span><span class="n">added_after</span>
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="n">datetime_has_tz</span><span class="p">(</span><span class="n">added_after</span><span class="p">):</span>
|
||||
<span class="n">added_after</span> <span class="o">=</span> <span class="n">datetime_naive_to_local</span><span class="p">(</span><span class="n">added_after</span><span class="p">)</span>
|
||||
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="n">p</span><span class="o">.</span><span class="n">date_added</span> <span class="ow">and</span> <span class="n">p</span><span class="o">.</span><span class="n">date_added</span> <span class="o">></span> <span class="n">added_after</span><span class="p">]</span>
|
||||
|
||||
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">added_before</span><span class="p">:</span>
|
||||
<span class="n">added_before</span> <span class="o">=</span> <span class="n">options</span><span class="o">.</span><span class="n">added_before</span>
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="n">datetime_has_tz</span><span class="p">(</span><span class="n">added_before</span><span class="p">):</span>
|
||||
<span class="n">added_before</span> <span class="o">=</span> <span class="n">datetime_naive_to_local</span><span class="p">(</span><span class="n">added_before</span><span class="p">)</span>
|
||||
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="n">p</span><span class="o">.</span><span class="n">date_added</span> <span class="ow">and</span> <span class="n">p</span><span class="o">.</span><span class="n">date_added</span> <span class="o"><</span> <span class="n">added_before</span><span class="p">]</span>
|
||||
|
||||
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">added_in_last</span><span class="p">:</span>
|
||||
<span class="n">added_after</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">()</span> <span class="o">-</span> <span class="n">options</span><span class="o">.</span><span class="n">added_in_last</span>
|
||||
<span class="n">added_after</span> <span class="o">=</span> <span class="n">datetime_naive_to_local</span><span class="p">(</span><span class="n">added_after</span><span class="p">)</span>
|
||||
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="n">p</span><span class="o">.</span><span class="n">date_added</span> <span class="ow">and</span> <span class="n">p</span><span class="o">.</span><span class="n">date_added</span> <span class="o">></span> <span class="n">added_after</span><span class="p">]</span>
|
||||
|
||||
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">function</span><span class="p">:</span>
|
||||
<span class="k">for</span> <span class="n">function</span> <span class="ow">in</span> <span class="n">options</span><span class="o">.</span><span class="n">function</span><span class="p">:</span>
|
||||
<span class="n">photos</span> <span class="o">=</span> <span class="n">function</span><span class="p">[</span><span class="mi">0</span><span class="p">](</span><span class="n">photos</span><span class="p">)</span>
|
||||
|
||||
@@ -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.48.1 documentation</title>
|
||||
<title>osxphotos.phototemplate - osxphotos 0.48.3 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.1 documentation</div></a>
|
||||
<a href="../../index.html"><div class="brand">osxphotos 0.48.3 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.1 documentation</span>
|
||||
<span class="sidebar-brand-text">osxphotos 0.48.3 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">
|
||||
|
||||
@@ -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.queryoptions - osxphotos 0.47.9 documentation</title>
|
||||
<title>osxphotos.queryoptions - osxphotos 0.48.3 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.3 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.3 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>
|
||||
@@ -210,158 +211,163 @@
|
||||
<span class="sd">"""QueryOptions class for PhotosDB.query</span>
|
||||
|
||||
<span class="sd"> Attributes:</span>
|
||||
<span class="sd"> keyword: list of keywords to search for</span>
|
||||
<span class="sd"> person: list of person names to search for</span>
|
||||
<span class="sd"> added_after: search for photos added after a given date</span>
|
||||
<span class="sd"> added_before: search for photos added before a given date</span>
|
||||
<span class="sd"> added_in_last: search for photos added in last X datetime.timedelta</span>
|
||||
<span class="sd"> album: list of album names to search for</span>
|
||||
<span class="sd"> folder: list of folder names to search for</span>
|
||||
<span class="sd"> uuid: list of uuids to search for</span>
|
||||
<span class="sd"> title: list of titles to search for</span>
|
||||
<span class="sd"> no_title: search for photos with no title</span>
|
||||
<span class="sd"> burst_photos: search for burst photos</span>
|
||||
<span class="sd"> burst: search for burst photos</span>
|
||||
<span class="sd"> cloudasset: search for photos that are managed by iCloud</span>
|
||||
<span class="sd"> deleted_only: search only for deleted photos</span>
|
||||
<span class="sd"> deleted: also include deleted photos</span>
|
||||
<span class="sd"> description: list of descriptions to search for</span>
|
||||
<span class="sd"> no_description: search for photos with no description</span>
|
||||
<span class="sd"> ignore_case: ignore case when searching</span>
|
||||
<span class="sd"> duplicate: search for duplicate photos</span>
|
||||
<span class="sd"> edited: search for edited photos</span>
|
||||
<span class="sd"> exif: search for photos with EXIF tags that matches the given data</span>
|
||||
<span class="sd"> external_edit: search for photos edited in external apps</span>
|
||||
<span class="sd"> favorite: search for favorite photos</span>
|
||||
<span class="sd"> not_favorite: search for non-favorite photos</span>
|
||||
<span class="sd"> hidden: search for hidden photos</span>
|
||||
<span class="sd"> not_hidden: search for non-hidden photos</span>
|
||||
<span class="sd"> missing: search for missing photos</span>
|
||||
<span class="sd"> not_missing: search for non-missing photos</span>
|
||||
<span class="sd"> shared: search for shared photos</span>
|
||||
<span class="sd"> not_shared: search for non-shared photos</span>
|
||||
<span class="sd"> photos: search for photos</span>
|
||||
<span class="sd"> movies: search for movies</span>
|
||||
<span class="sd"> uti: list of UTIs to search for</span>
|
||||
<span class="sd"> burst: search for burst photos</span>
|
||||
<span class="sd"> not_burst: search for non-burst photos</span>
|
||||
<span class="sd"> live: search for live photos</span>
|
||||
<span class="sd"> not_live: search for non-live photos</span>
|
||||
<span class="sd"> cloudasset: search for photos that are managed by iCloud</span>
|
||||
<span class="sd"> not_cloudasset: search for photos that are not managed by iCloud</span>
|
||||
<span class="sd"> incloud: search for cloud assets that are synched to iCloud</span>
|
||||
<span class="sd"> not_incloud: search for cloud asset photos that are not yet synched to iCloud</span>
|
||||
<span class="sd"> folder: list of folder names to search for</span>
|
||||
<span class="sd"> from_date: search for photos taken on or after this date</span>
|
||||
<span class="sd"> to_date: search for photos taken on or before this date</span>
|
||||
<span class="sd"> portrait: search for portrait photos</span>
|
||||
<span class="sd"> not_portrait: search for non-portrait photos</span>
|
||||
<span class="sd"> screenshot: search for screenshot photos</span>
|
||||
<span class="sd"> not_screenshot: search for non-screenshot photos</span>
|
||||
<span class="sd"> slow_mo: search for slow-mo photos</span>
|
||||
<span class="sd"> not_slow_mo: search for non-slow-mo photos</span>
|
||||
<span class="sd"> time_lapse: search for time-lapse photos</span>
|
||||
<span class="sd"> not_time_lapse: search for non-time-lapse photos</span>
|
||||
<span class="sd"> hdr: search for HDR photos</span>
|
||||
<span class="sd"> not_hdr: search for non-HDR photos</span>
|
||||
<span class="sd"> selfie: search for selfie photos</span>
|
||||
<span class="sd"> not_selfie: search for non-selfie photos</span>
|
||||
<span class="sd"> panorama: search for panorama photos</span>
|
||||
<span class="sd"> not_panorama: search for non-panorama photos</span>
|
||||
<span class="sd"> has_raw: search for photos with associated raw files</span>
|
||||
<span class="sd"> place: list of place names to search for</span>
|
||||
<span class="sd"> no_place: search for photos with no place</span>
|
||||
<span class="sd"> label: list of labels to search for</span>
|
||||
<span class="sd"> deleted: also include deleted photos</span>
|
||||
<span class="sd"> deleted_only: search only for deleted photos</span>
|
||||
<span class="sd"> has_comment: search for photos with comments</span>
|
||||
<span class="sd"> no_comment: search for photos with no comments</span>
|
||||
<span class="sd"> has_likes: search for shared photos with likes</span>
|
||||
<span class="sd"> no_likes: search for shared photos with no likes</span>
|
||||
<span class="sd"> is_reference: search for photos stored by reference (that is, they are not managed by Photos)</span>
|
||||
<span class="sd"> in_album: search for photos in an album</span>
|
||||
<span class="sd"> not_in_album: search for photos not in an album</span>
|
||||
<span class="sd"> burst_photos: search for burst photos</span>
|
||||
<span class="sd"> missing_bursts: for burst photos, also include burst photos that are missing</span>
|
||||
<span class="sd"> name: list of names to search for</span>
|
||||
<span class="sd"> min_size: minimum size of photos to search for</span>
|
||||
<span class="sd"> max_size: maximum size of photos to search for</span>
|
||||
<span class="sd"> regex: list of regular expressions to search for</span>
|
||||
<span class="sd"> query_eval: list of query expressions to evaluate</span>
|
||||
<span class="sd"> duplicate: search for duplicate photos</span>
|
||||
<span class="sd"> location: search for photos with a location</span>
|
||||
<span class="sd"> no_location: search for photos with no location</span>
|
||||
<span class="sd"> function: list of query functions to evaluate</span>
|
||||
<span class="sd"> has_comment: search for photos with comments</span>
|
||||
<span class="sd"> has_likes: search for shared photos with likes</span>
|
||||
<span class="sd"> has_raw: search for photos with associated raw files</span>
|
||||
<span class="sd"> hdr: search for HDR photos</span>
|
||||
<span class="sd"> hidden: search for hidden photos</span>
|
||||
<span class="sd"> ignore_case: ignore case when searching</span>
|
||||
<span class="sd"> in_album: search for photos in an album</span>
|
||||
<span class="sd"> incloud: search for cloud assets that are synched to iCloud</span>
|
||||
<span class="sd"> is_reference: search for photos stored by reference (that is, they are not managed by Photos)</span>
|
||||
<span class="sd"> keyword: list of keywords to search for</span>
|
||||
<span class="sd"> label: list of labels to search for</span>
|
||||
<span class="sd"> live: search for live photos</span>
|
||||
<span class="sd"> location: search for photos with a location</span>
|
||||
<span class="sd"> max_size: maximum size of photos to search for</span>
|
||||
<span class="sd"> min_size: minimum size of photos to search for</span>
|
||||
<span class="sd"> missing_bursts: for burst photos, also include burst photos that are missing</span>
|
||||
<span class="sd"> missing: search for missing photos</span>
|
||||
<span class="sd"> movies: search for movies</span>
|
||||
<span class="sd"> name: list of names to search for</span>
|
||||
<span class="sd"> no_comment: search for photos with no comments</span>
|
||||
<span class="sd"> no_description: search for photos with no description</span>
|
||||
<span class="sd"> no_likes: search for shared photos with no likes</span>
|
||||
<span class="sd"> no_location: search for photos with no location</span>
|
||||
<span class="sd"> no_place: search for photos with no place</span>
|
||||
<span class="sd"> no_title: search for photos with no title</span>
|
||||
<span class="sd"> not_burst: search for non-burst photos</span>
|
||||
<span class="sd"> not_cloudasset: search for photos that are not managed by iCloud</span>
|
||||
<span class="sd"> not_favorite: search for non-favorite photos</span>
|
||||
<span class="sd"> not_hdr: search for non-HDR photos</span>
|
||||
<span class="sd"> not_hidden: search for non-hidden photos</span>
|
||||
<span class="sd"> not_in_album: search for photos not in an album</span>
|
||||
<span class="sd"> not_incloud: search for cloud asset photos that are not yet synched to iCloud</span>
|
||||
<span class="sd"> not_live: search for non-live photos</span>
|
||||
<span class="sd"> not_missing: search for non-missing photos</span>
|
||||
<span class="sd"> not_panorama: search for non-panorama photos</span>
|
||||
<span class="sd"> not_portrait: search for non-portrait photos</span>
|
||||
<span class="sd"> not_screenshot: search for non-screenshot photos</span>
|
||||
<span class="sd"> not_selfie: search for non-selfie photos</span>
|
||||
<span class="sd"> not_shared: search for non-shared photos</span>
|
||||
<span class="sd"> not_slow_mo: search for non-slow-mo photos</span>
|
||||
<span class="sd"> not_time_lapse: search for non-time-lapse photos</span>
|
||||
<span class="sd"> panorama: search for panorama photos</span>
|
||||
<span class="sd"> person: list of person names to search for</span>
|
||||
<span class="sd"> photos: search for photos</span>
|
||||
<span class="sd"> place: list of place names to search for</span>
|
||||
<span class="sd"> portrait: search for portrait photos</span>
|
||||
<span class="sd"> query_eval: list of query expressions to evaluate</span>
|
||||
<span class="sd"> regex: list of regular expressions to search for</span>
|
||||
<span class="sd"> screenshot: search for screenshot photos</span>
|
||||
<span class="sd"> selected: search for selected photos</span>
|
||||
<span class="sd"> exif: search for photos with EXIF tags that matches the given data</span>
|
||||
<span class="sd"> selfie: search for selfie photos</span>
|
||||
<span class="sd"> shared: search for shared photos</span>
|
||||
<span class="sd"> slow_mo: search for slow-mo photos</span>
|
||||
<span class="sd"> time_lapse: search for time-lapse photos</span>
|
||||
<span class="sd"> title: list of titles to search for</span>
|
||||
<span class="sd"> to_date: search for photos taken on or before this date</span>
|
||||
<span class="sd"> uti: list of UTIs to search for</span>
|
||||
<span class="sd"> uuid: list of uuids to search for</span>
|
||||
<span class="sd"> year: search for photos taken in a given year</span>
|
||||
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="n">keyword</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">Iterable</span><span class="p">[</span><span class="nb">str</span><span class="p">]]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">person</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">Iterable</span><span class="p">[</span><span class="nb">str</span><span class="p">]]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">added_after</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">added_before</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">added_in_last</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">datetime</span><span class="o">.</span><span class="n">timedelta</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">album</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">Iterable</span><span class="p">[</span><span class="nb">str</span><span class="p">]]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">folder</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">Iterable</span><span class="p">[</span><span class="nb">str</span><span class="p">]]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">uuid</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">Iterable</span><span class="p">[</span><span class="nb">str</span><span class="p">]]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">title</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">Iterable</span><span class="p">[</span><span class="nb">str</span><span class="p">]]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">no_title</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">burst_photos</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">burst</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">cloudasset</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">deleted_only</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">deleted</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">description</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">Iterable</span><span class="p">[</span><span class="nb">str</span><span class="p">]]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">no_description</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">ignore_case</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">duplicate</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">edited</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">exif</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">Iterable</span><span class="p">[</span><span class="n">Tuple</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="nb">str</span><span class="p">]]]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">external_edit</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">favorite</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">not_favorite</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">hidden</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">not_hidden</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">missing</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">not_missing</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">shared</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">not_shared</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">photos</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span>
|
||||
<span class="n">movies</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span>
|
||||
<span class="n">uti</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">Iterable</span><span class="p">[</span><span class="nb">str</span><span class="p">]]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">burst</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">not_burst</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">live</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">not_live</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">cloudasset</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">not_cloudasset</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">incloud</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">not_incloud</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">folder</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">Iterable</span><span class="p">[</span><span class="nb">str</span><span class="p">]]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">from_date</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">to_date</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">from_time</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">datetime</span><span class="o">.</span><span class="n">time</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">to_time</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">datetime</span><span class="o">.</span><span class="n">time</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">portrait</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">not_portrait</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">screenshot</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">not_screenshot</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">slow_mo</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">not_slow_mo</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">time_lapse</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">not_time_lapse</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">hdr</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">not_hdr</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">selfie</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">not_selfie</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">panorama</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">not_panorama</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">has_raw</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">place</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">Iterable</span><span class="p">[</span><span class="nb">str</span><span class="p">]]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">no_place</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">label</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">Iterable</span><span class="p">[</span><span class="nb">str</span><span class="p">]]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">deleted</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">deleted_only</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">has_comment</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">no_comment</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">has_likes</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">no_likes</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">is_reference</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">in_album</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">not_in_album</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">burst_photos</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">missing_bursts</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">name</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">Iterable</span><span class="p">[</span><span class="nb">str</span><span class="p">]]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">min_size</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">bitmath</span><span class="o">.</span><span class="n">Byte</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">max_size</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">bitmath</span><span class="o">.</span><span class="n">Byte</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">regex</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">Iterable</span><span class="p">[</span><span class="n">Tuple</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="nb">str</span><span class="p">]]]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">query_eval</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">Iterable</span><span class="p">[</span><span class="nb">str</span><span class="p">]]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">duplicate</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">location</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">no_location</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">function</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">List</span><span class="p">[</span><span class="n">Tuple</span><span class="p">[</span><span class="n">callable</span><span class="p">,</span> <span class="nb">str</span><span class="p">]]]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">has_comment</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">has_likes</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">has_raw</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">hdr</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">hidden</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">ignore_case</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">in_album</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">incloud</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">is_reference</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">keyword</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">Iterable</span><span class="p">[</span><span class="nb">str</span><span class="p">]]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">label</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">Iterable</span><span class="p">[</span><span class="nb">str</span><span class="p">]]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">live</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">location</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">max_size</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">bitmath</span><span class="o">.</span><span class="n">Byte</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">min_size</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">bitmath</span><span class="o">.</span><span class="n">Byte</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">missing_bursts</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">missing</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">movies</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span>
|
||||
<span class="n">name</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">Iterable</span><span class="p">[</span><span class="nb">str</span><span class="p">]]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">no_comment</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">no_description</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">no_likes</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">no_location</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">no_place</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">no_title</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">not_burst</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">not_cloudasset</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">not_favorite</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">not_hdr</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">not_hidden</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">not_in_album</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">not_incloud</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">not_live</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">not_missing</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">not_panorama</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">not_portrait</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">not_screenshot</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">not_selfie</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">not_shared</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">not_slow_mo</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">not_time_lapse</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">panorama</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">person</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">Iterable</span><span class="p">[</span><span class="nb">str</span><span class="p">]]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">photos</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span>
|
||||
<span class="n">place</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">Iterable</span><span class="p">[</span><span class="nb">str</span><span class="p">]]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">portrait</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">query_eval</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">Iterable</span><span class="p">[</span><span class="nb">str</span><span class="p">]]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">regex</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">Iterable</span><span class="p">[</span><span class="n">Tuple</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="nb">str</span><span class="p">]]]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">screenshot</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">selected</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">exif</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">Iterable</span><span class="p">[</span><span class="n">Tuple</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="nb">str</span><span class="p">]]]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">selfie</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">shared</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">slow_mo</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">time_lapse</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">bool</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">title</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">Iterable</span><span class="p">[</span><span class="nb">str</span><span class="p">]]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">to_date</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">to_time</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">datetime</span><span class="o">.</span><span class="n">time</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">uti</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">Iterable</span><span class="p">[</span><span class="nb">str</span><span class="p">]]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">uuid</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">Iterable</span><span class="p">[</span><span class="nb">str</span><span class="p">]]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="n">year</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="n">Iterable</span><span class="p">[</span><span class="nb">int</span><span class="p">]]</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
|
||||
<span class="k">def</span> <span class="nf">asdict</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
|
||||
@@ -320,7 +320,7 @@ Template Substitutions
|
||||
* - {crlf}
|
||||
- a carriage return + line feed: '\r\n'
|
||||
* - {osxphotos_version}
|
||||
- The osxphotos version, e.g. '0.48.2'
|
||||
- The osxphotos version, e.g. '0.48.4'
|
||||
* - {osxphotos_cmd_line}
|
||||
- The full command line used to run osxphotos
|
||||
* - {album}
|
||||
|
||||
@@ -297,6 +297,10 @@ You can also export photos in a certain date range:
|
||||
|
||||
``osxphotos export /path/to/export --from-date "2020-01-01" --to-date "2020-02-28"``
|
||||
|
||||
or photos added to the library in the last week:
|
||||
|
||||
``osxphotos export /path/to/export --added-in-last "1 week"``
|
||||
|
||||
Converting images to JPEG on export
|
||||
-----------------------------------
|
||||
|
||||
|
||||
2
docs/_static/documentation_options.js
vendored
2
docs/_static/documentation_options.js
vendored
@@ -1,6 +1,6 @@
|
||||
var DOCUMENTATION_OPTIONS = {
|
||||
URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'),
|
||||
VERSION: '0.48.2',
|
||||
VERSION: '0.48.4',
|
||||
LANGUAGE: 'None',
|
||||
COLLAPSE_INDEX: false,
|
||||
BUILDER: 'html',
|
||||
|
||||
@@ -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.2 documentation</title>
|
||||
<title>OSXPhotos Command Line Interface (CLI) - osxphotos 0.48.4 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.2 documentation</div></a>
|
||||
<a href="index.html"><div class="brand">osxphotos 0.48.4 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.2 documentation</span>
|
||||
<span class="sidebar-brand-text">osxphotos 0.48.4 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">
|
||||
@@ -640,6 +640,21 @@ to modify this behavior.</p>
|
||||
<dd><p>Search for items from a specific year, e.g. –year 2022 to find all photos from the year 2022. May be repeated to search multiple years.</p>
|
||||
</dd></dl>
|
||||
<dl class="std option">
|
||||
<dt class="sig sig-object std" id="cmdoption-osxphotos-export-added-before">
|
||||
<span class="sig-name descname"><span class="pre">--added-before</span></span><span class="sig-prename descclassname"> <span class="pre"><DATE></span></span><a class="headerlink" href="#cmdoption-osxphotos-export-added-before" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>Search for items added to the library before a specific date/time, e.g. –added-before e.g. 2000-01-12T12:00:00, 2001-01-12T12:00:00-07:00, or 2000-12-31 (ISO 8601 with/without timezone).</p>
|
||||
</dd></dl>
|
||||
<dl class="std option">
|
||||
<dt class="sig sig-object std" id="cmdoption-osxphotos-export-added-after">
|
||||
<span class="sig-name descname"><span class="pre">--added-after</span></span><span class="sig-prename descclassname"> <span class="pre"><DATE></span></span><a class="headerlink" href="#cmdoption-osxphotos-export-added-after" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>Search for items added to the libray after a specific date/time, e.g. –added-after e.g. 2000-01-12T12:00:00, 2001-01-12T12:00:00-07:00, or 2000-12-31 (ISO 8601 with/without timezone).</p>
|
||||
</dd></dl>
|
||||
<dl class="std option">
|
||||
<dt class="sig sig-object std" id="cmdoption-osxphotos-export-added-in-last">
|
||||
<span class="sig-name descname"><span class="pre">--added-in-last</span></span><span class="sig-prename descclassname"> <span class="pre"><TIME_DELTA></span></span><a class="headerlink" href="#cmdoption-osxphotos-export-added-in-last" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>Search for items added to the library in the last TIME_DELTA, where TIME_DELTA is a string like ‘12 hrs’, ‘1 day’, ‘1d’, ‘1 week’, ‘2weeks’, ‘1 month’, ‘1 year’. for example, <cite>–added-in-last 7d</cite> and <cite>–added-in-last ‘1 week’</cite> are equivalent. months are assumed to be 30 days and years are assumed to be 365 days. Common English abbreviations are accepted, e.g. d, day, days or m, min, minutes.</p>
|
||||
</dd></dl>
|
||||
<dl class="std option">
|
||||
<dt class="sig sig-object std" id="cmdoption-osxphotos-export-has-comment">
|
||||
<span class="sig-name descname"><span class="pre">--has-comment</span></span><span class="sig-prename descclassname"></span><a class="headerlink" href="#cmdoption-osxphotos-export-has-comment" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>Search for photos that have comments.</p>
|
||||
@@ -1518,6 +1533,21 @@ if more than one option is provided, they are treated as “AND”
|
||||
<dd><p>Search for items from a specific year, e.g. –year 2022 to find all photos from the year 2022. May be repeated to search multiple years.</p>
|
||||
</dd></dl>
|
||||
<dl class="std option">
|
||||
<dt class="sig sig-object std" id="cmdoption-osxphotos-query-added-before">
|
||||
<span class="sig-name descname"><span class="pre">--added-before</span></span><span class="sig-prename descclassname"> <span class="pre"><DATE></span></span><a class="headerlink" href="#cmdoption-osxphotos-query-added-before" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>Search for items added to the library before a specific date/time, e.g. –added-before e.g. 2000-01-12T12:00:00, 2001-01-12T12:00:00-07:00, or 2000-12-31 (ISO 8601 with/without timezone).</p>
|
||||
</dd></dl>
|
||||
<dl class="std option">
|
||||
<dt class="sig sig-object std" id="cmdoption-osxphotos-query-added-after">
|
||||
<span class="sig-name descname"><span class="pre">--added-after</span></span><span class="sig-prename descclassname"> <span class="pre"><DATE></span></span><a class="headerlink" href="#cmdoption-osxphotos-query-added-after" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>Search for items added to the libray after a specific date/time, e.g. –added-after e.g. 2000-01-12T12:00:00, 2001-01-12T12:00:00-07:00, or 2000-12-31 (ISO 8601 with/without timezone).</p>
|
||||
</dd></dl>
|
||||
<dl class="std option">
|
||||
<dt class="sig sig-object std" id="cmdoption-osxphotos-query-added-in-last">
|
||||
<span class="sig-name descname"><span class="pre">--added-in-last</span></span><span class="sig-prename descclassname"> <span class="pre"><TIME_DELTA></span></span><a class="headerlink" href="#cmdoption-osxphotos-query-added-in-last" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>Search for items added to the library in the last TIME_DELTA, where TIME_DELTA is a string like ‘12 hrs’, ‘1 day’, ‘1d’, ‘1 week’, ‘2weeks’, ‘1 month’, ‘1 year’. for example, <cite>–added-in-last 7d</cite> and <cite>–added-in-last ‘1 week’</cite> are equivalent. months are assumed to be 30 days and years are assumed to be 365 days. Common English abbreviations are accepted, e.g. d, day, days or m, min, minutes.</p>
|
||||
</dd></dl>
|
||||
<dl class="std option">
|
||||
<dt class="sig sig-object std" id="cmdoption-osxphotos-query-has-comment">
|
||||
<span class="sig-name descname"><span class="pre">--has-comment</span></span><span class="sig-prename descclassname"></span><a class="headerlink" href="#cmdoption-osxphotos-query-has-comment" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>Search for photos that have comments.</p>
|
||||
@@ -1922,6 +1952,21 @@ if more than one option is provided, they are treated as “AND”
|
||||
<dd><p>Search for items from a specific year, e.g. –year 2022 to find all photos from the year 2022. May be repeated to search multiple years.</p>
|
||||
</dd></dl>
|
||||
<dl class="std option">
|
||||
<dt class="sig sig-object std" id="cmdoption-osxphotos-repl-added-before">
|
||||
<span class="sig-name descname"><span class="pre">--added-before</span></span><span class="sig-prename descclassname"> <span class="pre"><DATE></span></span><a class="headerlink" href="#cmdoption-osxphotos-repl-added-before" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>Search for items added to the library before a specific date/time, e.g. –added-before e.g. 2000-01-12T12:00:00, 2001-01-12T12:00:00-07:00, or 2000-12-31 (ISO 8601 with/without timezone).</p>
|
||||
</dd></dl>
|
||||
<dl class="std option">
|
||||
<dt class="sig sig-object std" id="cmdoption-osxphotos-repl-added-after">
|
||||
<span class="sig-name descname"><span class="pre">--added-after</span></span><span class="sig-prename descclassname"> <span class="pre"><DATE></span></span><a class="headerlink" href="#cmdoption-osxphotos-repl-added-after" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>Search for items added to the libray after a specific date/time, e.g. –added-after e.g. 2000-01-12T12:00:00, 2001-01-12T12:00:00-07:00, or 2000-12-31 (ISO 8601 with/without timezone).</p>
|
||||
</dd></dl>
|
||||
<dl class="std option">
|
||||
<dt class="sig sig-object std" id="cmdoption-osxphotos-repl-added-in-last">
|
||||
<span class="sig-name descname"><span class="pre">--added-in-last</span></span><span class="sig-prename descclassname"> <span class="pre"><TIME_DELTA></span></span><a class="headerlink" href="#cmdoption-osxphotos-repl-added-in-last" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>Search for items added to the library in the last TIME_DELTA, where TIME_DELTA is a string like ‘12 hrs’, ‘1 day’, ‘1d’, ‘1 week’, ‘2weeks’, ‘1 month’, ‘1 year’. for example, <cite>–added-in-last 7d</cite> and <cite>–added-in-last ‘1 week’</cite> are equivalent. months are assumed to be 30 days and years are assumed to be 365 days. Common English abbreviations are accepted, e.g. d, day, days or m, min, minutes.</p>
|
||||
</dd></dl>
|
||||
<dl class="std option">
|
||||
<dt class="sig sig-object std" id="cmdoption-osxphotos-repl-has-comment">
|
||||
<span class="sig-name descname"><span class="pre">--has-comment</span></span><span class="sig-prename descclassname"></span><a class="headerlink" href="#cmdoption-osxphotos-repl-has-comment" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>Search for photos that have comments.</p>
|
||||
|
||||
@@ -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.2 documentation</title>
|
||||
<meta name="generator" content="sphinx-4.4.0, furo 2022.04.07"/><title>Index - osxphotos 0.48.4 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.2 documentation</div></a>
|
||||
<a href="index.html"><div class="brand">osxphotos 0.48.4 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.2 documentation</span>
|
||||
<span class="sidebar-brand-text">osxphotos 0.48.4 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">
|
||||
@@ -229,6 +229,39 @@
|
||||
<li><a href="cli.html#cmdoption-osxphotos-query-add-to-album">osxphotos-query command line option</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-a">osxphotos-timewarp command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
--added-after
|
||||
|
||||
<ul>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-export-added-after">osxphotos-export command line option</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-query-added-after">osxphotos-query command line option</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-repl-added-after">osxphotos-repl command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
--added-before
|
||||
|
||||
<ul>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-export-added-before">osxphotos-export command line option</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-query-added-before">osxphotos-query command line option</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-repl-added-before">osxphotos-repl command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
--added-in-last
|
||||
|
||||
<ul>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-export-added-in-last">osxphotos-export command line option</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-query-added-in-last">osxphotos-query command line option</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-repl-added-in-last">osxphotos-repl command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
@@ -1026,6 +1059,8 @@
|
||||
<li><a href="cli.html#cmdoption-osxphotos-repl-not-cloudasset">osxphotos-repl command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
</ul></td>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li>
|
||||
--not-favorite
|
||||
|
||||
@@ -1048,8 +1083,6 @@
|
||||
<li><a href="cli.html#cmdoption-osxphotos-repl-not-hdr">osxphotos-repl command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
</ul></td>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li>
|
||||
--not-hidden
|
||||
|
||||
@@ -1934,6 +1967,12 @@
|
||||
<table style="width: 100%" class="indextable genindextable"><tr>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li><a href="reference.html#osxphotos.SearchInfo.activities">activities (osxphotos.SearchInfo property)</a>
|
||||
</li>
|
||||
<li><a href="reference.html#osxphotos.QueryOptions.added_after">added_after (osxphotos.QueryOptions attribute)</a>
|
||||
</li>
|
||||
<li><a href="reference.html#osxphotos.QueryOptions.added_before">added_before (osxphotos.QueryOptions attribute)</a>
|
||||
</li>
|
||||
<li><a href="reference.html#osxphotos.QueryOptions.added_in_last">added_in_last (osxphotos.QueryOptions attribute)</a>
|
||||
</li>
|
||||
<li><a href="reference.html#osxphotos.ExifTool.addvalues">addvalues() (osxphotos.ExifTool method)</a>
|
||||
</li>
|
||||
@@ -1953,14 +1992,14 @@
|
||||
</li>
|
||||
<li><a href="reference.html#osxphotos.AlbumInfo">AlbumInfo (class in osxphotos)</a>
|
||||
</li>
|
||||
</ul></td>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li><a href="reference.html#osxphotos.PhotoInfo.albums">albums (osxphotos.PhotoInfo property)</a>
|
||||
|
||||
<ul>
|
||||
<li><a href="reference.html#osxphotos.PhotosDB.albums">(osxphotos.PhotosDB property)</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
</ul></td>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li><a href="reference.html#osxphotos.PhotosDB.albums_as_dict">albums_as_dict (osxphotos.PhotosDB property)</a>
|
||||
</li>
|
||||
<li><a href="reference.html#osxphotos.PhotosDB.albums_shared">albums_shared (osxphotos.PhotosDB property)</a>
|
||||
@@ -2296,6 +2335,8 @@
|
||||
</li>
|
||||
</ul></li>
|
||||
<li><a href="reference.html#osxphotos.PhotoInfo.height">height (osxphotos.PhotoInfo property)</a>
|
||||
</li>
|
||||
<li><a href="reference.html#osxphotos.PhotoInfo.hexdigest">hexdigest (osxphotos.PhotoInfo property)</a>
|
||||
</li>
|
||||
<li><a href="reference.html#osxphotos.PhotoInfo.hidden">hidden (osxphotos.PhotoInfo property)</a>
|
||||
|
||||
@@ -2652,6 +2693,12 @@
|
||||
<li><a href="cli.html#cmdoption-osxphotos-export-add-missing-to-album">--add-missing-to-album</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-export-add-skipped-to-album">--add-skipped-to-album</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-export-added-after">--added-after</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-export-added-before">--added-before</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-export-added-in-last">--added-in-last</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-export-album">--album</a>
|
||||
</li>
|
||||
@@ -3015,6 +3062,12 @@
|
||||
|
||||
<ul>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-query-add-to-album">--add-to-album</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-query-added-after">--added-after</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-query-added-before">--added-before</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-query-added-in-last">--added-in-last</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-query-album">--album</a>
|
||||
</li>
|
||||
@@ -3181,6 +3234,12 @@
|
||||
osxphotos-repl command line option
|
||||
|
||||
<ul>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-repl-added-after">--added-after</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-repl-added-before">--added-before</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-repl-added-in-last">--added-in-last</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-repl-album">--album</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-repl-burst">--burst</a>
|
||||
|
||||
@@ -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.2 documentation</title>
|
||||
<title>osxphotos 0.48.4 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.2 documentation</div></a>
|
||||
<a href="#"><div class="brand">osxphotos 0.48.4 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.2 documentation</span>
|
||||
<span class="sidebar-brand-text">osxphotos 0.48.4 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">
|
||||
|
||||
BIN
docs/objects.inv
BIN
docs/objects.inv
Binary file not shown.
@@ -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 OSXPhotos’s documentation!" href="index.html" />
|
||||
|
||||
<meta name="generator" content="sphinx-4.4.0, furo 2022.04.07"/>
|
||||
<title>OSXPhotos - osxphotos 0.48.2 documentation</title>
|
||||
<title>OSXPhotos - osxphotos 0.48.4 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.2 documentation</div></a>
|
||||
<a href="index.html"><div class="brand">osxphotos 0.48.4 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.2 documentation</span>
|
||||
<span class="sidebar-brand-text">osxphotos 0.48.4 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">
|
||||
|
||||
@@ -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.2 documentation</title>
|
||||
<title>OSXPhotos Python Package Overview - osxphotos 0.48.4 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.2 documentation</div></a>
|
||||
<a href="index.html"><div class="brand">osxphotos 0.48.4 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.2 documentation</span>
|
||||
<span class="sidebar-brand-text">osxphotos 0.48.4 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">
|
||||
|
||||
@@ -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.2 documentation</title>
|
||||
<meta name="generator" content="sphinx-4.4.0, furo 2022.04.07"/><title>Python Module Index - osxphotos 0.48.4 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.2 documentation</div></a>
|
||||
<a href="index.html"><div class="brand">osxphotos 0.48.4 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.2 documentation</span>
|
||||
<span class="sidebar-brand-text">osxphotos 0.48.4 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">
|
||||
|
||||
1030
docs/reference.html
1030
docs/reference.html
File diff suppressed because one or more lines are too long
@@ -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.2 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.4 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.2 documentation</div></a>
|
||||
<a href="index.html"><div class="brand">osxphotos 0.48.4 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.2 documentation</span>
|
||||
<span class="sidebar-brand-text">osxphotos 0.48.4 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
@@ -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.2 documentation</title>
|
||||
<title>OSXPhotos Template System - osxphotos 0.48.4 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.2 documentation</div></a>
|
||||
<a href="index.html"><div class="brand">osxphotos 0.48.4 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.2 documentation</span>
|
||||
<span class="sidebar-brand-text">osxphotos 0.48.4 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">
|
||||
@@ -567,7 +567,7 @@
|
||||
<td><p>a carriage return + line feed: ‘rn’</p></td>
|
||||
</tr>
|
||||
<tr class="row-odd"><td><p>{osxphotos_version}</p></td>
|
||||
<td><p>The osxphotos version, e.g. ‘0.48.2’</p></td>
|
||||
<td><p>The osxphotos version, e.g. ‘0.48.4’</p></td>
|
||||
</tr>
|
||||
<tr class="row-even"><td><p>{osxphotos_cmd_line}</p></td>
|
||||
<td><p>The full command line used to run osxphotos</p></td>
|
||||
|
||||
@@ -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.2 documentation</title>
|
||||
<title>OSXPhotos Tutorial - osxphotos 0.48.4 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.2 documentation</div></a>
|
||||
<a href="index.html"><div class="brand">osxphotos 0.48.4 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.2 documentation</span>
|
||||
<span class="sidebar-brand-text">osxphotos 0.48.4 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">
|
||||
@@ -378,6 +378,8 @@
|
||||
<p><code class="docutils literal notranslate"><span class="pre">osxphotos</span> <span class="pre">export</span> <span class="pre">/path/to/export</span> <span class="pre">--portrait</span></code></p>
|
||||
<p>You can also export photos in a certain date range:</p>
|
||||
<p><code class="docutils literal notranslate"><span class="pre">osxphotos</span> <span class="pre">export</span> <span class="pre">/path/to/export</span> <span class="pre">--from-date</span> <span class="pre">"2020-01-01"</span> <span class="pre">--to-date</span> <span class="pre">"2020-02-28"</span></code></p>
|
||||
<p>or photos added to the library in the last week:</p>
|
||||
<p><code class="docutils literal notranslate"><span class="pre">osxphotos</span> <span class="pre">export</span> <span class="pre">/path/to/export</span> <span class="pre">--added-in-last</span> <span class="pre">"1</span> <span class="pre">week"</span></code></p>
|
||||
</section>
|
||||
<section id="converting-images-to-jpeg-on-export">
|
||||
<h2>Converting images to JPEG on export<a class="headerlink" href="#converting-images-to-jpeg-on-export" title="Permalink to this headline">#</a></h2>
|
||||
|
||||
@@ -320,7 +320,7 @@ Template Substitutions
|
||||
* - {crlf}
|
||||
- a carriage return + line feed: '\r\n'
|
||||
* - {osxphotos_version}
|
||||
- The osxphotos version, e.g. '0.48.2'
|
||||
- The osxphotos version, e.g. '0.48.4'
|
||||
* - {osxphotos_cmd_line}
|
||||
- The full command line used to run osxphotos
|
||||
* - {album}
|
||||
|
||||
@@ -297,6 +297,10 @@ You can also export photos in a certain date range:
|
||||
|
||||
``osxphotos export /path/to/export --from-date "2020-01-01" --to-date "2020-02-28"``
|
||||
|
||||
or photos added to the library in the last week:
|
||||
|
||||
``osxphotos export /path/to/export --added-in-last "1 week"``
|
||||
|
||||
Converting images to JPEG on export
|
||||
-----------------------------------
|
||||
|
||||
|
||||
@@ -50,6 +50,7 @@ def post_function(
|
||||
# exported_album: list of tuples of (filename, album_name) for exported files added to album with --add-exported-to-album
|
||||
# skipped_album: list of tuples of (filename, album_name) for skipped files added to album with --add-skipped-to-album
|
||||
# missing_album: list of tuples of (filename, album_name) for missing files added to album with --add-missing-to-album
|
||||
# metadata_changed: list of filenames that had metadata changes since last export
|
||||
|
||||
for filename in results.exported:
|
||||
# do your processing here
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
""" version info """
|
||||
|
||||
__version__ = "0.48.2"
|
||||
__version__ = "0.48.4"
|
||||
|
||||
@@ -380,6 +380,31 @@ def QUERY_OPTIONS(f):
|
||||
multiple=True,
|
||||
type=int,
|
||||
),
|
||||
o(
|
||||
"--added-before",
|
||||
metavar="DATE",
|
||||
help="Search for items added to the library before a specific date/time, "
|
||||
"e.g. --added-before e.g. 2000-01-12T12:00:00, 2001-01-12T12:00:00-07:00, or 2000-12-31 (ISO 8601 with/without timezone).",
|
||||
type=DateTimeISO8601(),
|
||||
),
|
||||
o(
|
||||
"--added-after",
|
||||
metavar="DATE",
|
||||
help="Search for items added to the libray after a specific date/time, "
|
||||
"e.g. --added-after e.g. 2000-01-12T12:00:00, 2001-01-12T12:00:00-07:00, or 2000-12-31 (ISO 8601 with/without timezone).",
|
||||
type=DateTimeISO8601(),
|
||||
),
|
||||
o(
|
||||
"--added-in-last",
|
||||
metavar="TIME_DELTA",
|
||||
help="Search for items added to the library in the last TIME_DELTA, "
|
||||
"where TIME_DELTA is a string like "
|
||||
"'12 hrs', '1 day', '1d', '1 week', '2weeks', '1 month', '1 year'. "
|
||||
"for example, `--added-in-last 7d` and `--added-in-last '1 week'` are equivalent. "
|
||||
"months are assumed to be 30 days and years are assumed to be 365 days. "
|
||||
"Common English abbreviations are accepted, e.g. d, day, days or m, min, minutes.",
|
||||
type=TimeOffset(),
|
||||
),
|
||||
o("--has-comment", is_flag=True, help="Search for photos that have comments."),
|
||||
o("--no-comment", is_flag=True, help="Search for photos with no comments."),
|
||||
o("--has-likes", is_flag=True, help="Search for photos that have likes."),
|
||||
@@ -569,4 +594,3 @@ def check_version():
|
||||
"to suppress this message and prevent osxphotos from checking for latest version.",
|
||||
err=True,
|
||||
)
|
||||
|
||||
|
||||
@@ -672,145 +672,148 @@ def export(
|
||||
cli_obj,
|
||||
db,
|
||||
photos_library,
|
||||
keyword,
|
||||
person,
|
||||
album,
|
||||
folder,
|
||||
uuid,
|
||||
name,
|
||||
uuid_from_file,
|
||||
title,
|
||||
no_title,
|
||||
description,
|
||||
no_description,
|
||||
uti,
|
||||
ignore_case,
|
||||
edited,
|
||||
external_edit,
|
||||
favorite,
|
||||
not_favorite,
|
||||
hidden,
|
||||
not_hidden,
|
||||
shared,
|
||||
not_shared,
|
||||
from_date,
|
||||
to_date,
|
||||
from_time,
|
||||
to_time,
|
||||
year,
|
||||
verbose,
|
||||
timestamp,
|
||||
no_progress,
|
||||
missing,
|
||||
update,
|
||||
force_update,
|
||||
ignore_signature,
|
||||
only_new,
|
||||
dry_run,
|
||||
export_as_hardlink,
|
||||
touch_file,
|
||||
overwrite,
|
||||
retry,
|
||||
export_by_date,
|
||||
skip_edited,
|
||||
skip_original_if_edited,
|
||||
skip_bursts,
|
||||
skip_live,
|
||||
skip_raw,
|
||||
skip_uuid,
|
||||
skip_uuid_from_file,
|
||||
person_keyword,
|
||||
add_exported_to_album,
|
||||
add_missing_to_album,
|
||||
add_skipped_to_album,
|
||||
added_after,
|
||||
added_before,
|
||||
added_in_last,
|
||||
album_keyword,
|
||||
keyword_template,
|
||||
replace_keywords,
|
||||
description_template,
|
||||
finder_tag_template,
|
||||
finder_tag_keywords,
|
||||
xattr_template,
|
||||
current_name,
|
||||
convert_to_jpeg,
|
||||
jpeg_quality,
|
||||
sidecar,
|
||||
sidecar_drop_ext,
|
||||
only_photos,
|
||||
only_movies,
|
||||
album,
|
||||
beta,
|
||||
burst,
|
||||
not_burst,
|
||||
live,
|
||||
not_live,
|
||||
download_missing,
|
||||
cleanup,
|
||||
config_only,
|
||||
convert_to_jpeg,
|
||||
current_name,
|
||||
deleted_only,
|
||||
deleted,
|
||||
description_template,
|
||||
description,
|
||||
dest,
|
||||
exiftool,
|
||||
exiftool_path,
|
||||
exiftool_option,
|
||||
directory,
|
||||
download_missing,
|
||||
dry_run,
|
||||
duplicate,
|
||||
edited_suffix,
|
||||
edited,
|
||||
exif,
|
||||
exiftool_merge_keywords,
|
||||
exiftool_merge_persons,
|
||||
ignore_date_modified,
|
||||
portrait,
|
||||
not_portrait,
|
||||
screenshot,
|
||||
not_screenshot,
|
||||
slow_mo,
|
||||
not_slow_mo,
|
||||
time_lapse,
|
||||
not_time_lapse,
|
||||
hdr,
|
||||
not_hdr,
|
||||
selfie,
|
||||
not_selfie,
|
||||
panorama,
|
||||
not_panorama,
|
||||
has_raw,
|
||||
directory,
|
||||
filename_template,
|
||||
jpeg_ext,
|
||||
strip,
|
||||
edited_suffix,
|
||||
original_suffix,
|
||||
place,
|
||||
no_place,
|
||||
location,
|
||||
no_location,
|
||||
has_comment,
|
||||
no_comment,
|
||||
has_likes,
|
||||
no_likes,
|
||||
label,
|
||||
deleted,
|
||||
deleted_only,
|
||||
use_photos_export,
|
||||
use_photokit,
|
||||
report,
|
||||
cleanup,
|
||||
add_exported_to_album,
|
||||
add_skipped_to_album,
|
||||
add_missing_to_album,
|
||||
exiftool_option,
|
||||
exiftool_path,
|
||||
exiftool,
|
||||
export_as_hardlink,
|
||||
export_by_date,
|
||||
exportdb,
|
||||
ramdb,
|
||||
tmpdir,
|
||||
load_config,
|
||||
save_config,
|
||||
config_only,
|
||||
is_reference,
|
||||
beta,
|
||||
external_edit,
|
||||
favorite,
|
||||
filename_template,
|
||||
finder_tag_keywords,
|
||||
finder_tag_template,
|
||||
folder,
|
||||
force_update,
|
||||
from_date,
|
||||
from_time,
|
||||
has_comment,
|
||||
has_likes,
|
||||
has_raw,
|
||||
hdr,
|
||||
hidden,
|
||||
ignore_case,
|
||||
ignore_date_modified,
|
||||
ignore_signature,
|
||||
in_album,
|
||||
not_in_album,
|
||||
min_size,
|
||||
is_reference,
|
||||
jpeg_ext,
|
||||
jpeg_quality,
|
||||
keyword_template,
|
||||
keyword,
|
||||
label,
|
||||
live,
|
||||
load_config,
|
||||
location,
|
||||
max_size,
|
||||
regex,
|
||||
selected,
|
||||
exif,
|
||||
query_eval,
|
||||
query_function,
|
||||
duplicate,
|
||||
min_size,
|
||||
missing,
|
||||
name,
|
||||
no_comment,
|
||||
no_description,
|
||||
no_likes,
|
||||
no_location,
|
||||
no_place,
|
||||
no_progress,
|
||||
no_title,
|
||||
not_burst,
|
||||
not_favorite,
|
||||
not_hdr,
|
||||
not_hidden,
|
||||
not_in_album,
|
||||
not_live,
|
||||
not_panorama,
|
||||
not_portrait,
|
||||
not_screenshot,
|
||||
not_selfie,
|
||||
not_shared,
|
||||
not_slow_mo,
|
||||
not_time_lapse,
|
||||
only_movies,
|
||||
only_new,
|
||||
only_photos,
|
||||
original_suffix,
|
||||
overwrite,
|
||||
panorama,
|
||||
person_keyword,
|
||||
person,
|
||||
place,
|
||||
portrait,
|
||||
post_command,
|
||||
post_function,
|
||||
preview,
|
||||
preview_suffix,
|
||||
preview_if_missing,
|
||||
profile,
|
||||
preview_suffix,
|
||||
preview,
|
||||
profile_sort,
|
||||
profile,
|
||||
query_eval,
|
||||
query_function,
|
||||
ramdb,
|
||||
regex,
|
||||
replace_keywords,
|
||||
report,
|
||||
retry,
|
||||
save_config,
|
||||
screenshot,
|
||||
selected,
|
||||
selfie,
|
||||
shared,
|
||||
sidecar_drop_ext,
|
||||
sidecar,
|
||||
skip_bursts,
|
||||
skip_edited,
|
||||
skip_live,
|
||||
skip_original_if_edited,
|
||||
skip_raw,
|
||||
skip_uuid_from_file,
|
||||
skip_uuid,
|
||||
slow_mo,
|
||||
strip,
|
||||
theme,
|
||||
time_lapse,
|
||||
timestamp,
|
||||
title,
|
||||
tmpdir,
|
||||
to_date,
|
||||
to_time,
|
||||
touch_file,
|
||||
update,
|
||||
use_photokit,
|
||||
use_photos_export,
|
||||
uti,
|
||||
uuid_from_file,
|
||||
uuid,
|
||||
verbose,
|
||||
xattr_template,
|
||||
year,
|
||||
debug, # debug, watch, breakpoint handled in cli/__init__.py
|
||||
watch,
|
||||
breakpoint,
|
||||
@@ -886,6 +889,9 @@ def export(
|
||||
|
||||
# re-set the local vars to the corresponding config value
|
||||
# this isn't elegant but avoids having to rewrite this function to use cfg.varname for every parameter
|
||||
added_after = cfg.added_after
|
||||
added_before = cfg.added_before
|
||||
added_in_last = cfg.added_in_last
|
||||
add_exported_to_album = cfg.add_exported_to_album
|
||||
add_missing_to_album = cfg.add_missing_to_album
|
||||
add_skipped_to_album = cfg.add_skipped_to_album
|
||||
@@ -1038,41 +1044,41 @@ def export(
|
||||
|
||||
# validate options
|
||||
exclusive_options = [
|
||||
("favorite", "not_favorite"),
|
||||
("hidden", "not_hidden"),
|
||||
("title", "no_title"),
|
||||
("description", "no_description"),
|
||||
("only_photos", "only_movies"),
|
||||
("burst", "not_burst"),
|
||||
("live", "not_live"),
|
||||
("portrait", "not_portrait"),
|
||||
("screenshot", "not_screenshot"),
|
||||
("slow_mo", "not_slow_mo"),
|
||||
("time_lapse", "not_time_lapse"),
|
||||
("hdr", "not_hdr"),
|
||||
("selfie", "not_selfie"),
|
||||
("panorama", "not_panorama"),
|
||||
("export_by_date", "directory"),
|
||||
("export_as_hardlink", "exiftool"),
|
||||
("place", "no_place"),
|
||||
("deleted", "deleted_only"),
|
||||
("skip_edited", "skip_original_if_edited"),
|
||||
("description", "no_description"),
|
||||
("export_as_hardlink", "convert_to_jpeg"),
|
||||
("export_as_hardlink", "download_missing"),
|
||||
("shared", "not_shared"),
|
||||
("export_as_hardlink", "exiftool"),
|
||||
("export_by_date", "directory"),
|
||||
("favorite", "not_favorite"),
|
||||
("has_comment", "no_comment"),
|
||||
("has_likes", "no_likes"),
|
||||
("hdr", "not_hdr"),
|
||||
("hidden", "not_hidden"),
|
||||
("in_album", "not_in_album"),
|
||||
("live", "not_live"),
|
||||
("location", "no_location"),
|
||||
("only_photos", "only_movies"),
|
||||
("panorama", "not_panorama"),
|
||||
("place", "no_place"),
|
||||
("portrait", "not_portrait"),
|
||||
("screenshot", "not_screenshot"),
|
||||
("selfie", "not_selfie"),
|
||||
("shared", "not_shared"),
|
||||
("skip_edited", "skip_original_if_edited"),
|
||||
("slow_mo", "not_slow_mo"),
|
||||
("time_lapse", "not_time_lapse"),
|
||||
("title", "no_title"),
|
||||
]
|
||||
dependent_options = [
|
||||
("missing", ("download_missing", "use_photos_export")),
|
||||
("jpeg_quality", ("convert_to_jpeg")),
|
||||
("ignore_signature", ("update", "force_update")),
|
||||
("only_new", ("update", "force_update")),
|
||||
("exiftool_option", ("exiftool")),
|
||||
("exiftool_merge_keywords", ("exiftool", "sidecar")),
|
||||
("exiftool_merge_persons", ("exiftool", "sidecar")),
|
||||
("exiftool_option", ("exiftool")),
|
||||
("ignore_signature", ("update", "force_update")),
|
||||
("jpeg_quality", ("convert_to_jpeg")),
|
||||
("missing", ("download_missing", "use_photos_export")),
|
||||
("only_new", ("update", "force_update")),
|
||||
]
|
||||
try:
|
||||
cfg.validate(exclusive=exclusive_options, dependent=dependent_options, cli=True)
|
||||
@@ -1267,83 +1273,86 @@ def export(
|
||||
photosdb._beta = beta
|
||||
|
||||
query_options = QueryOptions(
|
||||
keyword=keyword,
|
||||
person=person,
|
||||
added_after=added_after,
|
||||
added_before=added_before,
|
||||
added_in_last=added_in_last,
|
||||
album=album,
|
||||
folder=folder,
|
||||
uuid=uuid,
|
||||
title=title,
|
||||
no_title=no_title,
|
||||
burst_photos=export_bursts,
|
||||
burst=burst,
|
||||
cloudasset=False,
|
||||
deleted_only=deleted_only,
|
||||
deleted=deleted,
|
||||
description=description,
|
||||
no_description=no_description,
|
||||
ignore_case=ignore_case,
|
||||
duplicate=duplicate,
|
||||
edited=edited,
|
||||
exif=exif,
|
||||
external_edit=external_edit,
|
||||
favorite=favorite,
|
||||
not_favorite=not_favorite,
|
||||
hidden=hidden,
|
||||
not_hidden=not_hidden,
|
||||
missing=missing,
|
||||
not_missing=None,
|
||||
shared=shared,
|
||||
not_shared=not_shared,
|
||||
photos=photos,
|
||||
movies=movies,
|
||||
uti=uti,
|
||||
burst=burst,
|
||||
not_burst=not_burst,
|
||||
live=live,
|
||||
not_live=not_live,
|
||||
cloudasset=False,
|
||||
not_cloudasset=False,
|
||||
incloud=False,
|
||||
not_incloud=False,
|
||||
folder=folder,
|
||||
from_date=from_date,
|
||||
to_date=to_date,
|
||||
from_time=from_time,
|
||||
to_time=to_time,
|
||||
year=year,
|
||||
portrait=portrait,
|
||||
not_portrait=not_portrait,
|
||||
screenshot=screenshot,
|
||||
not_screenshot=not_screenshot,
|
||||
slow_mo=slow_mo,
|
||||
not_slow_mo=not_slow_mo,
|
||||
time_lapse=time_lapse,
|
||||
not_time_lapse=not_time_lapse,
|
||||
hdr=hdr,
|
||||
not_hdr=not_hdr,
|
||||
selfie=selfie,
|
||||
not_selfie=not_selfie,
|
||||
panorama=panorama,
|
||||
not_panorama=not_panorama,
|
||||
has_raw=has_raw,
|
||||
place=place,
|
||||
no_place=no_place,
|
||||
location=location,
|
||||
no_location=no_location,
|
||||
label=label,
|
||||
deleted=deleted,
|
||||
deleted_only=deleted_only,
|
||||
function=query_function,
|
||||
has_comment=has_comment,
|
||||
no_comment=no_comment,
|
||||
has_likes=has_likes,
|
||||
no_likes=no_likes,
|
||||
is_reference=is_reference,
|
||||
has_raw=has_raw,
|
||||
hdr=hdr,
|
||||
hidden=hidden,
|
||||
ignore_case=ignore_case,
|
||||
in_album=in_album,
|
||||
not_in_album=not_in_album,
|
||||
burst_photos=export_bursts,
|
||||
incloud=False,
|
||||
is_reference=is_reference,
|
||||
keyword=keyword,
|
||||
label=label,
|
||||
live=live,
|
||||
location=location,
|
||||
max_size=max_size,
|
||||
min_size=min_size,
|
||||
# skip missing bursts if using --download-missing by itself as AppleScript otherwise causes errors
|
||||
missing_bursts=(download_missing and use_photokit) or not download_missing,
|
||||
missing=missing,
|
||||
movies=movies,
|
||||
name=name,
|
||||
min_size=min_size,
|
||||
max_size=max_size,
|
||||
regex=regex,
|
||||
selected=selected,
|
||||
exif=exif,
|
||||
no_comment=no_comment,
|
||||
no_description=no_description,
|
||||
no_likes=no_likes,
|
||||
no_location=no_location,
|
||||
no_place=no_place,
|
||||
no_title=no_title,
|
||||
not_burst=not_burst,
|
||||
not_cloudasset=False,
|
||||
not_favorite=not_favorite,
|
||||
not_hdr=not_hdr,
|
||||
not_hidden=not_hidden,
|
||||
not_in_album=not_in_album,
|
||||
not_incloud=False,
|
||||
not_live=not_live,
|
||||
not_missing=None,
|
||||
not_panorama=not_panorama,
|
||||
not_portrait=not_portrait,
|
||||
not_screenshot=not_screenshot,
|
||||
not_selfie=not_selfie,
|
||||
not_shared=not_shared,
|
||||
not_slow_mo=not_slow_mo,
|
||||
not_time_lapse=not_time_lapse,
|
||||
panorama=panorama,
|
||||
person=person,
|
||||
photos=photos,
|
||||
place=place,
|
||||
portrait=portrait,
|
||||
query_eval=query_eval,
|
||||
function=query_function,
|
||||
duplicate=duplicate,
|
||||
regex=regex,
|
||||
screenshot=screenshot,
|
||||
selected=selected,
|
||||
selfie=selfie,
|
||||
shared=shared,
|
||||
slow_mo=slow_mo,
|
||||
time_lapse=time_lapse,
|
||||
title=title,
|
||||
to_date=to_date,
|
||||
to_time=to_time,
|
||||
uti=uti,
|
||||
uuid=uuid,
|
||||
year=year,
|
||||
)
|
||||
|
||||
try:
|
||||
|
||||
@@ -2,10 +2,11 @@
|
||||
import datetime
|
||||
import os
|
||||
import pathlib
|
||||
import re
|
||||
|
||||
import bitmath
|
||||
import click
|
||||
import pytimeparse
|
||||
import pytimeparse2
|
||||
|
||||
from osxphotos.export_db_utils import export_db_get_version
|
||||
from osxphotos.photoinfo import PhotoInfoNone
|
||||
@@ -159,19 +160,31 @@ class DateOffset(click.ParamType):
|
||||
name = "DATEOFFSET"
|
||||
|
||||
def convert(self, value, param, ctx):
|
||||
offset = pytimeparse.parse(value)
|
||||
# if it's a single number treat it as days
|
||||
# but pytimeparse2 treats is as seconds so need to verify it's just a number and if so,
|
||||
# convert it to seconds
|
||||
value = value.strip()
|
||||
if re.match(r"^[+-]?\s*?\d+$", value):
|
||||
# just a number
|
||||
# strip any whitespace, e.g. for "+ 1" or "- 1"
|
||||
value = "".join(value.split())
|
||||
try:
|
||||
return datetime.timedelta(days=int(value))
|
||||
except ValueError:
|
||||
self.fail(
|
||||
f"Invalid date offset format: {value}. "
|
||||
"Valid format for date/time offset: '±D days', '±W weeks', '±M months', '±D' where D is days "
|
||||
)
|
||||
|
||||
offset = pytimeparse2.parse(value)
|
||||
if offset is not None:
|
||||
offset = offset / 86400
|
||||
return datetime.timedelta(days=offset)
|
||||
|
||||
# could be in format "-1" (negative offset) or "+1" (positive offset)
|
||||
try:
|
||||
return datetime.timedelta(days=int(value))
|
||||
except ValueError:
|
||||
self.fail(
|
||||
f"Invalid date offset format: {value}. "
|
||||
"Valid format for date/time offset: '±D days', '±W weeks', '±D' where D is days "
|
||||
)
|
||||
self.fail(
|
||||
f"Invalid date offset format: {value}. "
|
||||
"Valid format for date/time offset: '±D days', '±W weeks', '±M months', '±D' where D is days "
|
||||
)
|
||||
|
||||
|
||||
class TimeOffset(click.ParamType):
|
||||
@@ -180,18 +193,14 @@ class TimeOffset(click.ParamType):
|
||||
name = "TIMEOFFSET"
|
||||
|
||||
def convert(self, value, param, ctx):
|
||||
offset = pytimeparse.parse(value)
|
||||
offset = pytimeparse2.parse(value)
|
||||
if offset is not None:
|
||||
return datetime.timedelta(seconds=offset)
|
||||
|
||||
# could be in format "-18000" (negative offset) or "+18000" (positive offset)
|
||||
try:
|
||||
return datetime.timedelta(seconds=int(value))
|
||||
except ValueError:
|
||||
self.fail(
|
||||
f"Invalid time offset format: {value}. "
|
||||
"Valid format for date/time offset: '±HH:MM:SS', '±H hours' (or hr), '±M minutes' (or min), '±S seconds' (or sec), '±S' (where S is seconds)"
|
||||
)
|
||||
self.fail(
|
||||
f"Invalid time offset format: {value}. "
|
||||
"Valid format for date/time offset: '±HH:MM:SS', '±H hours' (or hr), '±M minutes' (or min), '±S seconds' (or sec), '±S' (where S is seconds)"
|
||||
)
|
||||
|
||||
|
||||
class UTCOffset(click.ParamType):
|
||||
|
||||
@@ -73,83 +73,86 @@ def query(
|
||||
cli_obj,
|
||||
db,
|
||||
photos_library,
|
||||
keyword,
|
||||
person,
|
||||
add_to_album,
|
||||
added_after,
|
||||
added_before,
|
||||
added_in_last,
|
||||
album,
|
||||
folder,
|
||||
name,
|
||||
uuid,
|
||||
uuid_from_file,
|
||||
title,
|
||||
no_title,
|
||||
burst,
|
||||
cloudasset,
|
||||
deleted_only,
|
||||
deleted,
|
||||
description,
|
||||
no_description,
|
||||
ignore_case,
|
||||
json_,
|
||||
duplicate,
|
||||
edited,
|
||||
exif,
|
||||
external_edit,
|
||||
favorite,
|
||||
not_favorite,
|
||||
folder,
|
||||
from_date,
|
||||
from_time,
|
||||
has_comment,
|
||||
has_likes,
|
||||
has_raw,
|
||||
hdr,
|
||||
hidden,
|
||||
not_hidden,
|
||||
ignore_case,
|
||||
in_album,
|
||||
incloud,
|
||||
is_reference,
|
||||
json_,
|
||||
keyword,
|
||||
label,
|
||||
live,
|
||||
location,
|
||||
max_size,
|
||||
min_size,
|
||||
missing,
|
||||
name,
|
||||
no_comment,
|
||||
no_description,
|
||||
no_likes,
|
||||
no_location,
|
||||
no_place,
|
||||
no_title,
|
||||
not_burst,
|
||||
not_cloudasset,
|
||||
not_favorite,
|
||||
not_hdr,
|
||||
not_hidden,
|
||||
not_in_album,
|
||||
not_incloud,
|
||||
not_live,
|
||||
not_missing,
|
||||
shared,
|
||||
not_panorama,
|
||||
not_portrait,
|
||||
not_screenshot,
|
||||
not_selfie,
|
||||
not_shared,
|
||||
not_slow_mo,
|
||||
not_time_lapse,
|
||||
only_movies,
|
||||
only_photos,
|
||||
uti,
|
||||
burst,
|
||||
not_burst,
|
||||
live,
|
||||
not_live,
|
||||
cloudasset,
|
||||
not_cloudasset,
|
||||
incloud,
|
||||
not_incloud,
|
||||
from_date,
|
||||
to_date,
|
||||
from_time,
|
||||
to_time,
|
||||
year,
|
||||
portrait,
|
||||
not_portrait,
|
||||
screenshot,
|
||||
not_screenshot,
|
||||
slow_mo,
|
||||
not_slow_mo,
|
||||
time_lapse,
|
||||
not_time_lapse,
|
||||
hdr,
|
||||
not_hdr,
|
||||
selfie,
|
||||
not_selfie,
|
||||
panorama,
|
||||
not_panorama,
|
||||
has_raw,
|
||||
person,
|
||||
place,
|
||||
no_place,
|
||||
location,
|
||||
no_location,
|
||||
label,
|
||||
deleted,
|
||||
deleted_only,
|
||||
has_comment,
|
||||
no_comment,
|
||||
has_likes,
|
||||
no_likes,
|
||||
is_reference,
|
||||
in_album,
|
||||
not_in_album,
|
||||
duplicate,
|
||||
min_size,
|
||||
max_size,
|
||||
regex,
|
||||
selected,
|
||||
exif,
|
||||
portrait,
|
||||
query_eval,
|
||||
query_function,
|
||||
add_to_album,
|
||||
regex,
|
||||
screenshot,
|
||||
selected,
|
||||
selfie,
|
||||
shared,
|
||||
slow_mo,
|
||||
time_lapse,
|
||||
title,
|
||||
to_date,
|
||||
to_time,
|
||||
uti,
|
||||
uuid_from_file,
|
||||
uuid,
|
||||
year,
|
||||
debug, # handled in cli/__init__.py
|
||||
):
|
||||
"""Query the Photos database using 1 or more search options;
|
||||
@@ -160,58 +163,61 @@ def query(
|
||||
# if no query terms, show help and return
|
||||
# sanity check input args
|
||||
nonexclusive = [
|
||||
keyword,
|
||||
person,
|
||||
added_after,
|
||||
added_before,
|
||||
added_in_last,
|
||||
album,
|
||||
folder,
|
||||
name,
|
||||
uuid,
|
||||
uuid_from_file,
|
||||
duplicate,
|
||||
edited,
|
||||
exif,
|
||||
external_edit,
|
||||
uti,
|
||||
has_raw,
|
||||
folder,
|
||||
from_date,
|
||||
to_date,
|
||||
from_time,
|
||||
to_time,
|
||||
year,
|
||||
label,
|
||||
has_raw,
|
||||
is_reference,
|
||||
keyword,
|
||||
label,
|
||||
max_size,
|
||||
min_size,
|
||||
name,
|
||||
person,
|
||||
query_eval,
|
||||
query_function,
|
||||
min_size,
|
||||
max_size,
|
||||
regex,
|
||||
selected,
|
||||
exif,
|
||||
duplicate,
|
||||
to_date,
|
||||
to_time,
|
||||
uti,
|
||||
uuid_from_file,
|
||||
uuid,
|
||||
year,
|
||||
]
|
||||
exclusive = [
|
||||
(favorite, not_favorite),
|
||||
(hidden, not_hidden),
|
||||
(missing, not_missing),
|
||||
(any(title), no_title),
|
||||
(any(description), no_description),
|
||||
(only_photos, only_movies),
|
||||
(burst, not_burst),
|
||||
(live, not_live),
|
||||
(cloudasset, not_cloudasset),
|
||||
(incloud, not_incloud),
|
||||
(portrait, not_portrait),
|
||||
(screenshot, not_screenshot),
|
||||
(slow_mo, not_slow_mo),
|
||||
(time_lapse, not_time_lapse),
|
||||
(hdr, not_hdr),
|
||||
(selfie, not_selfie),
|
||||
(panorama, not_panorama),
|
||||
(any(place), no_place),
|
||||
(any(title), no_title),
|
||||
(burst, not_burst),
|
||||
(cloudasset, not_cloudasset),
|
||||
(deleted, deleted_only),
|
||||
(shared, not_shared),
|
||||
(favorite, not_favorite),
|
||||
(has_comment, no_comment),
|
||||
(has_likes, no_likes),
|
||||
(hdr, not_hdr),
|
||||
(hidden, not_hidden),
|
||||
(in_album, not_in_album),
|
||||
(incloud, not_incloud),
|
||||
(live, not_live),
|
||||
(location, no_location),
|
||||
(missing, not_missing),
|
||||
(only_photos, only_movies),
|
||||
(panorama, not_panorama),
|
||||
(portrait, not_portrait),
|
||||
(screenshot, not_screenshot),
|
||||
(selfie, not_selfie),
|
||||
(shared, not_shared),
|
||||
(slow_mo, not_slow_mo),
|
||||
(time_lapse, not_time_lapse),
|
||||
]
|
||||
# print help if no non-exclusive term or a double exclusive term is given
|
||||
if any(all(bb) for bb in exclusive) or not any(
|
||||
@@ -247,80 +253,83 @@ def query(
|
||||
|
||||
photosdb = osxphotos.PhotosDB(dbfile=db)
|
||||
query_options = QueryOptions(
|
||||
keyword=keyword,
|
||||
person=person,
|
||||
added_after=added_after,
|
||||
added_before=added_before,
|
||||
added_in_last=added_in_last,
|
||||
album=album,
|
||||
folder=folder,
|
||||
uuid=uuid,
|
||||
title=title,
|
||||
no_title=no_title,
|
||||
burst=burst,
|
||||
cloudasset=cloudasset,
|
||||
deleted_only=deleted_only,
|
||||
deleted=deleted,
|
||||
description=description,
|
||||
no_description=no_description,
|
||||
ignore_case=ignore_case,
|
||||
duplicate=duplicate,
|
||||
edited=edited,
|
||||
exif=exif,
|
||||
external_edit=external_edit,
|
||||
favorite=favorite,
|
||||
not_favorite=not_favorite,
|
||||
hidden=hidden,
|
||||
not_hidden=not_hidden,
|
||||
missing=missing,
|
||||
not_missing=not_missing,
|
||||
shared=shared,
|
||||
not_shared=not_shared,
|
||||
photos=photos,
|
||||
movies=movies,
|
||||
uti=uti,
|
||||
burst=burst,
|
||||
not_burst=not_burst,
|
||||
live=live,
|
||||
not_live=not_live,
|
||||
cloudasset=cloudasset,
|
||||
not_cloudasset=not_cloudasset,
|
||||
incloud=incloud,
|
||||
not_incloud=not_incloud,
|
||||
folder=folder,
|
||||
from_date=from_date,
|
||||
to_date=to_date,
|
||||
from_time=from_time,
|
||||
to_time=to_time,
|
||||
year=year,
|
||||
portrait=portrait,
|
||||
not_portrait=not_portrait,
|
||||
screenshot=screenshot,
|
||||
not_screenshot=not_screenshot,
|
||||
slow_mo=slow_mo,
|
||||
not_slow_mo=not_slow_mo,
|
||||
time_lapse=time_lapse,
|
||||
not_time_lapse=not_time_lapse,
|
||||
hdr=hdr,
|
||||
not_hdr=not_hdr,
|
||||
selfie=selfie,
|
||||
not_selfie=not_selfie,
|
||||
panorama=panorama,
|
||||
not_panorama=not_panorama,
|
||||
has_raw=has_raw,
|
||||
place=place,
|
||||
no_place=no_place,
|
||||
location=location,
|
||||
no_location=no_location,
|
||||
label=label,
|
||||
deleted=deleted,
|
||||
deleted_only=deleted_only,
|
||||
has_comment=has_comment,
|
||||
no_comment=no_comment,
|
||||
has_likes=has_likes,
|
||||
no_likes=no_likes,
|
||||
is_reference=is_reference,
|
||||
in_album=in_album,
|
||||
not_in_album=not_in_album,
|
||||
name=name,
|
||||
min_size=min_size,
|
||||
max_size=max_size,
|
||||
query_eval=query_eval,
|
||||
function=query_function,
|
||||
has_comment=has_comment,
|
||||
has_likes=has_likes,
|
||||
has_raw=has_raw,
|
||||
hdr=hdr,
|
||||
hidden=hidden,
|
||||
ignore_case=ignore_case,
|
||||
in_album=in_album,
|
||||
incloud=incloud,
|
||||
is_reference=is_reference,
|
||||
keyword=keyword,
|
||||
label=label,
|
||||
live=live,
|
||||
location=location,
|
||||
max_size=max_size,
|
||||
min_size=min_size,
|
||||
missing=missing,
|
||||
movies=movies,
|
||||
name=name,
|
||||
no_comment=no_comment,
|
||||
no_description=no_description,
|
||||
no_likes=no_likes,
|
||||
no_location=no_location,
|
||||
no_place=no_place,
|
||||
no_title=no_title,
|
||||
not_burst=not_burst,
|
||||
not_cloudasset=not_cloudasset,
|
||||
not_favorite=not_favorite,
|
||||
not_hdr=not_hdr,
|
||||
not_hidden=not_hidden,
|
||||
not_in_album=not_in_album,
|
||||
not_incloud=not_incloud,
|
||||
not_live=not_live,
|
||||
not_missing=not_missing,
|
||||
not_panorama=not_panorama,
|
||||
not_portrait=not_portrait,
|
||||
not_screenshot=not_screenshot,
|
||||
not_selfie=not_selfie,
|
||||
not_shared=not_shared,
|
||||
not_slow_mo=not_slow_mo,
|
||||
not_time_lapse=not_time_lapse,
|
||||
panorama=panorama,
|
||||
person=person,
|
||||
photos=photos,
|
||||
place=place,
|
||||
portrait=portrait,
|
||||
query_eval=query_eval,
|
||||
regex=regex,
|
||||
screenshot=screenshot,
|
||||
selected=selected,
|
||||
exif=exif,
|
||||
duplicate=duplicate,
|
||||
selfie=selfie,
|
||||
shared=shared,
|
||||
slow_mo=slow_mo,
|
||||
time_lapse=time_lapse,
|
||||
title=title,
|
||||
to_date=to_date,
|
||||
to_time=to_time,
|
||||
uti=uti,
|
||||
uuid=uuid,
|
||||
year=year,
|
||||
)
|
||||
|
||||
try:
|
||||
|
||||
@@ -241,55 +241,58 @@ def _query_options_from_kwargs(**kwargs) -> QueryOptions:
|
||||
"""Validate query options and create a QueryOptions instance"""
|
||||
# sanity check input args
|
||||
nonexclusive = [
|
||||
"keyword",
|
||||
"person",
|
||||
"added_after",
|
||||
"added_before",
|
||||
"added_in_last",
|
||||
"album",
|
||||
"folder",
|
||||
"name",
|
||||
"uuid",
|
||||
"uuid_from_file",
|
||||
"duplicate",
|
||||
"edited",
|
||||
"exif",
|
||||
"external_edit",
|
||||
"uti",
|
||||
"has_raw",
|
||||
"folder",
|
||||
"from_date",
|
||||
"to_date",
|
||||
"from_time",
|
||||
"to_time",
|
||||
"year",
|
||||
"label",
|
||||
"has_raw",
|
||||
"is_reference",
|
||||
"keyword",
|
||||
"label",
|
||||
"max_size",
|
||||
"min_size",
|
||||
"name",
|
||||
"person",
|
||||
"query_eval",
|
||||
"query_function",
|
||||
"min_size",
|
||||
"max_size",
|
||||
"regex",
|
||||
"selected",
|
||||
"exif",
|
||||
"duplicate",
|
||||
"to_date",
|
||||
"to_time",
|
||||
"uti",
|
||||
"uuid_from_file",
|
||||
"uuid",
|
||||
"year",
|
||||
]
|
||||
exclusive = [
|
||||
("favorite", "not_favorite"),
|
||||
("hidden", "not_hidden"),
|
||||
("missing", "not_missing"),
|
||||
("only_photos", "only_movies"),
|
||||
("burst", "not_burst"),
|
||||
("live", "not_live"),
|
||||
("cloudasset", "not_cloudasset"),
|
||||
("incloud", "not_incloud"),
|
||||
("portrait", "not_portrait"),
|
||||
("screenshot", "not_screenshot"),
|
||||
("slow_mo", "not_slow_mo"),
|
||||
("time_lapse", "not_time_lapse"),
|
||||
("hdr", "not_hdr"),
|
||||
("selfie", "not_selfie"),
|
||||
("panorama", "not_panorama"),
|
||||
("deleted", "deleted_only"),
|
||||
("shared", "not_shared"),
|
||||
("favorite", "not_favorite"),
|
||||
("has_comment", "no_comment"),
|
||||
("has_likes", "no_likes"),
|
||||
("hdr", "not_hdr"),
|
||||
("hidden", "not_hidden"),
|
||||
("in_album", "not_in_album"),
|
||||
("incloud", "not_incloud"),
|
||||
("live", "not_live"),
|
||||
("location", "no_location"),
|
||||
("missing", "not_missing"),
|
||||
("only_photos", "only_movies"),
|
||||
("panorama", "not_panorama"),
|
||||
("portrait", "not_portrait"),
|
||||
("screenshot", "not_screenshot"),
|
||||
("selfie", "not_selfie"),
|
||||
("shared", "not_shared"),
|
||||
("slow_mo", "not_slow_mo"),
|
||||
("time_lapse", "not_time_lapse"),
|
||||
]
|
||||
# print help if no non-exclusive term or a double exclusive term is given
|
||||
# TODO: add option to validate requiring at least one query arg
|
||||
|
||||
Binary file not shown.
@@ -2,13 +2,11 @@
|
||||
"""
|
||||
|
||||
import dataclasses
|
||||
import hashlib
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import pathlib
|
||||
import re
|
||||
import tempfile
|
||||
import typing as t
|
||||
from collections import namedtuple # pylint: disable=syntax-error
|
||||
from dataclasses import asdict, dataclass
|
||||
@@ -45,14 +43,13 @@ from .photokit import (
|
||||
from .phototemplate import RenderOptions
|
||||
from .rich_utils import add_rich_markup_tag
|
||||
from .uti import get_preferred_uti_extension
|
||||
from .utils import increment_filename, lineno, list_directory
|
||||
from .utils import hexdigest, increment_filename, lineno, list_directory
|
||||
|
||||
__all__ = [
|
||||
"ExportError",
|
||||
"ExportOptions",
|
||||
"ExportResults",
|
||||
"PhotoExporter",
|
||||
"hexdigest",
|
||||
"rename_jpeg_files",
|
||||
]
|
||||
|
||||
@@ -266,6 +263,7 @@ class ExportResults:
|
||||
exported_album=None,
|
||||
skipped_album=None,
|
||||
missing_album=None,
|
||||
metadata_changed=None,
|
||||
):
|
||||
self.exported = exported or []
|
||||
self.new = new or []
|
||||
@@ -292,6 +290,7 @@ class ExportResults:
|
||||
self.exported_album = exported_album or []
|
||||
self.skipped_album = skipped_album or []
|
||||
self.missing_album = missing_album or []
|
||||
self.metadata_changed = metadata_changed or []
|
||||
|
||||
def all_files(self):
|
||||
"""return all filenames contained in results"""
|
||||
@@ -342,6 +341,7 @@ class ExportResults:
|
||||
self.exported_album += other.exported_album
|
||||
self.skipped_album += other.skipped_album
|
||||
self.missing_album += other.missing_album
|
||||
self.metadata_changed += other.metadata_changed
|
||||
|
||||
return self
|
||||
|
||||
@@ -371,12 +371,14 @@ class ExportResults:
|
||||
+ f",exported_album={self.exported_album}"
|
||||
+ f",skipped_album={self.skipped_album}"
|
||||
+ f",missing_album={self.missing_album}"
|
||||
+ f",metadata_changed={self.metadata_changed}"
|
||||
+ ")"
|
||||
)
|
||||
|
||||
|
||||
class PhotoExporter:
|
||||
"""Export a photo"""
|
||||
|
||||
def __init__(self, photo: "PhotoInfo", tmpdir: t.Optional[str] = None):
|
||||
self.photo = photo
|
||||
self._render_options = RenderOptions()
|
||||
@@ -739,7 +741,7 @@ class PhotoExporter:
|
||||
return ShouldUpdate.EDITED_SIG_DIFFERENT
|
||||
|
||||
if options.force_update:
|
||||
current_digest = hexdigest(self.photo.json())
|
||||
current_digest = self.photo.hexdigest
|
||||
if current_digest != file_record.digest:
|
||||
# metadata in Photos changed, force update
|
||||
return ShouldUpdate.DIGEST_DIFFERENT
|
||||
@@ -1179,8 +1181,9 @@ class PhotoExporter:
|
||||
rec.dest_sig = fileutil.file_sig(dest)
|
||||
if options.exiftool:
|
||||
rec.exifdata = self._exiftool_json_sidecar(options)
|
||||
if options.force_update:
|
||||
rec.digest = hexdigest(photoinfo)
|
||||
if self.photo.hexdigest != rec.digest:
|
||||
results.metadata_changed = [dest_str]
|
||||
rec.digest = self.photo.hexdigest
|
||||
|
||||
return results
|
||||
|
||||
@@ -2011,13 +2014,6 @@ class PhotoExporter:
|
||||
f.close()
|
||||
|
||||
|
||||
def hexdigest(strval):
|
||||
"""hexdigest of a string, using blake2b"""
|
||||
h = hashlib.blake2b(digest_size=20)
|
||||
h.update(bytes(strval, "utf-8"))
|
||||
return h.hexdigest()
|
||||
|
||||
|
||||
def _check_export_suffix(src, dest, edited):
|
||||
"""Helper function for exporting photos to check file extensions of destination path.
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import os
|
||||
import os.path
|
||||
import pathlib
|
||||
from datetime import timedelta, timezone
|
||||
from functools import cached_property
|
||||
from typing import Optional
|
||||
|
||||
import yaml
|
||||
@@ -54,7 +55,7 @@ from .scoreinfo import ScoreInfo
|
||||
from .searchinfo import SearchInfo
|
||||
from .text_detection import detect_text
|
||||
from .uti import get_preferred_uti_extension, get_uti_for_extension
|
||||
from .utils import _get_resource_loc, list_directory
|
||||
from .utils import _get_resource_loc, hexdigest, list_directory
|
||||
|
||||
__all__ = ["PhotoInfo", "PhotoInfoNone"]
|
||||
|
||||
@@ -1356,6 +1357,12 @@ class PhotoInfo:
|
||||
self._exiftool = exiftool
|
||||
return self._exiftool
|
||||
|
||||
@cached_property
|
||||
def hexdigest(self):
|
||||
"""Returns a unique digest of the photo's properties and metadata;
|
||||
useful for detecting changes in any property/metadata of the photo"""
|
||||
return hexdigest(self.json())
|
||||
|
||||
def detected_text(self, confidence_threshold=TEXT_DETECTION_CONFIDENCE_THRESHOLD):
|
||||
"""Detects text in photo and returns lists of results as (detected text, confidence)
|
||||
|
||||
|
||||
@@ -3446,6 +3446,23 @@ class PhotosDB:
|
||||
matching_photos.append(p)
|
||||
photos = matching_photos
|
||||
|
||||
if options.added_after:
|
||||
added_after = options.added_after
|
||||
if not datetime_has_tz(added_after):
|
||||
added_after = datetime_naive_to_local(added_after)
|
||||
photos = [p for p in photos if p.date_added and p.date_added > added_after]
|
||||
|
||||
if options.added_before:
|
||||
added_before = options.added_before
|
||||
if not datetime_has_tz(added_before):
|
||||
added_before = datetime_naive_to_local(added_before)
|
||||
photos = [p for p in photos if p.date_added and p.date_added < added_before]
|
||||
|
||||
if options.added_in_last:
|
||||
added_after = datetime.now() - options.added_in_last
|
||||
added_after = datetime_naive_to_local(added_after)
|
||||
photos = [p for p in photos if p.date_added and p.date_added > added_after]
|
||||
|
||||
if options.function:
|
||||
for function in options.function:
|
||||
photos = function[0](photos)
|
||||
|
||||
@@ -15,158 +15,163 @@ class QueryOptions:
|
||||
"""QueryOptions class for PhotosDB.query
|
||||
|
||||
Attributes:
|
||||
keyword: list of keywords to search for
|
||||
person: list of person names to search for
|
||||
added_after: search for photos added after a given date
|
||||
added_before: search for photos added before a given date
|
||||
added_in_last: search for photos added in last X datetime.timedelta
|
||||
album: list of album names to search for
|
||||
folder: list of folder names to search for
|
||||
uuid: list of uuids to search for
|
||||
title: list of titles to search for
|
||||
no_title: search for photos with no title
|
||||
burst_photos: search for burst photos
|
||||
burst: search for burst photos
|
||||
cloudasset: search for photos that are managed by iCloud
|
||||
deleted_only: search only for deleted photos
|
||||
deleted: also include deleted photos
|
||||
description: list of descriptions to search for
|
||||
no_description: search for photos with no description
|
||||
ignore_case: ignore case when searching
|
||||
duplicate: search for duplicate photos
|
||||
edited: search for edited photos
|
||||
exif: search for photos with EXIF tags that matches the given data
|
||||
external_edit: search for photos edited in external apps
|
||||
favorite: search for favorite photos
|
||||
not_favorite: search for non-favorite photos
|
||||
hidden: search for hidden photos
|
||||
not_hidden: search for non-hidden photos
|
||||
missing: search for missing photos
|
||||
not_missing: search for non-missing photos
|
||||
shared: search for shared photos
|
||||
not_shared: search for non-shared photos
|
||||
photos: search for photos
|
||||
movies: search for movies
|
||||
uti: list of UTIs to search for
|
||||
burst: search for burst photos
|
||||
not_burst: search for non-burst photos
|
||||
live: search for live photos
|
||||
not_live: search for non-live photos
|
||||
cloudasset: search for photos that are managed by iCloud
|
||||
not_cloudasset: search for photos that are not managed by iCloud
|
||||
incloud: search for cloud assets that are synched to iCloud
|
||||
not_incloud: search for cloud asset photos that are not yet synched to iCloud
|
||||
folder: list of folder names to search for
|
||||
from_date: search for photos taken on or after this date
|
||||
to_date: search for photos taken on or before this date
|
||||
portrait: search for portrait photos
|
||||
not_portrait: search for non-portrait photos
|
||||
screenshot: search for screenshot photos
|
||||
not_screenshot: search for non-screenshot photos
|
||||
slow_mo: search for slow-mo photos
|
||||
not_slow_mo: search for non-slow-mo photos
|
||||
time_lapse: search for time-lapse photos
|
||||
not_time_lapse: search for non-time-lapse photos
|
||||
hdr: search for HDR photos
|
||||
not_hdr: search for non-HDR photos
|
||||
selfie: search for selfie photos
|
||||
not_selfie: search for non-selfie photos
|
||||
panorama: search for panorama photos
|
||||
not_panorama: search for non-panorama photos
|
||||
has_raw: search for photos with associated raw files
|
||||
place: list of place names to search for
|
||||
no_place: search for photos with no place
|
||||
label: list of labels to search for
|
||||
deleted: also include deleted photos
|
||||
deleted_only: search only for deleted photos
|
||||
has_comment: search for photos with comments
|
||||
no_comment: search for photos with no comments
|
||||
has_likes: search for shared photos with likes
|
||||
no_likes: search for shared photos with no likes
|
||||
is_reference: search for photos stored by reference (that is, they are not managed by Photos)
|
||||
in_album: search for photos in an album
|
||||
not_in_album: search for photos not in an album
|
||||
burst_photos: search for burst photos
|
||||
missing_bursts: for burst photos, also include burst photos that are missing
|
||||
name: list of names to search for
|
||||
min_size: minimum size of photos to search for
|
||||
max_size: maximum size of photos to search for
|
||||
regex: list of regular expressions to search for
|
||||
query_eval: list of query expressions to evaluate
|
||||
duplicate: search for duplicate photos
|
||||
location: search for photos with a location
|
||||
no_location: search for photos with no location
|
||||
function: list of query functions to evaluate
|
||||
has_comment: search for photos with comments
|
||||
has_likes: search for shared photos with likes
|
||||
has_raw: search for photos with associated raw files
|
||||
hdr: search for HDR photos
|
||||
hidden: search for hidden photos
|
||||
ignore_case: ignore case when searching
|
||||
in_album: search for photos in an album
|
||||
incloud: search for cloud assets that are synched to iCloud
|
||||
is_reference: search for photos stored by reference (that is, they are not managed by Photos)
|
||||
keyword: list of keywords to search for
|
||||
label: list of labels to search for
|
||||
live: search for live photos
|
||||
location: search for photos with a location
|
||||
max_size: maximum size of photos to search for
|
||||
min_size: minimum size of photos to search for
|
||||
missing_bursts: for burst photos, also include burst photos that are missing
|
||||
missing: search for missing photos
|
||||
movies: search for movies
|
||||
name: list of names to search for
|
||||
no_comment: search for photos with no comments
|
||||
no_description: search for photos with no description
|
||||
no_likes: search for shared photos with no likes
|
||||
no_location: search for photos with no location
|
||||
no_place: search for photos with no place
|
||||
no_title: search for photos with no title
|
||||
not_burst: search for non-burst photos
|
||||
not_cloudasset: search for photos that are not managed by iCloud
|
||||
not_favorite: search for non-favorite photos
|
||||
not_hdr: search for non-HDR photos
|
||||
not_hidden: search for non-hidden photos
|
||||
not_in_album: search for photos not in an album
|
||||
not_incloud: search for cloud asset photos that are not yet synched to iCloud
|
||||
not_live: search for non-live photos
|
||||
not_missing: search for non-missing photos
|
||||
not_panorama: search for non-panorama photos
|
||||
not_portrait: search for non-portrait photos
|
||||
not_screenshot: search for non-screenshot photos
|
||||
not_selfie: search for non-selfie photos
|
||||
not_shared: search for non-shared photos
|
||||
not_slow_mo: search for non-slow-mo photos
|
||||
not_time_lapse: search for non-time-lapse photos
|
||||
panorama: search for panorama photos
|
||||
person: list of person names to search for
|
||||
photos: search for photos
|
||||
place: list of place names to search for
|
||||
portrait: search for portrait photos
|
||||
query_eval: list of query expressions to evaluate
|
||||
regex: list of regular expressions to search for
|
||||
screenshot: search for screenshot photos
|
||||
selected: search for selected photos
|
||||
exif: search for photos with EXIF tags that matches the given data
|
||||
selfie: search for selfie photos
|
||||
shared: search for shared photos
|
||||
slow_mo: search for slow-mo photos
|
||||
time_lapse: search for time-lapse photos
|
||||
title: list of titles to search for
|
||||
to_date: search for photos taken on or before this date
|
||||
uti: list of UTIs to search for
|
||||
uuid: list of uuids to search for
|
||||
year: search for photos taken in a given year
|
||||
|
||||
"""
|
||||
|
||||
keyword: Optional[Iterable[str]] = None
|
||||
person: Optional[Iterable[str]] = None
|
||||
added_after: Optional[datetime.datetime] = None
|
||||
added_before: Optional[datetime.datetime] = None
|
||||
added_in_last: Optional[datetime.timedelta] = None
|
||||
album: Optional[Iterable[str]] = None
|
||||
folder: Optional[Iterable[str]] = None
|
||||
uuid: Optional[Iterable[str]] = None
|
||||
title: Optional[Iterable[str]] = None
|
||||
no_title: Optional[bool] = None
|
||||
burst_photos: Optional[bool] = None
|
||||
burst: Optional[bool] = None
|
||||
cloudasset: Optional[bool] = None
|
||||
deleted_only: Optional[bool] = None
|
||||
deleted: Optional[bool] = None
|
||||
description: Optional[Iterable[str]] = None
|
||||
no_description: Optional[bool] = None
|
||||
ignore_case: Optional[bool] = None
|
||||
duplicate: Optional[bool] = None
|
||||
edited: Optional[bool] = None
|
||||
exif: Optional[Iterable[Tuple[str, str]]] = None
|
||||
external_edit: Optional[bool] = None
|
||||
favorite: Optional[bool] = None
|
||||
not_favorite: Optional[bool] = None
|
||||
hidden: Optional[bool] = None
|
||||
not_hidden: Optional[bool] = None
|
||||
missing: Optional[bool] = None
|
||||
not_missing: Optional[bool] = None
|
||||
shared: Optional[bool] = None
|
||||
not_shared: Optional[bool] = None
|
||||
photos: Optional[bool] = True
|
||||
movies: Optional[bool] = True
|
||||
uti: Optional[Iterable[str]] = None
|
||||
burst: Optional[bool] = None
|
||||
not_burst: Optional[bool] = None
|
||||
live: Optional[bool] = None
|
||||
not_live: Optional[bool] = None
|
||||
cloudasset: Optional[bool] = None
|
||||
not_cloudasset: Optional[bool] = None
|
||||
incloud: Optional[bool] = None
|
||||
not_incloud: Optional[bool] = None
|
||||
folder: Optional[Iterable[str]] = None
|
||||
from_date: Optional[datetime.datetime] = None
|
||||
to_date: Optional[datetime.datetime] = None
|
||||
from_time: Optional[datetime.time] = None
|
||||
to_time: Optional[datetime.time] = None
|
||||
portrait: Optional[bool] = None
|
||||
not_portrait: Optional[bool] = None
|
||||
screenshot: Optional[bool] = None
|
||||
not_screenshot: Optional[bool] = None
|
||||
slow_mo: Optional[bool] = None
|
||||
not_slow_mo: Optional[bool] = None
|
||||
time_lapse: Optional[bool] = None
|
||||
not_time_lapse: Optional[bool] = None
|
||||
hdr: Optional[bool] = None
|
||||
not_hdr: Optional[bool] = None
|
||||
selfie: Optional[bool] = None
|
||||
not_selfie: Optional[bool] = None
|
||||
panorama: Optional[bool] = None
|
||||
not_panorama: Optional[bool] = None
|
||||
has_raw: Optional[bool] = None
|
||||
place: Optional[Iterable[str]] = None
|
||||
no_place: Optional[bool] = None
|
||||
label: Optional[Iterable[str]] = None
|
||||
deleted: Optional[bool] = None
|
||||
deleted_only: Optional[bool] = None
|
||||
has_comment: Optional[bool] = None
|
||||
no_comment: Optional[bool] = None
|
||||
has_likes: Optional[bool] = None
|
||||
no_likes: Optional[bool] = None
|
||||
is_reference: Optional[bool] = None
|
||||
in_album: Optional[bool] = None
|
||||
not_in_album: Optional[bool] = None
|
||||
burst_photos: Optional[bool] = None
|
||||
missing_bursts: Optional[bool] = None
|
||||
name: Optional[Iterable[str]] = None
|
||||
min_size: Optional[bitmath.Byte] = None
|
||||
max_size: Optional[bitmath.Byte] = None
|
||||
regex: Optional[Iterable[Tuple[str, str]]] = None
|
||||
query_eval: Optional[Iterable[str]] = None
|
||||
duplicate: Optional[bool] = None
|
||||
location: Optional[bool] = None
|
||||
no_location: Optional[bool] = None
|
||||
function: Optional[List[Tuple[callable, str]]] = None
|
||||
has_comment: Optional[bool] = None
|
||||
has_likes: Optional[bool] = None
|
||||
has_raw: Optional[bool] = None
|
||||
hdr: Optional[bool] = None
|
||||
hidden: Optional[bool] = None
|
||||
ignore_case: Optional[bool] = None
|
||||
in_album: Optional[bool] = None
|
||||
incloud: Optional[bool] = None
|
||||
is_reference: Optional[bool] = None
|
||||
keyword: Optional[Iterable[str]] = None
|
||||
label: Optional[Iterable[str]] = None
|
||||
live: Optional[bool] = None
|
||||
location: Optional[bool] = None
|
||||
max_size: Optional[bitmath.Byte] = None
|
||||
min_size: Optional[bitmath.Byte] = None
|
||||
missing_bursts: Optional[bool] = None
|
||||
missing: Optional[bool] = None
|
||||
movies: Optional[bool] = True
|
||||
name: Optional[Iterable[str]] = None
|
||||
no_comment: Optional[bool] = None
|
||||
no_description: Optional[bool] = None
|
||||
no_likes: Optional[bool] = None
|
||||
no_location: Optional[bool] = None
|
||||
no_place: Optional[bool] = None
|
||||
no_title: Optional[bool] = None
|
||||
not_burst: Optional[bool] = None
|
||||
not_cloudasset: Optional[bool] = None
|
||||
not_favorite: Optional[bool] = None
|
||||
not_hdr: Optional[bool] = None
|
||||
not_hidden: Optional[bool] = None
|
||||
not_in_album: Optional[bool] = None
|
||||
not_incloud: Optional[bool] = None
|
||||
not_live: Optional[bool] = None
|
||||
not_missing: Optional[bool] = None
|
||||
not_panorama: Optional[bool] = None
|
||||
not_portrait: Optional[bool] = None
|
||||
not_screenshot: Optional[bool] = None
|
||||
not_selfie: Optional[bool] = None
|
||||
not_shared: Optional[bool] = None
|
||||
not_slow_mo: Optional[bool] = None
|
||||
not_time_lapse: Optional[bool] = None
|
||||
panorama: Optional[bool] = None
|
||||
person: Optional[Iterable[str]] = None
|
||||
photos: Optional[bool] = True
|
||||
place: Optional[Iterable[str]] = None
|
||||
portrait: Optional[bool] = None
|
||||
query_eval: Optional[Iterable[str]] = None
|
||||
regex: Optional[Iterable[Tuple[str, str]]] = None
|
||||
screenshot: Optional[bool] = None
|
||||
selected: Optional[bool] = None
|
||||
exif: Optional[Iterable[Tuple[str, str]]] = None
|
||||
selfie: Optional[bool] = None
|
||||
shared: Optional[bool] = None
|
||||
slow_mo: Optional[bool] = None
|
||||
time_lapse: Optional[bool] = None
|
||||
title: Optional[Iterable[str]] = None
|
||||
to_date: Optional[datetime.datetime] = None
|
||||
to_time: Optional[datetime.time] = None
|
||||
uti: Optional[Iterable[str]] = None
|
||||
uuid: Optional[Iterable[str]] = None
|
||||
year: Optional[Iterable[int]] = None
|
||||
|
||||
def asdict(self):
|
||||
|
||||
@@ -8,7 +8,7 @@ import re
|
||||
|
||||
def utc_offset_string_to_seconds(utc_offset: str) -> int:
|
||||
"""match a UTC offset in format ±[hh]:[mm], ±[h]:[mm], or ±[hh][mm] and return number of seconds offset"""
|
||||
patterns = ["^([+-]?)(\d{1,2}):(\d{2})$", "^([+-]?)(\d{2})(\d{2})$"]
|
||||
patterns = [r"^([+-]?)(\d{1,2}):(\d{2})$", r"^([+-]?)(\d{2})(\d{2})$"]
|
||||
for pattern in patterns:
|
||||
match = re.match(pattern, utc_offset)
|
||||
if not match:
|
||||
@@ -56,7 +56,7 @@ def update_datetime(
|
||||
return dt
|
||||
|
||||
|
||||
def time_string_to_datetime(time: str) -> datetime.datetime:
|
||||
def time_string_to_datetime(time: str) -> datetime.time:
|
||||
"""Convert time string to datetime.datetime"""
|
||||
|
||||
""" valid time formats:
|
||||
@@ -74,7 +74,7 @@ def time_string_to_datetime(time: str) -> datetime.datetime:
|
||||
|
||||
for dt_format in time_formats:
|
||||
try:
|
||||
parsed_dt = datetime.datetime.strptime(time, dt_format)
|
||||
parsed_dt = datetime.datetime.strptime(time, dt_format).time()
|
||||
except ValueError as e:
|
||||
pass
|
||||
else:
|
||||
|
||||
@@ -54,3 +54,8 @@ class Timezone:
|
||||
|
||||
def __repr__(self):
|
||||
return self.name
|
||||
|
||||
def __eq__(self, other):
|
||||
if isinstance(other, Timezone):
|
||||
return self.timezone == other.timezone
|
||||
return False
|
||||
|
||||
@@ -252,6 +252,10 @@ You can also export photos in a certain date range:
|
||||
|
||||
`osxphotos export /path/to/export --from-date "2020-01-01" --to-date "2020-02-28"`
|
||||
|
||||
or photos added to the library in the last week:
|
||||
|
||||
`osxphotos export /path/to/export --added-in-last "1 week"`
|
||||
|
||||
## Converting images to JPEG on export
|
||||
|
||||
Photos can store images in many different formats. osxphotos can convert non-JPEG images (for example, RAW photos) to JPEG on export using the `--convert-to-jpeg` option. You can specify the JPEG quality (0: worst, 1.0: best) using `--jpeg-quality`. For example:
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
import datetime
|
||||
import fnmatch
|
||||
import glob
|
||||
import hashlib
|
||||
import importlib
|
||||
import inspect
|
||||
import logging
|
||||
@@ -29,6 +30,7 @@ __all__ = [
|
||||
"expand_and_validate_filepath",
|
||||
"get_last_library_path",
|
||||
"get_system_library_path",
|
||||
"hexdigest",
|
||||
"increment_filename_with_count",
|
||||
"increment_filename",
|
||||
"lineno",
|
||||
@@ -517,3 +519,10 @@ def get_latest_version() -> Tuple[Optional[str], str]:
|
||||
def pluralize(count, singular, plural):
|
||||
"""Return singular or plural based on count"""
|
||||
return singular if count == 1 else plural
|
||||
|
||||
|
||||
def hexdigest(strval: str) -> str:
|
||||
"""hexdigest of a string, using blake2b"""
|
||||
h = hashlib.blake2b(digest_size=20)
|
||||
h.update(bytes(strval, "utf-8"))
|
||||
return h.hexdigest()
|
||||
|
||||
@@ -19,7 +19,7 @@ pyobjc-framework-Metal>=7.3,<9.0
|
||||
pyobjc-framework-Photos>=7.3,<9.0
|
||||
pyobjc-framework-Quartz>=7.3,<9.0
|
||||
pyobjc-framework-Vision>=7.3,<9.0
|
||||
pytimeparse==1.1.8
|
||||
pytimeparse2==1.4.0
|
||||
PyYAML>=5.4.1,<6.0.0
|
||||
requests>=2.27.1,<3.0.0
|
||||
rich>=11.2.0,<13.0.0
|
||||
|
||||
2
setup.py
2
setup.py
@@ -95,7 +95,7 @@ setup(
|
||||
"pyobjc-framework-Photos>=7.3,<9.0",
|
||||
"pyobjc-framework-Quartz>=7.3,<9.0",
|
||||
"pyobjc-framework-Vision>=7.3,<9.0",
|
||||
"pytimeparse==1.1.8",
|
||||
"pytimeparse2==1.4.0",
|
||||
"requests>=2.27.1,<3.0.0",
|
||||
"rich>=11.2.0,<13.0.0",
|
||||
"rich_theme_manager>=0.11.0",
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
""" Test the command line interface (CLI) """
|
||||
|
||||
import datetime
|
||||
import glob
|
||||
import json
|
||||
@@ -7079,6 +7078,67 @@ def test_query_function():
|
||||
assert json_got[0]["original_filename"] == "DSC03584.dng"
|
||||
|
||||
|
||||
def test_query_added_after():
|
||||
"""test query --added-after"""
|
||||
|
||||
runner = CliRunner()
|
||||
cwd = os.getcwd()
|
||||
# pylint: disable=not-context-manager
|
||||
results = runner.invoke(
|
||||
query,
|
||||
[
|
||||
os.path.join(cwd, PHOTOS_DB_15_7),
|
||||
"--json",
|
||||
"--added-after",
|
||||
"2022-02-03",
|
||||
],
|
||||
)
|
||||
assert results.exit_code == 0
|
||||
json_got = json.loads(results.output)
|
||||
assert len(json_got) == 4
|
||||
|
||||
|
||||
def test_query_added_before():
|
||||
"""test query --added-before"""
|
||||
|
||||
runner = CliRunner()
|
||||
cwd = os.getcwd()
|
||||
# pylint: disable=not-context-manager
|
||||
results = runner.invoke(
|
||||
query,
|
||||
[
|
||||
os.path.join(cwd, PHOTOS_DB_15_7),
|
||||
"--json",
|
||||
"--added-before",
|
||||
"2019-07-28",
|
||||
],
|
||||
)
|
||||
assert results.exit_code == 0
|
||||
json_got = json.loads(results.output)
|
||||
assert len(json_got) == 7
|
||||
|
||||
|
||||
def test_query_added_in_last():
|
||||
"""test query --added-in-last"""
|
||||
|
||||
# Note: ideally, I'd test this with freezegun to verify the time deltas worked but
|
||||
# freezegun causes osxphotos tests to crash so we just test that the --added-in-last runs without error
|
||||
|
||||
runner = CliRunner()
|
||||
cwd = os.getcwd()
|
||||
# pylint: disable=not-context-manager
|
||||
results = runner.invoke(
|
||||
query,
|
||||
[
|
||||
os.path.join(cwd, PHOTOS_DB_15_7),
|
||||
"--json",
|
||||
"--added-in-last",
|
||||
"10 years",
|
||||
],
|
||||
)
|
||||
assert results.exit_code == 0
|
||||
|
||||
|
||||
def test_export_export_dir_template():
|
||||
"""Test {export_dir} template"""
|
||||
|
||||
@@ -7592,3 +7652,66 @@ def test_theme_list():
|
||||
result = runner.invoke(cli_main, ["theme", "--list"])
|
||||
assert result.exit_code == 0
|
||||
assert "Dark" in result.output
|
||||
|
||||
|
||||
def test_export_added_after():
|
||||
"""test export --added-after"""
|
||||
|
||||
runner = CliRunner()
|
||||
cwd = os.getcwd()
|
||||
with runner.isolated_filesystem():
|
||||
result = runner.invoke(
|
||||
export,
|
||||
[
|
||||
".",
|
||||
"--db",
|
||||
os.path.join(cwd, PHOTOS_DB_15_7),
|
||||
"--added-after",
|
||||
"2022-02-03",
|
||||
],
|
||||
)
|
||||
assert result.exit_code == 0
|
||||
assert "Exporting 4 photos" in result.output
|
||||
|
||||
|
||||
def test_export_added_before():
|
||||
"""test export --added-before"""
|
||||
|
||||
runner = CliRunner()
|
||||
cwd = os.getcwd()
|
||||
with runner.isolated_filesystem():
|
||||
result = runner.invoke(
|
||||
export,
|
||||
[
|
||||
".",
|
||||
"--db",
|
||||
os.path.join(cwd, PHOTOS_DB_15_7),
|
||||
"--added-before",
|
||||
"2019-07-28",
|
||||
],
|
||||
)
|
||||
assert result.exit_code == 0
|
||||
assert "Exporting 7 photos" in result.output
|
||||
|
||||
|
||||
def test_export_added_in_last():
|
||||
"""test export --added-in-last"""
|
||||
|
||||
# can't use freezegun as it causes osxphotos tests to crash so
|
||||
# just run export with --added-in-last and verify no errors
|
||||
|
||||
runner = CliRunner()
|
||||
cwd = os.getcwd()
|
||||
with runner.isolated_filesystem():
|
||||
result = runner.invoke(
|
||||
export,
|
||||
[
|
||||
".",
|
||||
"--db",
|
||||
os.path.join(cwd, PHOTOS_DB_15_7),
|
||||
"--added-in-last",
|
||||
"10 years",
|
||||
],
|
||||
)
|
||||
assert result.exit_code == 0
|
||||
assert "Exporting" in result.output
|
||||
|
||||
205
tests/test_cli_param_types.py
Normal file
205
tests/test_cli_param_types.py
Normal file
@@ -0,0 +1,205 @@
|
||||
""" Test custom click paramater types used by osxphotos CLI"""
|
||||
|
||||
import datetime
|
||||
from bitmath import MB
|
||||
|
||||
import pytest
|
||||
|
||||
from osxphotos.timezones import Timezone
|
||||
|
||||
from click.exceptions import BadParameter
|
||||
|
||||
from osxphotos.cli.param_types import (
|
||||
BitMathSize,
|
||||
DateOffset,
|
||||
DateTimeISO8601,
|
||||
ExportDBType,
|
||||
FunctionCall,
|
||||
TemplateString,
|
||||
TimeISO8601,
|
||||
TimeOffset,
|
||||
TimeString,
|
||||
UTCOffset,
|
||||
)
|
||||
|
||||
|
||||
def test_date_offset():
|
||||
"""Test DateOffset"""
|
||||
date_offset_data = {
|
||||
"1": datetime.timedelta(days=1),
|
||||
"1 day": datetime.timedelta(days=1),
|
||||
"+1 day": datetime.timedelta(days=1),
|
||||
"1 d": datetime.timedelta(days=1),
|
||||
"1d": datetime.timedelta(days=1),
|
||||
"+ 1": datetime.timedelta(days=1),
|
||||
"+1 day": datetime.timedelta(days=1),
|
||||
"+ 1": datetime.timedelta(days=1),
|
||||
"14:30": datetime.timedelta(minutes=14, seconds=30),
|
||||
"14:30:00": datetime.timedelta(hours=14, minutes=30, seconds=0),
|
||||
"1 week": datetime.timedelta(days=7),
|
||||
"2 wk": datetime.timedelta(days=14),
|
||||
"2 months": datetime.timedelta(days=60),
|
||||
"1 mos": datetime.timedelta(days=30),
|
||||
}
|
||||
for date_offset_str, date_offset_delta in date_offset_data.items():
|
||||
assert DateOffset().convert(date_offset_str, None, None) == date_offset_delta
|
||||
|
||||
|
||||
def test_date_offset_invalid_format():
|
||||
"""Test DateOffset with invalid format"""
|
||||
date_offset_data = [
|
||||
"1 foo",
|
||||
"1 day 14",
|
||||
"day",
|
||||
]
|
||||
for date_offset_str in date_offset_data:
|
||||
with pytest.raises(BadParameter):
|
||||
DateOffset().convert(date_offset_str, None, None)
|
||||
|
||||
|
||||
def test_time_offset():
|
||||
"""Test TimeOffset"""
|
||||
time_offset_data = {
|
||||
"1": datetime.timedelta(seconds=1),
|
||||
"1s": datetime.timedelta(seconds=1),
|
||||
"2 s": datetime.timedelta(seconds=2),
|
||||
"2 sec": datetime.timedelta(seconds=2),
|
||||
"3 sec": datetime.timedelta(seconds=3),
|
||||
"1m": datetime.timedelta(minutes=1),
|
||||
"1 min": datetime.timedelta(minutes=1),
|
||||
"1 day": datetime.timedelta(days=1),
|
||||
"14:30": datetime.timedelta(minutes=14, seconds=30),
|
||||
"14:30:00": datetime.timedelta(hours=14, minutes=30, seconds=0),
|
||||
}
|
||||
for time_offset_str, time_offset_delta in time_offset_data.items():
|
||||
assert TimeOffset().convert(time_offset_str, None, None) == time_offset_delta
|
||||
|
||||
|
||||
def test_time_offset_invalid_format():
|
||||
"""Test TimeOffset with invalid format"""
|
||||
time_offset_data = [
|
||||
"1 foo",
|
||||
"1 day 14",
|
||||
"1 sec 1",
|
||||
"sec",
|
||||
]
|
||||
for time_offset_str in time_offset_data:
|
||||
with pytest.raises(BadParameter):
|
||||
TimeOffset().convert(time_offset_str, None, None)
|
||||
|
||||
|
||||
def test_bitmath_size():
|
||||
"""Test BitMathSize"""
|
||||
bitmath_size_data = {
|
||||
"1048576": MB(1.048576),
|
||||
"1.048576MB": MB(1.048576),
|
||||
"1 MiB": MB(1.048576),
|
||||
}
|
||||
for bitmath_size_str, bitmath_size_int in bitmath_size_data.items():
|
||||
assert BitMathSize().convert(bitmath_size_str, None, None) == bitmath_size_int
|
||||
|
||||
|
||||
def test_bitmath_size_invalid_format():
|
||||
"""Test BitMathSize with invalid format"""
|
||||
bitmath_size_data = [
|
||||
"1 foo",
|
||||
"1 mehgabite",
|
||||
]
|
||||
for bitmath_size_str in bitmath_size_data:
|
||||
with pytest.raises(BadParameter):
|
||||
BitMathSize().convert(bitmath_size_str, None, None)
|
||||
|
||||
|
||||
def test_date_time_iso8601():
|
||||
"""Test DateTimeISO8601"""
|
||||
date_time_iso8601_data = {
|
||||
"2020-01-01T00:00:00": datetime.datetime(2020, 1, 1, 0, 0, 0),
|
||||
"2020-01-01T00:00:00.000": datetime.datetime(2020, 1, 1, 0, 0, 0),
|
||||
"2020-01-01": datetime.datetime(2020, 1, 1),
|
||||
}
|
||||
for date_time_iso8601_str, date_time_iso8601_dt in date_time_iso8601_data.items():
|
||||
assert (
|
||||
DateTimeISO8601().convert(date_time_iso8601_str, None, None)
|
||||
== date_time_iso8601_dt
|
||||
)
|
||||
|
||||
|
||||
def test_date_time_iso8601_invalid_format():
|
||||
"""Test DateTimeISO8601 with invalid format"""
|
||||
date_time_iso8601_data = [
|
||||
"20-01-01T00:00:00",
|
||||
"20-01-1",
|
||||
]
|
||||
for date_time_iso8601_str in date_time_iso8601_data:
|
||||
with pytest.raises(BadParameter):
|
||||
DateTimeISO8601().convert(date_time_iso8601_str, None, None)
|
||||
|
||||
|
||||
def test_time_iso8601():
|
||||
"""Test TimeISO8601"""
|
||||
time_iso8601_data = {
|
||||
"00:00:00": datetime.time(0, 0, 0),
|
||||
"00:00:00.000": datetime.time(0, 0, 0),
|
||||
}
|
||||
|
||||
for time_iso8601_str, time_iso8601_dt in time_iso8601_data.items():
|
||||
assert TimeISO8601().convert(time_iso8601_str, None, None) == time_iso8601_dt
|
||||
|
||||
|
||||
def test_time_iso8601_invalid_format():
|
||||
"""Test TimeISO8601 with invalid format"""
|
||||
date_time_iso8601_data = [
|
||||
"20-01-01T00:00:00",
|
||||
"20-01-1",
|
||||
]
|
||||
for date_time_iso8601_str in date_time_iso8601_data:
|
||||
with pytest.raises(BadParameter):
|
||||
TimeISO8601().convert(date_time_iso8601_str, None, None)
|
||||
|
||||
|
||||
def test_timestring():
|
||||
"""Test TimeString"""
|
||||
timestring_data = {
|
||||
"01:02:03": datetime.time(1, 2, 3),
|
||||
"01:02:03.000": datetime.time(1, 2, 3),
|
||||
"01:02:03.0000": datetime.time(1, 2, 3),
|
||||
"01:02": datetime.time(1, 2, 0),
|
||||
}
|
||||
for timestring_str, timestring_dt in timestring_data.items():
|
||||
assert TimeString().convert(timestring_str, None, None) == timestring_dt
|
||||
|
||||
|
||||
def test_timestring_invalid_format():
|
||||
"""Test TimeString with invalid format"""
|
||||
timestring_data = [
|
||||
"20-01-01T00:00:00",
|
||||
"20-01-1",
|
||||
]
|
||||
for timestring_str in timestring_data:
|
||||
with pytest.raises(BadParameter):
|
||||
TimeString().convert(timestring_str, None, None)
|
||||
|
||||
|
||||
def test_utcoffset():
|
||||
"""Test UTCOffset"""
|
||||
utcoffset_data = {
|
||||
"+00:00": Timezone(0),
|
||||
"-00:00": Timezone(-0),
|
||||
"+01:00": Timezone(3600),
|
||||
"-01:00": Timezone(-3600),
|
||||
"+01:30": Timezone(5400),
|
||||
"-01:30": Timezone(-5400),
|
||||
}
|
||||
for utcoffset_str, utcoffset_int in utcoffset_data.items():
|
||||
assert UTCOffset().convert(utcoffset_str, None, None) == utcoffset_int
|
||||
|
||||
|
||||
def test_utcoffset_invalid_format():
|
||||
"""Test UTCOffset with invalid format"""
|
||||
utcoffset_data = [
|
||||
"20-01-01T00:00:00",
|
||||
"20-01-1",
|
||||
]
|
||||
for utcoffset_str in utcoffset_data:
|
||||
with pytest.raises(BadParameter):
|
||||
UTCOffset().convert(utcoffset_str, None, None)
|
||||
@@ -81,7 +81,7 @@ def test_inspect(photoslib, suspend_capture, output_file):
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(
|
||||
timewarp,
|
||||
["--inspect", "--plain", "-o", output_file],
|
||||
["--inspect", "--plain", "--force", "-o", output_file],
|
||||
terminal_width=TERMINAL_WIDTH,
|
||||
)
|
||||
assert result.exit_code == 0
|
||||
@@ -101,6 +101,7 @@ def test_date(photoslib, suspend_capture):
|
||||
"--date",
|
||||
TEST_DATA["date"]["value"],
|
||||
"--plain",
|
||||
"--force",
|
||||
],
|
||||
terminal_width=TERMINAL_WIDTH,
|
||||
)
|
||||
@@ -122,13 +123,14 @@ def test_date_delta(photoslib, suspend_capture, input_value, expected, output_fi
|
||||
"--date-delta",
|
||||
input_value,
|
||||
"--plain",
|
||||
"--force",
|
||||
],
|
||||
terminal_width=TERMINAL_WIDTH,
|
||||
)
|
||||
assert result.exit_code == 0
|
||||
result = runner.invoke(
|
||||
timewarp,
|
||||
["--inspect", "--plain", "-o", output_file],
|
||||
["--inspect", "--plain", "--force", "-o", output_file],
|
||||
terminal_width=TERMINAL_WIDTH,
|
||||
)
|
||||
output_values = parse_inspect_output(output_file)
|
||||
@@ -148,6 +150,7 @@ def test_time(photoslib, suspend_capture, input_value, expected, output_file):
|
||||
"--time",
|
||||
input_value,
|
||||
"--plain",
|
||||
"--force",
|
||||
],
|
||||
terminal_width=TERMINAL_WIDTH,
|
||||
)
|
||||
@@ -156,7 +159,7 @@ def test_time(photoslib, suspend_capture, input_value, expected, output_file):
|
||||
# don't use photo.date as it will return local time instead of the time in the timezone
|
||||
result = runner.invoke(
|
||||
timewarp,
|
||||
["--inspect", "--plain", "-o", output_file],
|
||||
["--inspect", "--plain", "--force", "-o", output_file],
|
||||
terminal_width=TERMINAL_WIDTH,
|
||||
)
|
||||
output_values = parse_inspect_output(output_file)
|
||||
@@ -176,13 +179,14 @@ def test_time_delta(photoslib, suspend_capture, input_value, expected, output_fi
|
||||
"--time-delta",
|
||||
input_value,
|
||||
"--plain",
|
||||
"--force",
|
||||
],
|
||||
terminal_width=TERMINAL_WIDTH,
|
||||
)
|
||||
assert result.exit_code == 0
|
||||
result = runner.invoke(
|
||||
timewarp,
|
||||
["--inspect", "--plain", "-o", output_file],
|
||||
["--inspect", "--plain", "--force", "-o", output_file],
|
||||
terminal_width=TERMINAL_WIDTH,
|
||||
)
|
||||
output_values = parse_inspect_output(output_file)
|
||||
@@ -206,13 +210,14 @@ def test_time_zone(
|
||||
"--timezone",
|
||||
input_value,
|
||||
"--plain",
|
||||
"--force",
|
||||
],
|
||||
terminal_width=TERMINAL_WIDTH,
|
||||
)
|
||||
assert result.exit_code == 0
|
||||
result = runner.invoke(
|
||||
timewarp,
|
||||
["--inspect", "--plain", "-o", output_file],
|
||||
["--inspect", "--plain", "--force", "-o", output_file],
|
||||
terminal_width=TERMINAL_WIDTH,
|
||||
)
|
||||
output_values = parse_inspect_output(output_file)
|
||||
@@ -232,6 +237,7 @@ def test_compare_exif(photoslib, suspend_capture, expected, output_file):
|
||||
[
|
||||
"--compare-exif",
|
||||
"--plain",
|
||||
"--force",
|
||||
"-o",
|
||||
output_file,
|
||||
],
|
||||
@@ -258,6 +264,7 @@ def test_compare_exif_add_to_album(photoslib, suspend_capture, expected, album):
|
||||
"--add-to-album",
|
||||
album,
|
||||
"--plain",
|
||||
"--force",
|
||||
],
|
||||
terminal_width=TERMINAL_WIDTH,
|
||||
)
|
||||
@@ -282,7 +289,7 @@ def test_compare_exif_3(photoslib, suspend_capture, expected, output_file):
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(
|
||||
timewarp,
|
||||
["--compare-exif", "--plain", "-o", output_file],
|
||||
["--compare-exif", "--plain", "--force", "-o", output_file],
|
||||
terminal_width=TERMINAL_WIDTH,
|
||||
)
|
||||
assert result.exit_code == 0
|
||||
@@ -304,13 +311,14 @@ def test_match(photoslib, suspend_capture, input_value, expected, output_file):
|
||||
input_value,
|
||||
"--match-time",
|
||||
"--plain",
|
||||
"--force",
|
||||
],
|
||||
terminal_width=TERMINAL_WIDTH,
|
||||
)
|
||||
assert result.exit_code == 0
|
||||
result = runner.invoke(
|
||||
timewarp,
|
||||
["--inspect", "--plain", "-o", output_file],
|
||||
["--inspect", "--plain", "--force", "-o", output_file],
|
||||
terminal_width=TERMINAL_WIDTH,
|
||||
)
|
||||
output_values = parse_inspect_output(output_file)
|
||||
@@ -324,7 +332,9 @@ def test_push_exif_missing_file():
|
||||
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(
|
||||
timewarp, ["--push-exif", "--plain", "--verbose"], terminal_width=TERMINAL_WIDTH
|
||||
timewarp,
|
||||
["--push-exif", "--plain", "--force", "--verbose"],
|
||||
terminal_width=TERMINAL_WIDTH,
|
||||
)
|
||||
assert result.exit_code == 0
|
||||
assert "Skipping EXIF update for missing photo" in result.output
|
||||
@@ -361,6 +371,7 @@ def test_push_exif_1(
|
||||
time_delta_value,
|
||||
"--push-exif",
|
||||
"--plain",
|
||||
"--force",
|
||||
]
|
||||
if match:
|
||||
cli_args.append("--match-time")
|
||||
@@ -370,7 +381,7 @@ def test_push_exif_1(
|
||||
assert result.exit_code == 0
|
||||
result = runner.invoke(
|
||||
timewarp,
|
||||
["--inspect", "--plain", "-o", output_file],
|
||||
["--inspect", "--plain", "--force", "-o", output_file],
|
||||
terminal_width=TERMINAL_WIDTH,
|
||||
)
|
||||
output_values = parse_inspect_output(output_file)
|
||||
@@ -403,7 +414,7 @@ def test_push_exif_2(photoslib, suspend_capture, output_file):
|
||||
|
||||
result = runner.invoke(
|
||||
timewarp,
|
||||
["--compare-exif", "--plain", "-o", output_file],
|
||||
["--compare-exif", "--plain", "--force", "-o", output_file],
|
||||
terminal_width=TERMINAL_WIDTH,
|
||||
)
|
||||
output_values = parse_compare_exif(output_file)
|
||||
@@ -414,6 +425,7 @@ def test_push_exif_2(photoslib, suspend_capture, output_file):
|
||||
[
|
||||
"--push-exif",
|
||||
"--plain",
|
||||
"--force",
|
||||
"--verbose",
|
||||
],
|
||||
terminal_width=TERMINAL_WIDTH,
|
||||
@@ -422,7 +434,7 @@ def test_push_exif_2(photoslib, suspend_capture, output_file):
|
||||
|
||||
result = runner.invoke(
|
||||
timewarp,
|
||||
["--compare-exif", "--plain", "-o", output_file],
|
||||
["--compare-exif", "--plain", "--force", "-o", output_file],
|
||||
terminal_width=TERMINAL_WIDTH,
|
||||
)
|
||||
output_values = parse_compare_exif(output_file)
|
||||
@@ -442,14 +454,14 @@ def test_pull_exif_1(photoslib, suspend_capture, output_file):
|
||||
# update the photo so we know if the data is updated
|
||||
result = runner.invoke(
|
||||
timewarp,
|
||||
["-z", "-0400", "-D", "+1 day", "-m", "-V", "--plain"],
|
||||
["-z", "-0400", "-D", "+1 day", "-m", "-V", "--plain", "--force"],
|
||||
terminal_width=TERMINAL_WIDTH,
|
||||
)
|
||||
assert result.exit_code == 0
|
||||
|
||||
result = runner.invoke(
|
||||
timewarp,
|
||||
["--compare-exif", "--plain", "-o", output_file],
|
||||
["--compare-exif", "--plain", "--force", "-o", output_file],
|
||||
terminal_width=TERMINAL_WIDTH,
|
||||
)
|
||||
output_values = parse_compare_exif(output_file)
|
||||
@@ -460,6 +472,7 @@ def test_pull_exif_1(photoslib, suspend_capture, output_file):
|
||||
[
|
||||
"--pull-exif",
|
||||
"--plain",
|
||||
"--force",
|
||||
"--verbose",
|
||||
],
|
||||
terminal_width=TERMINAL_WIDTH,
|
||||
@@ -468,7 +481,7 @@ def test_pull_exif_1(photoslib, suspend_capture, output_file):
|
||||
|
||||
result = runner.invoke(
|
||||
timewarp,
|
||||
["--compare-exif", "--plain", "-o", output_file],
|
||||
["--compare-exif", "--plain", "--force", "-o", output_file],
|
||||
terminal_width=TERMINAL_WIDTH,
|
||||
)
|
||||
output_values = parse_compare_exif(output_file)
|
||||
@@ -493,7 +506,7 @@ def test_pull_exif_no_time(photoslib, suspend_capture, output_file):
|
||||
|
||||
result = runner.invoke(
|
||||
timewarp,
|
||||
["--compare-exif", "--plain", "-o", output_file],
|
||||
["--compare-exif", "--plain", "--force", "-o", output_file],
|
||||
terminal_width=TERMINAL_WIDTH,
|
||||
)
|
||||
output_values = parse_compare_exif(output_file)
|
||||
@@ -504,6 +517,7 @@ def test_pull_exif_no_time(photoslib, suspend_capture, output_file):
|
||||
[
|
||||
"--pull-exif",
|
||||
"--plain",
|
||||
"--force",
|
||||
"--verbose",
|
||||
],
|
||||
terminal_width=TERMINAL_WIDTH,
|
||||
@@ -512,7 +526,7 @@ def test_pull_exif_no_time(photoslib, suspend_capture, output_file):
|
||||
|
||||
result = runner.invoke(
|
||||
timewarp,
|
||||
["--compare-exif", "--plain", "-o", output_file],
|
||||
["--compare-exif", "--plain", "--force", "-o", output_file],
|
||||
terminal_width=TERMINAL_WIDTH,
|
||||
)
|
||||
output_values = parse_compare_exif(output_file)
|
||||
@@ -537,7 +551,7 @@ def test_pull_exif_no_offset(photoslib, suspend_capture, output_file):
|
||||
|
||||
result = runner.invoke(
|
||||
timewarp,
|
||||
["--compare-exif", "--plain", "-o", output_file],
|
||||
["--compare-exif", "--plain", "--force", "-o", output_file],
|
||||
terminal_width=TERMINAL_WIDTH,
|
||||
)
|
||||
output_values = parse_compare_exif(output_file)
|
||||
@@ -548,6 +562,7 @@ def test_pull_exif_no_offset(photoslib, suspend_capture, output_file):
|
||||
[
|
||||
"--pull-exif",
|
||||
"--plain",
|
||||
"--force",
|
||||
"--verbose",
|
||||
],
|
||||
terminal_width=TERMINAL_WIDTH,
|
||||
@@ -556,7 +571,7 @@ def test_pull_exif_no_offset(photoslib, suspend_capture, output_file):
|
||||
|
||||
result = runner.invoke(
|
||||
timewarp,
|
||||
["--compare-exif", "--plain", "-o", output_file],
|
||||
["--compare-exif", "--plain", "--force", "-o", output_file],
|
||||
terminal_width=TERMINAL_WIDTH,
|
||||
)
|
||||
output_values = parse_compare_exif(output_file)
|
||||
@@ -583,7 +598,7 @@ def test_pull_exif_no_data(photoslib, suspend_capture, output_file):
|
||||
|
||||
result = runner.invoke(
|
||||
timewarp,
|
||||
["--compare-exif", "--plain", "-o", output_file],
|
||||
["--compare-exif", "--plain", "--force", "-o", output_file],
|
||||
terminal_width=TERMINAL_WIDTH,
|
||||
)
|
||||
output_values = parse_compare_exif(output_file)
|
||||
@@ -594,6 +609,7 @@ def test_pull_exif_no_data(photoslib, suspend_capture, output_file):
|
||||
[
|
||||
"--pull-exif",
|
||||
"--plain",
|
||||
"--force",
|
||||
"--verbose",
|
||||
],
|
||||
terminal_width=TERMINAL_WIDTH,
|
||||
@@ -603,7 +619,7 @@ def test_pull_exif_no_data(photoslib, suspend_capture, output_file):
|
||||
|
||||
result = runner.invoke(
|
||||
timewarp,
|
||||
["--compare-exif", "--plain", "-o", output_file],
|
||||
["--compare-exif", "--plain", "--force", "-o", output_file],
|
||||
terminal_width=TERMINAL_WIDTH,
|
||||
)
|
||||
output_values = parse_compare_exif(output_file)
|
||||
@@ -622,7 +638,7 @@ def test_pull_exif_no_data_use_file_time(photoslib, suspend_capture, output_file
|
||||
|
||||
result = runner.invoke(
|
||||
timewarp,
|
||||
["--compare-exif", "--plain", "-o", output_file],
|
||||
["--compare-exif", "--plain", "--force", "-o", output_file],
|
||||
terminal_width=TERMINAL_WIDTH,
|
||||
)
|
||||
output_values = parse_compare_exif(output_file)
|
||||
@@ -633,6 +649,7 @@ def test_pull_exif_no_data_use_file_time(photoslib, suspend_capture, output_file
|
||||
[
|
||||
"--pull-exif",
|
||||
"--plain",
|
||||
"--force",
|
||||
"--verbose",
|
||||
"--use-file-time",
|
||||
],
|
||||
@@ -643,7 +660,7 @@ def test_pull_exif_no_data_use_file_time(photoslib, suspend_capture, output_file
|
||||
|
||||
result = runner.invoke(
|
||||
timewarp,
|
||||
["--compare-exif", "--plain", "-o", output_file],
|
||||
["--compare-exif", "--plain", "--force", "-o", output_file],
|
||||
terminal_width=TERMINAL_WIDTH,
|
||||
)
|
||||
output_values = parse_compare_exif(output_file)
|
||||
@@ -668,6 +685,7 @@ def test_video_compare_exif(photoslib, suspend_capture, expected, output_file):
|
||||
[
|
||||
"--compare-exif",
|
||||
"--plain",
|
||||
"--force",
|
||||
"-o",
|
||||
output_file,
|
||||
],
|
||||
@@ -695,6 +713,7 @@ def test_video_date_delta(
|
||||
"--date-delta",
|
||||
input_value,
|
||||
"--plain",
|
||||
"--force",
|
||||
],
|
||||
terminal_width=TERMINAL_WIDTH,
|
||||
)
|
||||
@@ -702,7 +721,7 @@ def test_video_date_delta(
|
||||
|
||||
result = runner.invoke(
|
||||
timewarp,
|
||||
["--inspect", "--plain", "-o", output_file],
|
||||
["--inspect", "--plain", "--force", "-o", output_file],
|
||||
terminal_width=TERMINAL_WIDTH,
|
||||
)
|
||||
output_values = parse_inspect_output(output_file)
|
||||
@@ -726,13 +745,14 @@ def test_video_time_delta(
|
||||
"--time-delta",
|
||||
input_value,
|
||||
"--plain",
|
||||
"--force",
|
||||
],
|
||||
terminal_width=TERMINAL_WIDTH,
|
||||
)
|
||||
assert result.exit_code == 0
|
||||
result = runner.invoke(
|
||||
timewarp,
|
||||
["--inspect", "--plain", "-o", output_file],
|
||||
["--inspect", "--plain", "--force", "-o", output_file],
|
||||
terminal_width=TERMINAL_WIDTH,
|
||||
)
|
||||
output_values = parse_inspect_output(output_file)
|
||||
@@ -752,6 +772,7 @@ def test_video_date(photoslib, suspend_capture, input_value, expected, output_fi
|
||||
"--date",
|
||||
input_value,
|
||||
"--plain",
|
||||
"--force",
|
||||
],
|
||||
terminal_width=TERMINAL_WIDTH,
|
||||
)
|
||||
@@ -760,7 +781,7 @@ def test_video_date(photoslib, suspend_capture, input_value, expected, output_fi
|
||||
# don't use photo.date as it will return local time instead of the time in the timezone
|
||||
result = runner.invoke(
|
||||
timewarp,
|
||||
["--inspect", "--plain", "-o", output_file],
|
||||
["--inspect", "--plain", "--force", "-o", output_file],
|
||||
terminal_width=TERMINAL_WIDTH,
|
||||
)
|
||||
output_values = parse_inspect_output(output_file)
|
||||
@@ -780,6 +801,7 @@ def test_video_time(photoslib, suspend_capture, input_value, expected, output_fi
|
||||
"--time",
|
||||
input_value,
|
||||
"--plain",
|
||||
"--force",
|
||||
],
|
||||
terminal_width=TERMINAL_WIDTH,
|
||||
)
|
||||
@@ -788,7 +810,7 @@ def test_video_time(photoslib, suspend_capture, input_value, expected, output_fi
|
||||
# don't use photo.date as it will return local time instead of the time in the timezone
|
||||
result = runner.invoke(
|
||||
timewarp,
|
||||
["--inspect", "--plain", "-o", output_file],
|
||||
["--inspect", "--plain", "--force", "-o", output_file],
|
||||
terminal_width=TERMINAL_WIDTH,
|
||||
)
|
||||
output_values = parse_inspect_output(output_file)
|
||||
@@ -812,13 +834,14 @@ def test_video_time_zone(
|
||||
"--timezone",
|
||||
input_value,
|
||||
"--plain",
|
||||
"--force",
|
||||
],
|
||||
terminal_width=TERMINAL_WIDTH,
|
||||
)
|
||||
assert result.exit_code == 0
|
||||
result = runner.invoke(
|
||||
timewarp,
|
||||
["--inspect", "--plain", "-o", output_file],
|
||||
["--inspect", "--plain", "--force", "-o", output_file],
|
||||
terminal_width=TERMINAL_WIDTH,
|
||||
)
|
||||
output_values = parse_inspect_output(output_file)
|
||||
@@ -840,13 +863,14 @@ def test_video_match(photoslib, suspend_capture, input_value, expected, output_f
|
||||
input_value,
|
||||
"--match-time",
|
||||
"--plain",
|
||||
"--force",
|
||||
],
|
||||
terminal_width=TERMINAL_WIDTH,
|
||||
)
|
||||
assert result.exit_code == 0
|
||||
result = runner.invoke(
|
||||
timewarp,
|
||||
["--inspect", "--plain", "-o", output_file],
|
||||
["--inspect", "--plain", "--force", "-o", output_file],
|
||||
terminal_width=TERMINAL_WIDTH,
|
||||
)
|
||||
output_values = parse_inspect_output(output_file)
|
||||
@@ -865,7 +889,7 @@ def test_video_push_exif(photoslib, suspend_capture, output_file):
|
||||
|
||||
result = runner.invoke(
|
||||
timewarp,
|
||||
["--compare-exif", "--plain", "-o", output_file],
|
||||
["--compare-exif", "--plain", "--force", "-o", output_file],
|
||||
terminal_width=TERMINAL_WIDTH,
|
||||
)
|
||||
output_values = parse_compare_exif(output_file)
|
||||
@@ -876,6 +900,7 @@ def test_video_push_exif(photoslib, suspend_capture, output_file):
|
||||
[
|
||||
"--push-exif",
|
||||
"--plain",
|
||||
"--force",
|
||||
"--verbose",
|
||||
],
|
||||
terminal_width=TERMINAL_WIDTH,
|
||||
@@ -884,7 +909,7 @@ def test_video_push_exif(photoslib, suspend_capture, output_file):
|
||||
|
||||
result = runner.invoke(
|
||||
timewarp,
|
||||
["--compare-exif", "--plain", "-o", output_file],
|
||||
["--compare-exif", "--plain", "--force", "-o", output_file],
|
||||
terminal_width=TERMINAL_WIDTH,
|
||||
)
|
||||
output_values = parse_compare_exif(output_file)
|
||||
@@ -904,14 +929,25 @@ def test_video_pull_exif(photoslib, suspend_capture, output_file):
|
||||
# update the photo so we know if the data is updated
|
||||
result = runner.invoke(
|
||||
timewarp,
|
||||
["-z", "-0500", "-D", "+1 day", "-T", "-10 hours", "-m", "-V", "--plain"],
|
||||
[
|
||||
"-z",
|
||||
"-0500",
|
||||
"-D",
|
||||
"+1 day",
|
||||
"-T",
|
||||
"-10 hours",
|
||||
"-m",
|
||||
"-V",
|
||||
"--plain",
|
||||
"--force",
|
||||
],
|
||||
terminal_width=TERMINAL_WIDTH,
|
||||
)
|
||||
assert result.exit_code == 0
|
||||
|
||||
result = runner.invoke(
|
||||
timewarp,
|
||||
["--compare-exif", "--plain", "-o", output_file],
|
||||
["--compare-exif", "--plain", "--force", "-o", output_file],
|
||||
terminal_width=TERMINAL_WIDTH,
|
||||
)
|
||||
output_values = parse_compare_exif(output_file)
|
||||
@@ -922,6 +958,7 @@ def test_video_pull_exif(photoslib, suspend_capture, output_file):
|
||||
[
|
||||
"--pull-exif",
|
||||
"--plain",
|
||||
"--force",
|
||||
"--verbose",
|
||||
],
|
||||
terminal_width=TERMINAL_WIDTH,
|
||||
@@ -930,7 +967,7 @@ def test_video_pull_exif(photoslib, suspend_capture, output_file):
|
||||
|
||||
result = runner.invoke(
|
||||
timewarp,
|
||||
["--compare-exif", "--plain", "-o", output_file],
|
||||
["--compare-exif", "--plain", "--force", "-o", output_file],
|
||||
terminal_width=TERMINAL_WIDTH,
|
||||
)
|
||||
output_values = parse_compare_exif(output_file)
|
||||
@@ -956,13 +993,14 @@ def test_function(photoslib, suspend_capture, output_file):
|
||||
[
|
||||
"--function",
|
||||
"tests/timewarp_function_example.py::get_date_time_timezone",
|
||||
"--force",
|
||||
],
|
||||
terminal_width=TERMINAL_WIDTH,
|
||||
)
|
||||
assert result.exit_code == 0
|
||||
result = runner.invoke(
|
||||
timewarp,
|
||||
["--inspect", "--plain", "-o", output_file],
|
||||
["--inspect", "--plain", "--force", "-o", output_file],
|
||||
terminal_width=TERMINAL_WIDTH,
|
||||
)
|
||||
output_values = parse_inspect_output(output_file)
|
||||
|
||||
Reference in New Issue
Block a user