Compare commits
23 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9bc5890589 | ||
|
|
e9bbfeca52 | ||
|
|
f42bee84c0 | ||
|
|
ac67ef2384 | ||
|
|
1ae4ec4851 | ||
|
|
6070616717 | ||
|
|
70d3247e8c | ||
|
|
25f35699d8 | ||
|
|
d07aab58d1 | ||
|
|
dc4d322dab | ||
|
|
8a3dc9b393 | ||
|
|
5e3cd66a4b | ||
|
|
e4b6c0f1e0 | ||
|
|
ad13565dfd | ||
|
|
bd9a14a6f3 | ||
|
|
f602af8485 | ||
|
|
2d29b79102 | ||
|
|
a7ed7dde54 | ||
|
|
c518fa5394 | ||
|
|
fa80ea3772 | ||
|
|
b8b4c15784 | ||
|
|
ee6e4602e4 | ||
|
|
3d3e1ab78a |
2204
API_README.md
Normal file
2204
API_README.md
Normal file
File diff suppressed because it is too large
Load Diff
44
CHANGELOG.md
44
CHANGELOG.md
@@ -4,6 +4,50 @@ All notable changes to this project will be documented in this file. Dates are d
|
||||
|
||||
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
||||
|
||||
#### [v0.48.1](https://github.com/RhetTbull/osxphotos/compare/v0.48.0...v0.48.1)
|
||||
|
||||
> 1 May 2022
|
||||
|
||||
- Feature timewarp function [`#678`](https://github.com/RhetTbull/osxphotos/pull/678)
|
||||
- Updated docs [`6070616`](https://github.com/RhetTbull/osxphotos/commit/60706167173f719d70e21193acef89f6252767e6)
|
||||
|
||||
#### [v0.48.0](https://github.com/RhetTbull/osxphotos/compare/v0.47.13...v0.48.0)
|
||||
|
||||
> 1 May 2022
|
||||
|
||||
- Feature timewarp [`#675`](https://github.com/RhetTbull/osxphotos/pull/675)
|
||||
- Version bump [`d07aab5`](https://github.com/RhetTbull/osxphotos/commit/d07aab58d1b0ef8e8769740db089235bbc938a4e)
|
||||
- Updated dependencies for rich_theme_manager [`8a3dc9b`](https://github.com/RhetTbull/osxphotos/commit/8a3dc9b3938f2363baba6dbf1f832ee55d57eb28)
|
||||
|
||||
#### [v0.47.13](https://github.com/RhetTbull/osxphotos/compare/v0.47.12...v0.47.13)
|
||||
|
||||
> 24 April 2022
|
||||
|
||||
- Updated docs to use zipfile [`bd9a14a`](https://github.com/RhetTbull/osxphotos/commit/bd9a14a6f30042044345b91c5c3d5176ac6bc4ad)
|
||||
- Added retry to export_db for #674 [`e4b6c0f`](https://github.com/RhetTbull/osxphotos/commit/e4b6c0f1e00123064575e39183cb5a209afee49d)
|
||||
- Updated license [`ad13565`](https://github.com/RhetTbull/osxphotos/commit/ad13565dfded64fdf1dd72a001609d2522b64737)
|
||||
|
||||
#### [v0.47.12](https://github.com/RhetTbull/osxphotos/compare/v0.47.11...v0.47.12)
|
||||
|
||||
> 23 April 2022
|
||||
|
||||
- Updated version [`a7ed7dd`](https://github.com/RhetTbull/osxphotos/commit/a7ed7dde54a10e7d277d1253f6c75e721aaacf83)
|
||||
|
||||
#### [v0.47.11](https://github.com/RhetTbull/osxphotos/compare/v0.47.10...v0.47.11)
|
||||
|
||||
> 23 April 2022
|
||||
|
||||
- Added version command [`#672`](https://github.com/RhetTbull/osxphotos/pull/672)
|
||||
- Added API_README [`ee6e460`](https://github.com/RhetTbull/osxphotos/commit/ee6e4602e4506fce63a4a207112c1224163eef8d)
|
||||
- Updated docs build to use cog [`b8b4c15`](https://github.com/RhetTbull/osxphotos/commit/b8b4c15784b611ac170ebfc0ddff68f78c82f5d1)
|
||||
- Updated docs with developer notes [`fa80ea3`](https://github.com/RhetTbull/osxphotos/commit/fa80ea3772fed00afe4cab0493e7d02c39291358)
|
||||
|
||||
#### [v0.47.10](https://github.com/RhetTbull/osxphotos/compare/v0.47.9...v0.47.10)
|
||||
|
||||
> 22 April 2022
|
||||
|
||||
- Updated docs [`b1aa923`](https://github.com/RhetTbull/osxphotos/commit/b1aa9238d38a90afa3cb9d2f5f95cf8b1f344690)
|
||||
|
||||
#### [v0.47.9](https://github.com/RhetTbull/osxphotos/compare/v0.47.8...v0.47.9)
|
||||
|
||||
> 20 April 2022
|
||||
|
||||
@@ -95,6 +95,7 @@ Alternatively, you can also run the command line utility like this: ``python3 -m
|
||||
-v, --version Show the version and exit.
|
||||
-h, --help Show this message and exit.
|
||||
|
||||
|
||||
Commands:
|
||||
about Print information about osxphotos including license.
|
||||
albums Print out albums found in the Photos library.
|
||||
@@ -115,9 +116,11 @@ Alternatively, you can also run the command line utility like this: ``python3 -m
|
||||
run Run a python file using same environment as osxphotos
|
||||
snap Create snapshot of Photos database to use with diff command
|
||||
theme Manage osxphotos color themes.
|
||||
timewarp Adjust date/time/timezone of photos in Apple Photos.
|
||||
tutorial Display osxphotos tutorial.
|
||||
uninstall Uninstall Python packages from the osxphotos environment
|
||||
uuid Print out unique IDs (UUID) of photos selected in Photos
|
||||
version Check for new version of osxphotos.
|
||||
|
||||
To get help on a specific command, use ``osxphotos help <command_name>``
|
||||
|
||||
|
||||
21
build.sh
21
build.sh
@@ -3,9 +3,19 @@
|
||||
# script to help build osxphotos release
|
||||
# this is unique to my own dev setup
|
||||
|
||||
rm -rf dist; rm -rf build
|
||||
echo "Cleaning old build and dist directories"
|
||||
rm -rf dist
|
||||
rm -rf build
|
||||
|
||||
echo "Updated phototemplate.md"
|
||||
cog -d -o osxphotos/phototemplate.md osxphotos/phototemplate.cog.md
|
||||
|
||||
echo "Updating README.md"
|
||||
python3 utils/update_readme.py
|
||||
|
||||
echo "Updating API_README.md"
|
||||
cog -r API_README.md
|
||||
|
||||
# stage and convert markdown to rst
|
||||
echo "Copying osxphotos/tutorial.md to docsrc/source/tutorial.md"
|
||||
cp osxphotos/tutorial.md docsrc/source/tutorial.md
|
||||
@@ -20,10 +30,17 @@ m2r2 docsrc/source/template_help.md
|
||||
rm docsrc/source/template_help.md
|
||||
|
||||
# build docs
|
||||
(cd docsrc && make github && make docs && make pdf)
|
||||
echo "Building docs"
|
||||
(cd docsrc && make github && make pdf)
|
||||
|
||||
# copy docs to osxphotos/docs/docs.zip for use with `osxphotos docs` command
|
||||
echo "Zipping docs to osxphotos/docs/docs.zip"
|
||||
zip -r osxphotos/docs/docs.zip docs/*
|
||||
|
||||
# build the package
|
||||
echo "Building package"
|
||||
python3 -m build
|
||||
|
||||
# build CLI executable
|
||||
echo "Building CLI executable"
|
||||
./make_cli_exe.sh
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
build
|
||||
cogapp>=3.3.0,<4.0.0
|
||||
furo
|
||||
m2r2
|
||||
pdbpp
|
||||
|
||||
@@ -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: 93e80185682565b83f06940002a2e690
|
||||
config: 80f83a536e4014ef4d71db9e7d4e82e8
|
||||
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.47.10 documentation</title>
|
||||
<title>Overview: module code - osxphotos 0.48.2 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="../_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="../_static/styles/furo.css?digest=68f4518137b9aefe99b631505a2064c3c42c9852" />
|
||||
<link rel="stylesheet" type="text/css" href="../_static/copybutton.css" />
|
||||
@@ -123,7 +123,7 @@
|
||||
</label>
|
||||
</div>
|
||||
<div class="header-center">
|
||||
<a href="../index.html"><div class="brand">osxphotos 0.47.10 documentation</div></a>
|
||||
<a href="../index.html"><div class="brand">osxphotos 0.48.2 documentation</div></a>
|
||||
</div>
|
||||
<div class="header-right">
|
||||
<div class="theme-toggle-container theme-toggle-header">
|
||||
@@ -146,7 +146,7 @@
|
||||
<div class="sidebar-sticky"><a class="sidebar-brand" href="../index.html">
|
||||
|
||||
|
||||
<span class="sidebar-brand-text">osxphotos 0.47.10 documentation</span>
|
||||
<span class="sidebar-brand-text">osxphotos 0.48.2 documentation</span>
|
||||
|
||||
</a><form class="sidebar-search-container" method="get" action="../search.html" role="search">
|
||||
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
|
||||
@@ -155,12 +155,12 @@
|
||||
</form>
|
||||
<div id="searchbox"></div><div class="sidebar-scroll"><div class="sidebar-tree">
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../overview.html">osxphotos</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../tutorial.html">osxphotos Tutorial</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../cli.html">osxphotos Command Line Interface (CLI)</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../template_help.html">osxphotos Template System</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../package_overview.html">Example uses of the python package</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../reference.html">osxphotos python API</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../overview.html">OSXPhotos</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../tutorial.html">OSXPhotos Tutorial</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../cli.html">OSXPhotos Command Line Interface (CLI)</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../template_help.html">OSXPhotos Template System</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../package_overview.html">OSXPhotos Python Package Overview</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../reference.html">OSXPhotos python API</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -1,54 +1,217 @@
|
||||
<!doctype html>
|
||||
<html class="no-js">
|
||||
<head><meta charset="utf-8"/>
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1"/>
|
||||
<meta name="color-scheme" content="light dark"><link rel="index" title="Index" href="../../genindex.html" /><link rel="search" title="Search" href="../../search.html" />
|
||||
|
||||
<!DOCTYPE html>
|
||||
<meta name="generator" content="sphinx-4.4.0, furo 2022.04.07"/>
|
||||
<title>osxphotos._constants - osxphotos 0.48.1 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="../../_static/styles/furo.css?digest=68f4518137b9aefe99b631505a2064c3c42c9852" />
|
||||
<link rel="stylesheet" type="text/css" href="../../_static/copybutton.css" />
|
||||
<link rel="stylesheet" type="text/css" href="../../_static/styles/furo-extensions.css?digest=30d1aed668e5c3a91c3e3bf6a60b675221979f0e" />
|
||||
|
||||
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>osxphotos._constants — osxphotos 0.47.9 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="../../_static/alabaster.css" />
|
||||
<script data-url_root="../../" id="documentation_options" src="../../_static/documentation_options.js"></script>
|
||||
<script src="../../_static/jquery.js"></script>
|
||||
<script src="../../_static/underscore.js"></script>
|
||||
<script src="../../_static/doctools.js"></script>
|
||||
<link rel="index" title="Index" href="../../genindex.html" />
|
||||
<link rel="search" title="Search" href="../../search.html" />
|
||||
|
||||
<link rel="stylesheet" href="../../_static/custom.css" type="text/css" />
|
||||
|
||||
<style>
|
||||
body {
|
||||
--color-code-background: #f8f8f8;
|
||||
--color-code-foreground: black;
|
||||
|
||||
}
|
||||
@media not print {
|
||||
body[data-theme="dark"] {
|
||||
--color-code-background: #202020;
|
||||
--color-code-foreground: #d0d0d0;
|
||||
|
||||
}
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body:not([data-theme="light"]) {
|
||||
--color-code-background: #202020;
|
||||
--color-code-foreground: #d0d0d0;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</style></head>
|
||||
<body>
|
||||
|
||||
<script>
|
||||
document.body.dataset.theme = localStorage.getItem("theme") || "auto";
|
||||
</script>
|
||||
|
||||
|
||||
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
|
||||
<symbol id="svg-toc" viewBox="0 0 24 24">
|
||||
<title>Contents</title>
|
||||
<svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 1024 1024">
|
||||
<path d="M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM115.4 518.9L271.7 642c5.8 4.6 14.4.5 14.4-6.9V388.9c0-7.4-8.5-11.5-14.4-6.9L115.4 505.1a8.74 8.74 0 0 0 0 13.8z"/>
|
||||
</svg>
|
||||
</symbol>
|
||||
<symbol id="svg-menu" viewBox="0 0 24 24">
|
||||
<title>Menu</title>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather-menu">
|
||||
<line x1="3" y1="12" x2="21" y2="12"></line>
|
||||
<line x1="3" y1="6" x2="21" y2="6"></line>
|
||||
<line x1="3" y1="18" x2="21" y2="18"></line>
|
||||
</svg>
|
||||
</symbol>
|
||||
<symbol id="svg-arrow-right" viewBox="0 0 24 24">
|
||||
<title>Expand</title>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather-chevron-right">
|
||||
<polyline points="9 18 15 12 9 6"></polyline>
|
||||
</svg>
|
||||
</symbol>
|
||||
<symbol id="svg-sun" viewBox="0 0 24 24">
|
||||
<title>Light mode</title>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="feather-sun">
|
||||
<circle cx="12" cy="12" r="5"></circle>
|
||||
<line x1="12" y1="1" x2="12" y2="3"></line>
|
||||
<line x1="12" y1="21" x2="12" y2="23"></line>
|
||||
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
|
||||
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
|
||||
<line x1="1" y1="12" x2="3" y2="12"></line>
|
||||
<line x1="21" y1="12" x2="23" y2="12"></line>
|
||||
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
|
||||
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
|
||||
</svg>
|
||||
</symbol>
|
||||
<symbol id="svg-moon" viewBox="0 0 24 24">
|
||||
<title>Dark mode</title>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="icon-tabler-moon">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M12 3c.132 0 .263 0 .393 0a7.5 7.5 0 0 0 7.92 12.446a9 9 0 1 1 -8.313 -12.454z" />
|
||||
</svg>
|
||||
</symbol>
|
||||
<symbol id="svg-sun-half" viewBox="0 0 24 24">
|
||||
<title>Auto light/dark mode</title>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="icon-tabler-shadow">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"/>
|
||||
<circle cx="12" cy="12" r="9" />
|
||||
<path d="M13 12h5" />
|
||||
<path d="M13 15h4" />
|
||||
<path d="M13 18h1" />
|
||||
<path d="M13 9h4" />
|
||||
<path d="M13 6h1" />
|
||||
</svg>
|
||||
</symbol>
|
||||
</svg>
|
||||
|
||||
<input type="checkbox" class="sidebar-toggle" name="__navigation" id="__navigation">
|
||||
<input type="checkbox" class="sidebar-toggle" name="__toc" id="__toc">
|
||||
<label class="overlay sidebar-overlay" for="__navigation">
|
||||
<div class="visually-hidden">Hide navigation sidebar</div>
|
||||
</label>
|
||||
<label class="overlay toc-overlay" for="__toc">
|
||||
<div class="visually-hidden">Hide table of contents sidebar</div>
|
||||
</label>
|
||||
|
||||
|
||||
|
||||
<div class="page">
|
||||
<header class="mobile-header">
|
||||
<div class="header-left">
|
||||
<label class="nav-overlay-icon" for="__navigation">
|
||||
<div class="visually-hidden">Toggle site navigation sidebar</div>
|
||||
<i class="icon"><svg><use href="#svg-menu"></use></svg></i>
|
||||
</label>
|
||||
</div>
|
||||
<div class="header-center">
|
||||
<a href="../../index.html"><div class="brand">osxphotos 0.48.1 documentation</div></a>
|
||||
</div>
|
||||
<div class="header-right">
|
||||
<div class="theme-toggle-container theme-toggle-header">
|
||||
<button class="theme-toggle">
|
||||
<div class="visually-hidden">Toggle Light / Dark / Auto color theme</div>
|
||||
<svg class="theme-icon-when-auto"><use href="#svg-sun-half"></use></svg>
|
||||
<svg class="theme-icon-when-dark"><use href="#svg-moon"></use></svg>
|
||||
<svg class="theme-icon-when-light"><use href="#svg-sun"></use></svg>
|
||||
</button>
|
||||
</div>
|
||||
<label class="toc-overlay-icon toc-header-icon no-toc" for="__toc">
|
||||
<div class="visually-hidden">Toggle table of contents sidebar</div>
|
||||
<i class="icon"><svg><use href="#svg-toc"></use></svg></i>
|
||||
</label>
|
||||
</div>
|
||||
</header>
|
||||
<aside class="sidebar-drawer">
|
||||
<div class="sidebar-container">
|
||||
|
||||
<div class="sidebar-sticky"><a class="sidebar-brand" href="../../index.html">
|
||||
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
|
||||
|
||||
</head><body>
|
||||
<span class="sidebar-brand-text">osxphotos 0.48.1 documentation</span>
|
||||
|
||||
</a><form class="sidebar-search-container" method="get" action="../../search.html" role="search">
|
||||
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
|
||||
<input type="hidden" name="check_keywords" value="yes">
|
||||
<input type="hidden" name="area" value="default">
|
||||
</form>
|
||||
<div id="searchbox"></div><div class="sidebar-scroll"><div class="sidebar-tree">
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../overview.html">OSXPhotos</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../tutorial.html">OSXPhotos Tutorial</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../cli.html">OSXPhotos Command Line Interface (CLI)</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../template_help.html">OSXPhotos Template System</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../package_overview.html">OSXPhotos Python Package Overview</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../reference.html">OSXPhotos python API</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="document">
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="body" role="main">
|
||||
|
||||
<h1>Source code for osxphotos._constants</h1><div class="highlight"><pre>
|
||||
<span></span><span class="sd">"""</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</aside>
|
||||
<div class="main">
|
||||
<div class="content">
|
||||
<div class="article-container">
|
||||
<a href="#" class="back-to-top muted-link">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8v12z"></path>
|
||||
</svg>
|
||||
<span>Back to top</span>
|
||||
</a>
|
||||
<div class="content-icon-container"><div class="theme-toggle-container theme-toggle-content">
|
||||
<button class="theme-toggle">
|
||||
<div class="visually-hidden">Toggle Light / Dark / Auto color theme</div>
|
||||
<svg class="theme-icon-when-auto"><use href="#svg-sun-half"></use></svg>
|
||||
<svg class="theme-icon-when-dark"><use href="#svg-moon"></use></svg>
|
||||
<svg class="theme-icon-when-light"><use href="#svg-sun"></use></svg>
|
||||
</button>
|
||||
</div>
|
||||
<label class="toc-overlay-icon toc-content-icon no-toc" for="__toc">
|
||||
<div class="visually-hidden">Toggle table of contents sidebar</div>
|
||||
<i class="icon"><svg><use href="#svg-toc"></use></svg></i>
|
||||
</label>
|
||||
</div>
|
||||
<article role="main">
|
||||
<h1>Source code for osxphotos._constants</h1><div class="highlight"><pre>
|
||||
<span></span><span class="sd">"""</span>
|
||||
<span class="sd">Constants used by osxphotos </span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd">"""</span>
|
||||
|
||||
<span class="kn">import</span> <span class="nn">os.path</span>
|
||||
<span class="kn">from</span> <span class="nn">datetime</span> <span class="kn">import</span> <span class="n">datetime</span>
|
||||
<span class="kn">from</span> <span class="nn">enum</span> <span class="kn">import</span> <span class="n">Enum</span>
|
||||
|
||||
<span class="n">APP_NAME</span> <span class="o">=</span> <span class="s2">"osxphotos"</span>
|
||||
<span class="n">APP_NAME</span> <span class="o">=</span> <span class="s2">"osxphotos"</span>
|
||||
|
||||
<span class="n">OSXPHOTOS_URL</span> <span class="o">=</span> <span class="s2">"https://github.com/RhetTbull/osxphotos"</span>
|
||||
<span class="n">OSXPHOTOS_URL</span> <span class="o">=</span> <span class="s2">"https://github.com/RhetTbull/osxphotos"</span>
|
||||
|
||||
<span class="c1"># Time delta: add this to Photos times to get unix time</span>
|
||||
<span class="c1"># Apple Epoch is Jan 1, 2001</span>
|
||||
<span class="n">TIME_DELTA</span> <span class="o">=</span> <span class="p">(</span><span class="n">datetime</span><span class="p">(</span><span class="mi">2001</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="o">-</span> <span class="n">datetime</span><span class="p">(</span><span class="mi">1970</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">))</span><span class="o">.</span><span class="n">total_seconds</span><span class="p">()</span>
|
||||
|
||||
<span class="c1"># Unicode format to use for comparing strings</span>
|
||||
<span class="n">UNICODE_FORMAT</span> <span class="o">=</span> <span class="s2">"NFC"</span>
|
||||
<span class="n">UNICODE_FORMAT</span> <span class="o">=</span> <span class="s2">"NFC"</span>
|
||||
|
||||
<span class="c1"># which Photos library database versions have been tested</span>
|
||||
<span class="c1"># Photos 2.0 (10.12.6) == 2622</span>
|
||||
@@ -56,23 +219,23 @@
|
||||
<span class="c1"># Photos 4.0 (10.14.5) == 4016</span>
|
||||
<span class="c1"># Photos 4.0 (10.14.6) == 4025</span>
|
||||
<span class="c1"># Photos 5.0 (10.15.0) == 6000 or 5001</span>
|
||||
<span class="n">_TESTED_DB_VERSIONS</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"6000"</span><span class="p">,</span> <span class="s2">"5001"</span><span class="p">,</span> <span class="s2">"4025"</span><span class="p">,</span> <span class="s2">"4016"</span><span class="p">,</span> <span class="s2">"3301"</span><span class="p">,</span> <span class="s2">"2622"</span><span class="p">]</span>
|
||||
<span class="n">_TESTED_DB_VERSIONS</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"6000"</span><span class="p">,</span> <span class="s2">"5001"</span><span class="p">,</span> <span class="s2">"4025"</span><span class="p">,</span> <span class="s2">"4016"</span><span class="p">,</span> <span class="s2">"3301"</span><span class="p">,</span> <span class="s2">"2622"</span><span class="p">]</span>
|
||||
|
||||
<span class="c1"># database model versions (applies to Photos 5, Photos 6)</span>
|
||||
<span class="c1"># these come from PLModelVersion key in binary plist in Z_METADATA.Z_PLIST</span>
|
||||
<span class="c1"># Photos 5 (10.15.1) == 13537</span>
|
||||
<span class="c1"># Photos 5 (10.15.4, 10.15.5, 10.15.6) == 13703</span>
|
||||
<span class="c1"># Photos 6 (10.16.0 Beta) == 14104</span>
|
||||
<span class="n">_TEST_MODEL_VERSIONS</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"13537"</span><span class="p">,</span> <span class="s2">"13703"</span><span class="p">,</span> <span class="s2">"14104"</span><span class="p">]</span>
|
||||
<span class="n">_TEST_MODEL_VERSIONS</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"13537"</span><span class="p">,</span> <span class="s2">"13703"</span><span class="p">,</span> <span class="s2">"14104"</span><span class="p">]</span>
|
||||
|
||||
<span class="n">_PHOTOS_2_VERSION</span> <span class="o">=</span> <span class="s2">"2622"</span>
|
||||
<span class="n">_PHOTOS_2_VERSION</span> <span class="o">=</span> <span class="s2">"2622"</span>
|
||||
|
||||
<span class="c1"># only version 3 - 4 have RKVersion.selfPortrait</span>
|
||||
<span class="n">_PHOTOS_3_VERSION</span> <span class="o">=</span> <span class="s2">"3301"</span>
|
||||
<span class="n">_PHOTOS_3_VERSION</span> <span class="o">=</span> <span class="s2">"3301"</span>
|
||||
|
||||
<span class="c1"># versions 5.0 and later have a different database structure</span>
|
||||
<span class="n">_PHOTOS_4_VERSION</span> <span class="o">=</span> <span class="s2">"4025"</span> <span class="c1"># latest Mojove version on 10.14.6</span>
|
||||
<span class="n">_PHOTOS_5_VERSION</span> <span class="o">=</span> <span class="s2">"5000"</span> <span class="c1"># I've seen both 5001 and 6000. 6000 is most common on Catalina and up but there are some version 5001 database in the wild</span>
|
||||
<span class="n">_PHOTOS_4_VERSION</span> <span class="o">=</span> <span class="s2">"4025"</span> <span class="c1"># latest Mojove version on 10.14.6</span>
|
||||
<span class="n">_PHOTOS_5_VERSION</span> <span class="o">=</span> <span class="s2">"5000"</span> <span class="c1"># I've seen both 5001 and 6000. 6000 is most common on Catalina and up but there are some version 5001 database in the wild</span>
|
||||
|
||||
<span class="c1"># Ranges for model version by Photos version</span>
|
||||
<span class="n">_PHOTOS_5_MODEL_VERSION</span> <span class="o">=</span> <span class="p">[</span><span class="mi">13000</span><span class="p">,</span> <span class="mi">13999</span><span class="p">]</span>
|
||||
@@ -85,82 +248,82 @@
|
||||
<span class="c1"># some table names differ between Photos 5 and Photos 6</span>
|
||||
<span class="n">_DB_TABLE_NAMES</span> <span class="o">=</span> <span class="p">{</span>
|
||||
<span class="mi">5</span><span class="p">:</span> <span class="p">{</span>
|
||||
<span class="s2">"ASSET"</span><span class="p">:</span> <span class="s2">"ZGENERICASSET"</span><span class="p">,</span>
|
||||
<span class="s2">"KEYWORD_JOIN"</span><span class="p">:</span> <span class="s2">"Z_1KEYWORDS.Z_37KEYWORDS"</span><span class="p">,</span>
|
||||
<span class="s2">"ALBUM_JOIN"</span><span class="p">:</span> <span class="s2">"Z_26ASSETS.Z_34ASSETS"</span><span class="p">,</span>
|
||||
<span class="s2">"ALBUM_SORT_ORDER"</span><span class="p">:</span> <span class="s2">"Z_26ASSETS.Z_FOK_34ASSETS"</span><span class="p">,</span>
|
||||
<span class="s2">"IMPORT_FOK"</span><span class="p">:</span> <span class="s2">"ZGENERICASSET.Z_FOK_IMPORTSESSION"</span><span class="p">,</span>
|
||||
<span class="s2">"DEPTH_STATE"</span><span class="p">:</span> <span class="s2">"ZGENERICASSET.ZDEPTHSTATES"</span><span class="p">,</span>
|
||||
<span class="s2">"UTI_ORIGINAL"</span><span class="p">:</span> <span class="s2">"ZINTERNALRESOURCE.ZUNIFORMTYPEIDENTIFIER"</span><span class="p">,</span>
|
||||
<span class="s2">"ASSET_ALBUM_JOIN"</span><span class="p">:</span> <span class="s2">"Z_26ASSETS.Z_26ALBUMS"</span><span class="p">,</span>
|
||||
<span class="s2">"ASSET_ALBUM_TABLE"</span><span class="p">:</span> <span class="s2">"Z_26ASSETS"</span><span class="p">,</span>
|
||||
<span class="s2">"HDR_TYPE"</span><span class="p">:</span> <span class="s2">"ZCUSTOMRENDEREDVALUE"</span><span class="p">,</span>
|
||||
<span class="s2">"ASSET"</span><span class="p">:</span> <span class="s2">"ZGENERICASSET"</span><span class="p">,</span>
|
||||
<span class="s2">"KEYWORD_JOIN"</span><span class="p">:</span> <span class="s2">"Z_1KEYWORDS.Z_37KEYWORDS"</span><span class="p">,</span>
|
||||
<span class="s2">"ALBUM_JOIN"</span><span class="p">:</span> <span class="s2">"Z_26ASSETS.Z_34ASSETS"</span><span class="p">,</span>
|
||||
<span class="s2">"ALBUM_SORT_ORDER"</span><span class="p">:</span> <span class="s2">"Z_26ASSETS.Z_FOK_34ASSETS"</span><span class="p">,</span>
|
||||
<span class="s2">"IMPORT_FOK"</span><span class="p">:</span> <span class="s2">"ZGENERICASSET.Z_FOK_IMPORTSESSION"</span><span class="p">,</span>
|
||||
<span class="s2">"DEPTH_STATE"</span><span class="p">:</span> <span class="s2">"ZGENERICASSET.ZDEPTHSTATES"</span><span class="p">,</span>
|
||||
<span class="s2">"UTI_ORIGINAL"</span><span class="p">:</span> <span class="s2">"ZINTERNALRESOURCE.ZUNIFORMTYPEIDENTIFIER"</span><span class="p">,</span>
|
||||
<span class="s2">"ASSET_ALBUM_JOIN"</span><span class="p">:</span> <span class="s2">"Z_26ASSETS.Z_26ALBUMS"</span><span class="p">,</span>
|
||||
<span class="s2">"ASSET_ALBUM_TABLE"</span><span class="p">:</span> <span class="s2">"Z_26ASSETS"</span><span class="p">,</span>
|
||||
<span class="s2">"HDR_TYPE"</span><span class="p">:</span> <span class="s2">"ZCUSTOMRENDEREDVALUE"</span><span class="p">,</span>
|
||||
<span class="p">},</span>
|
||||
<span class="mi">6</span><span class="p">:</span> <span class="p">{</span>
|
||||
<span class="s2">"ASSET"</span><span class="p">:</span> <span class="s2">"ZASSET"</span><span class="p">,</span>
|
||||
<span class="s2">"KEYWORD_JOIN"</span><span class="p">:</span> <span class="s2">"Z_1KEYWORDS.Z_36KEYWORDS"</span><span class="p">,</span>
|
||||
<span class="s2">"ALBUM_JOIN"</span><span class="p">:</span> <span class="s2">"Z_26ASSETS.Z_3ASSETS"</span><span class="p">,</span>
|
||||
<span class="s2">"ALBUM_SORT_ORDER"</span><span class="p">:</span> <span class="s2">"Z_26ASSETS.Z_FOK_3ASSETS"</span><span class="p">,</span>
|
||||
<span class="s2">"IMPORT_FOK"</span><span class="p">:</span> <span class="s2">"null"</span><span class="p">,</span>
|
||||
<span class="s2">"DEPTH_STATE"</span><span class="p">:</span> <span class="s2">"ZASSET.ZDEPTHTYPE"</span><span class="p">,</span>
|
||||
<span class="s2">"UTI_ORIGINAL"</span><span class="p">:</span> <span class="s2">"ZINTERNALRESOURCE.ZUNIFORMTYPEIDENTIFIER"</span><span class="p">,</span>
|
||||
<span class="s2">"ASSET_ALBUM_JOIN"</span><span class="p">:</span> <span class="s2">"Z_26ASSETS.Z_26ALBUMS"</span><span class="p">,</span>
|
||||
<span class="s2">"ASSET_ALBUM_TABLE"</span><span class="p">:</span> <span class="s2">"Z_26ASSETS"</span><span class="p">,</span>
|
||||
<span class="s2">"HDR_TYPE"</span><span class="p">:</span> <span class="s2">"ZCUSTOMRENDEREDVALUE"</span><span class="p">,</span>
|
||||
<span class="s2">"ASSET"</span><span class="p">:</span> <span class="s2">"ZASSET"</span><span class="p">,</span>
|
||||
<span class="s2">"KEYWORD_JOIN"</span><span class="p">:</span> <span class="s2">"Z_1KEYWORDS.Z_36KEYWORDS"</span><span class="p">,</span>
|
||||
<span class="s2">"ALBUM_JOIN"</span><span class="p">:</span> <span class="s2">"Z_26ASSETS.Z_3ASSETS"</span><span class="p">,</span>
|
||||
<span class="s2">"ALBUM_SORT_ORDER"</span><span class="p">:</span> <span class="s2">"Z_26ASSETS.Z_FOK_3ASSETS"</span><span class="p">,</span>
|
||||
<span class="s2">"IMPORT_FOK"</span><span class="p">:</span> <span class="s2">"null"</span><span class="p">,</span>
|
||||
<span class="s2">"DEPTH_STATE"</span><span class="p">:</span> <span class="s2">"ZASSET.ZDEPTHTYPE"</span><span class="p">,</span>
|
||||
<span class="s2">"UTI_ORIGINAL"</span><span class="p">:</span> <span class="s2">"ZINTERNALRESOURCE.ZUNIFORMTYPEIDENTIFIER"</span><span class="p">,</span>
|
||||
<span class="s2">"ASSET_ALBUM_JOIN"</span><span class="p">:</span> <span class="s2">"Z_26ASSETS.Z_26ALBUMS"</span><span class="p">,</span>
|
||||
<span class="s2">"ASSET_ALBUM_TABLE"</span><span class="p">:</span> <span class="s2">"Z_26ASSETS"</span><span class="p">,</span>
|
||||
<span class="s2">"HDR_TYPE"</span><span class="p">:</span> <span class="s2">"ZCUSTOMRENDEREDVALUE"</span><span class="p">,</span>
|
||||
<span class="p">},</span>
|
||||
<span class="mi">7</span><span class="p">:</span> <span class="p">{</span>
|
||||
<span class="s2">"ASSET"</span><span class="p">:</span> <span class="s2">"ZASSET"</span><span class="p">,</span>
|
||||
<span class="s2">"KEYWORD_JOIN"</span><span class="p">:</span> <span class="s2">"Z_1KEYWORDS.Z_38KEYWORDS"</span><span class="p">,</span>
|
||||
<span class="s2">"ALBUM_JOIN"</span><span class="p">:</span> <span class="s2">"Z_27ASSETS.Z_3ASSETS"</span><span class="p">,</span>
|
||||
<span class="s2">"ALBUM_SORT_ORDER"</span><span class="p">:</span> <span class="s2">"Z_27ASSETS.Z_FOK_3ASSETS"</span><span class="p">,</span>
|
||||
<span class="s2">"IMPORT_FOK"</span><span class="p">:</span> <span class="s2">"null"</span><span class="p">,</span>
|
||||
<span class="s2">"DEPTH_STATE"</span><span class="p">:</span> <span class="s2">"ZASSET.ZDEPTHTYPE"</span><span class="p">,</span>
|
||||
<span class="s2">"UTI_ORIGINAL"</span><span class="p">:</span> <span class="s2">"ZINTERNALRESOURCE.ZCOMPACTUTI"</span><span class="p">,</span>
|
||||
<span class="s2">"ASSET_ALBUM_JOIN"</span><span class="p">:</span> <span class="s2">"Z_27ASSETS.Z_27ALBUMS"</span><span class="p">,</span>
|
||||
<span class="s2">"ASSET_ALBUM_TABLE"</span><span class="p">:</span> <span class="s2">"Z_27ASSETS"</span><span class="p">,</span>
|
||||
<span class="s2">"HDR_TYPE"</span><span class="p">:</span> <span class="s2">"ZHDRTYPE"</span><span class="p">,</span>
|
||||
<span class="s2">"ASSET"</span><span class="p">:</span> <span class="s2">"ZASSET"</span><span class="p">,</span>
|
||||
<span class="s2">"KEYWORD_JOIN"</span><span class="p">:</span> <span class="s2">"Z_1KEYWORDS.Z_38KEYWORDS"</span><span class="p">,</span>
|
||||
<span class="s2">"ALBUM_JOIN"</span><span class="p">:</span> <span class="s2">"Z_27ASSETS.Z_3ASSETS"</span><span class="p">,</span>
|
||||
<span class="s2">"ALBUM_SORT_ORDER"</span><span class="p">:</span> <span class="s2">"Z_27ASSETS.Z_FOK_3ASSETS"</span><span class="p">,</span>
|
||||
<span class="s2">"IMPORT_FOK"</span><span class="p">:</span> <span class="s2">"null"</span><span class="p">,</span>
|
||||
<span class="s2">"DEPTH_STATE"</span><span class="p">:</span> <span class="s2">"ZASSET.ZDEPTHTYPE"</span><span class="p">,</span>
|
||||
<span class="s2">"UTI_ORIGINAL"</span><span class="p">:</span> <span class="s2">"ZINTERNALRESOURCE.ZCOMPACTUTI"</span><span class="p">,</span>
|
||||
<span class="s2">"ASSET_ALBUM_JOIN"</span><span class="p">:</span> <span class="s2">"Z_27ASSETS.Z_27ALBUMS"</span><span class="p">,</span>
|
||||
<span class="s2">"ASSET_ALBUM_TABLE"</span><span class="p">:</span> <span class="s2">"Z_27ASSETS"</span><span class="p">,</span>
|
||||
<span class="s2">"HDR_TYPE"</span><span class="p">:</span> <span class="s2">"ZHDRTYPE"</span><span class="p">,</span>
|
||||
<span class="p">},</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="c1"># which version operating systems have been tested</span>
|
||||
<span class="n">_TESTED_OS_VERSIONS</span> <span class="o">=</span> <span class="p">[</span>
|
||||
<span class="p">(</span><span class="s2">"10"</span><span class="p">,</span> <span class="s2">"12"</span><span class="p">),</span>
|
||||
<span class="p">(</span><span class="s2">"10"</span><span class="p">,</span> <span class="s2">"13"</span><span class="p">),</span>
|
||||
<span class="p">(</span><span class="s2">"10"</span><span class="p">,</span> <span class="s2">"14"</span><span class="p">),</span>
|
||||
<span class="p">(</span><span class="s2">"10"</span><span class="p">,</span> <span class="s2">"15"</span><span class="p">),</span>
|
||||
<span class="p">(</span><span class="s2">"10"</span><span class="p">,</span> <span class="s2">"16"</span><span class="p">),</span>
|
||||
<span class="p">(</span><span class="s2">"11"</span><span class="p">,</span> <span class="s2">"0"</span><span class="p">),</span>
|
||||
<span class="p">(</span><span class="s2">"11"</span><span class="p">,</span> <span class="s2">"1"</span><span class="p">),</span>
|
||||
<span class="p">(</span><span class="s2">"11"</span><span class="p">,</span> <span class="s2">"2"</span><span class="p">),</span>
|
||||
<span class="p">(</span><span class="s2">"11"</span><span class="p">,</span> <span class="s2">"3"</span><span class="p">),</span>
|
||||
<span class="p">(</span><span class="s2">"11"</span><span class="p">,</span> <span class="s2">"4"</span><span class="p">),</span>
|
||||
<span class="p">(</span><span class="s2">"11"</span><span class="p">,</span> <span class="s2">"5"</span><span class="p">),</span>
|
||||
<span class="p">(</span><span class="s2">"11"</span><span class="p">,</span> <span class="s2">"6"</span><span class="p">),</span>
|
||||
<span class="p">(</span><span class="s2">"12"</span><span class="p">,</span> <span class="s2">"0"</span><span class="p">),</span>
|
||||
<span class="p">(</span><span class="s2">"12"</span><span class="p">,</span> <span class="s2">"1"</span><span class="p">),</span>
|
||||
<span class="p">(</span><span class="s2">"12"</span><span class="p">,</span> <span class="s2">"2"</span><span class="p">),</span>
|
||||
<span class="p">(</span><span class="s2">"12"</span><span class="p">,</span> <span class="s2">"3"</span><span class="p">),</span>
|
||||
<span class="p">(</span><span class="s2">"10"</span><span class="p">,</span> <span class="s2">"12"</span><span class="p">),</span>
|
||||
<span class="p">(</span><span class="s2">"10"</span><span class="p">,</span> <span class="s2">"13"</span><span class="p">),</span>
|
||||
<span class="p">(</span><span class="s2">"10"</span><span class="p">,</span> <span class="s2">"14"</span><span class="p">),</span>
|
||||
<span class="p">(</span><span class="s2">"10"</span><span class="p">,</span> <span class="s2">"15"</span><span class="p">),</span>
|
||||
<span class="p">(</span><span class="s2">"10"</span><span class="p">,</span> <span class="s2">"16"</span><span class="p">),</span>
|
||||
<span class="p">(</span><span class="s2">"11"</span><span class="p">,</span> <span class="s2">"0"</span><span class="p">),</span>
|
||||
<span class="p">(</span><span class="s2">"11"</span><span class="p">,</span> <span class="s2">"1"</span><span class="p">),</span>
|
||||
<span class="p">(</span><span class="s2">"11"</span><span class="p">,</span> <span class="s2">"2"</span><span class="p">),</span>
|
||||
<span class="p">(</span><span class="s2">"11"</span><span class="p">,</span> <span class="s2">"3"</span><span class="p">),</span>
|
||||
<span class="p">(</span><span class="s2">"11"</span><span class="p">,</span> <span class="s2">"4"</span><span class="p">),</span>
|
||||
<span class="p">(</span><span class="s2">"11"</span><span class="p">,</span> <span class="s2">"5"</span><span class="p">),</span>
|
||||
<span class="p">(</span><span class="s2">"11"</span><span class="p">,</span> <span class="s2">"6"</span><span class="p">),</span>
|
||||
<span class="p">(</span><span class="s2">"12"</span><span class="p">,</span> <span class="s2">"0"</span><span class="p">),</span>
|
||||
<span class="p">(</span><span class="s2">"12"</span><span class="p">,</span> <span class="s2">"1"</span><span class="p">),</span>
|
||||
<span class="p">(</span><span class="s2">"12"</span><span class="p">,</span> <span class="s2">"2"</span><span class="p">),</span>
|
||||
<span class="p">(</span><span class="s2">"12"</span><span class="p">,</span> <span class="s2">"3"</span><span class="p">),</span>
|
||||
<span class="p">]</span>
|
||||
|
||||
<span class="c1"># Photos 5 has persons who are empty string if unidentified face</span>
|
||||
<span class="n">_UNKNOWN_PERSON</span> <span class="o">=</span> <span class="s2">"_UNKNOWN_"</span>
|
||||
<span class="n">_UNKNOWN_PERSON</span> <span class="o">=</span> <span class="s2">"_UNKNOWN_"</span>
|
||||
|
||||
<span class="c1"># photos with no reverse geolocation info (place)</span>
|
||||
<span class="n">_UNKNOWN_PLACE</span> <span class="o">=</span> <span class="s2">"_UNKNOWN_"</span>
|
||||
<span class="n">_UNKNOWN_PLACE</span> <span class="o">=</span> <span class="s2">"_UNKNOWN_"</span>
|
||||
|
||||
<span class="n">_EXIF_TOOL_URL</span> <span class="o">=</span> <span class="s2">"https://exiftool.org/"</span>
|
||||
<span class="n">_EXIF_TOOL_URL</span> <span class="o">=</span> <span class="s2">"https://exiftool.org/"</span>
|
||||
|
||||
<span class="c1"># Where are shared iCloud photos located?</span>
|
||||
<span class="n">_PHOTOS_5_SHARED_PHOTO_PATH</span> <span class="o">=</span> <span class="s2">"resources/cloudsharing/data"</span>
|
||||
<span class="n">_PHOTOS_5_SHARED_PHOTO_PATH</span> <span class="o">=</span> <span class="s2">"resources/cloudsharing/data"</span>
|
||||
|
||||
<span class="c1"># What type of file? Based on ZGENERICASSET.ZKIND in Photos 5 database</span>
|
||||
<span class="n">_PHOTO_TYPE</span> <span class="o">=</span> <span class="mi">0</span>
|
||||
<span class="n">_MOVIE_TYPE</span> <span class="o">=</span> <span class="mi">1</span>
|
||||
|
||||
<span class="c1"># Name of XMP template file</span>
|
||||
<span class="n">_TEMPLATE_DIR</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">dirname</span><span class="p">(</span><span class="vm">__file__</span><span class="p">),</span> <span class="s2">"templates"</span><span class="p">)</span>
|
||||
<span class="n">_XMP_TEMPLATE_NAME</span> <span class="o">=</span> <span class="s2">"xmp_sidecar.mako"</span>
|
||||
<span class="n">_XMP_TEMPLATE_NAME_BETA</span> <span class="o">=</span> <span class="s2">"xmp_sidecar_beta.mako"</span>
|
||||
<span class="n">_TEMPLATE_DIR</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">dirname</span><span class="p">(</span><span class="vm">__file__</span><span class="p">),</span> <span class="s2">"templates"</span><span class="p">)</span>
|
||||
<span class="n">_XMP_TEMPLATE_NAME</span> <span class="o">=</span> <span class="s2">"xmp_sidecar.mako"</span>
|
||||
<span class="n">_XMP_TEMPLATE_NAME_BETA</span> <span class="o">=</span> <span class="s2">"xmp_sidecar_beta.mako"</span>
|
||||
|
||||
<span class="c1"># Constants used for processing folders and albums</span>
|
||||
<span class="n">_PHOTOS_5_ALBUM_KIND</span> <span class="o">=</span> <span class="mi">2</span> <span class="c1"># normal user album</span>
|
||||
@@ -175,20 +338,20 @@
|
||||
<span class="n">_PHOTOS_4_ALBUM_TYPE_PROJECT</span> <span class="o">=</span> <span class="mi">9</span> <span class="c1"># RKAlbum.albumType</span>
|
||||
<span class="n">_PHOTOS_4_ALBUM_TYPE_SLIDESHOW</span> <span class="o">=</span> <span class="mi">8</span> <span class="c1"># RKAlbum.albumType</span>
|
||||
<span class="n">_PHOTOS_4_TOP_LEVEL_ALBUMS</span> <span class="o">=</span> <span class="p">[</span>
|
||||
<span class="s2">"TopLevelAlbums"</span><span class="p">,</span>
|
||||
<span class="s2">"TopLevelKeepsakes"</span><span class="p">,</span>
|
||||
<span class="s2">"TopLevelSlideshows"</span><span class="p">,</span>
|
||||
<span class="s2">"TopLevelAlbums"</span><span class="p">,</span>
|
||||
<span class="s2">"TopLevelKeepsakes"</span><span class="p">,</span>
|
||||
<span class="s2">"TopLevelSlideshows"</span><span class="p">,</span>
|
||||
<span class="p">]</span>
|
||||
<span class="n">_PHOTOS_4_ROOT_FOLDER</span> <span class="o">=</span> <span class="s2">"LibraryFolder"</span>
|
||||
<span class="n">_PHOTOS_4_ROOT_FOLDER</span> <span class="o">=</span> <span class="s2">"LibraryFolder"</span>
|
||||
|
||||
<span class="c1"># EXIF related constants</span>
|
||||
<span class="c1"># max keyword length for IPTC:Keyword, reference</span>
|
||||
<span class="c1"># https://www.iptc.org/std/photometadata/documentation/userguide/</span>
|
||||
<span class="n">_MAX_IPTC_KEYWORD_LEN</span> <span class="o">=</span> <span class="mi">64</span>
|
||||
|
||||
<span class="c1"># Sentinel value for detecting if a template in keyword_template doesn't match</span>
|
||||
<span class="c1"># Sentinel value for detecting if a template in keyword_template doesn't match</span>
|
||||
<span class="c1"># If anyone has a keyword matching this, then too bad...</span>
|
||||
<span class="n">_OSXPHOTOS_NONE_SENTINEL</span> <span class="o">=</span> <span class="s2">"OSXPhotosXYZZY42_Sentinel$"</span>
|
||||
<span class="n">_OSXPHOTOS_NONE_SENTINEL</span> <span class="o">=</span> <span class="s2">"OSXPhotosXYZZY42_Sentinel$"</span>
|
||||
|
||||
<span class="c1"># SearchInfo categories for Photos 5, corresponds to categories in database/search/psi.sqlite</span>
|
||||
<span class="n">SEARCH_CATEGORY_LABEL</span> <span class="o">=</span> <span class="mi">2024</span>
|
||||
@@ -260,13 +423,13 @@
|
||||
<span class="n">DEFAULT_JPEG_QUALITY</span> <span class="o">=</span> <span class="mf">1.0</span>
|
||||
|
||||
<span class="c1"># Default suffix to add to edited images</span>
|
||||
<span class="n">DEFAULT_EDITED_SUFFIX</span> <span class="o">=</span> <span class="s2">"_edited"</span>
|
||||
<span class="n">DEFAULT_EDITED_SUFFIX</span> <span class="o">=</span> <span class="s2">"_edited"</span>
|
||||
|
||||
<span class="c1"># Default suffix to add to original images</span>
|
||||
<span class="n">DEFAULT_ORIGINAL_SUFFIX</span> <span class="o">=</span> <span class="s2">""</span>
|
||||
<span class="n">DEFAULT_ORIGINAL_SUFFIX</span> <span class="o">=</span> <span class="s2">""</span>
|
||||
|
||||
<span class="c1"># Default suffix to add to preview images</span>
|
||||
<span class="n">DEFAULT_PREVIEW_SUFFIX</span> <span class="o">=</span> <span class="s2">"_preview"</span>
|
||||
<span class="n">DEFAULT_PREVIEW_SUFFIX</span> <span class="o">=</span> <span class="s2">"_preview"</span>
|
||||
|
||||
<span class="c1"># Bit masks for --sidecar</span>
|
||||
<span class="n">SIDECAR_JSON</span> <span class="o">=</span> <span class="mh">0x1</span>
|
||||
@@ -275,28 +438,28 @@
|
||||
|
||||
<span class="c1"># supported attributes for --xattr-template</span>
|
||||
<span class="n">EXTENDED_ATTRIBUTE_NAMES</span> <span class="o">=</span> <span class="p">[</span>
|
||||
<span class="s2">"authors"</span><span class="p">,</span>
|
||||
<span class="s2">"comment"</span><span class="p">,</span>
|
||||
<span class="s2">"copyright"</span><span class="p">,</span>
|
||||
<span class="s2">"creator"</span><span class="p">,</span>
|
||||
<span class="s2">"description"</span><span class="p">,</span>
|
||||
<span class="s2">"findercomment"</span><span class="p">,</span>
|
||||
<span class="s2">"headline"</span><span class="p">,</span>
|
||||
<span class="s2">"keywords"</span><span class="p">,</span>
|
||||
<span class="s2">"participants"</span><span class="p">,</span>
|
||||
<span class="s2">"projects"</span><span class="p">,</span>
|
||||
<span class="s2">"rating"</span><span class="p">,</span>
|
||||
<span class="s2">"subject"</span><span class="p">,</span>
|
||||
<span class="s2">"title"</span><span class="p">,</span>
|
||||
<span class="s2">"version"</span><span class="p">,</span>
|
||||
<span class="s2">"authors"</span><span class="p">,</span>
|
||||
<span class="s2">"comment"</span><span class="p">,</span>
|
||||
<span class="s2">"copyright"</span><span class="p">,</span>
|
||||
<span class="s2">"creator"</span><span class="p">,</span>
|
||||
<span class="s2">"description"</span><span class="p">,</span>
|
||||
<span class="s2">"findercomment"</span><span class="p">,</span>
|
||||
<span class="s2">"headline"</span><span class="p">,</span>
|
||||
<span class="s2">"keywords"</span><span class="p">,</span>
|
||||
<span class="s2">"participants"</span><span class="p">,</span>
|
||||
<span class="s2">"projects"</span><span class="p">,</span>
|
||||
<span class="s2">"rating"</span><span class="p">,</span>
|
||||
<span class="s2">"subject"</span><span class="p">,</span>
|
||||
<span class="s2">"title"</span><span class="p">,</span>
|
||||
<span class="s2">"version"</span><span class="p">,</span>
|
||||
<span class="p">]</span>
|
||||
<span class="n">EXTENDED_ATTRIBUTE_NAMES_QUOTED</span> <span class="o">=</span> <span class="p">[</span><span class="sa">f</span><span class="s2">"'</span><span class="si">{</span><span class="n">x</span><span class="si">}</span><span class="s2">'"</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">EXTENDED_ATTRIBUTE_NAMES</span><span class="p">]</span>
|
||||
<span class="n">EXTENDED_ATTRIBUTE_NAMES_QUOTED</span> <span class="o">=</span> <span class="p">[</span><span class="sa">f</span><span class="s2">"'</span><span class="si">{</span><span class="n">x</span><span class="si">}</span><span class="s2">'"</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">EXTENDED_ATTRIBUTE_NAMES</span><span class="p">]</span>
|
||||
|
||||
|
||||
<span class="c1"># name of export DB</span>
|
||||
<span class="n">OSXPHOTOS_EXPORT_DB</span> <span class="o">=</span> <span class="s2">".osxphotos_export.db"</span>
|
||||
<span class="n">OSXPHOTOS_EXPORT_DB</span> <span class="o">=</span> <span class="s2">".osxphotos_export.db"</span>
|
||||
|
||||
<span class="c1"># bit flags for burst images ("burstPickType")</span>
|
||||
<span class="c1"># bit flags for burst images ("burstPickType")</span>
|
||||
<span class="n">BURST_PICK_TYPE_NONE</span> <span class="o">=</span> <span class="mb">0b0</span> <span class="c1"># 0: sometimes used for single images with a burst UUID</span>
|
||||
<span class="n">BURST_NOT_SELECTED</span> <span class="o">=</span> <span class="mb">0b10</span> <span class="c1"># 2: burst image is not selected</span>
|
||||
<span class="n">BURST_DEFAULT_PICK</span> <span class="o">=</span> <span class="mb">0b100</span> <span class="c1"># 4: burst image is the one Photos picked to be key image before any selections made</span>
|
||||
@@ -304,32 +467,32 @@
|
||||
<span class="n">BURST_KEY</span> <span class="o">=</span> <span class="mb">0b10000</span> <span class="c1"># 16: burst image is the key photo (top of burst stack)</span>
|
||||
<span class="n">BURST_UNKNOWN</span> <span class="o">=</span> <span class="mb">0b100000</span> <span class="c1"># 32: this is almost always set with BURST_DEFAULT_PICK and never if BURST_DEFAULT_PICK is not set. I think this has something to do with what algorithm Photos used to pick the default image</span>
|
||||
|
||||
<span class="n">LIVE_VIDEO_EXTENSIONS</span> <span class="o">=</span> <span class="p">[</span><span class="s2">".mov"</span><span class="p">]</span>
|
||||
<span class="n">LIVE_VIDEO_EXTENSIONS</span> <span class="o">=</span> <span class="p">[</span><span class="s2">".mov"</span><span class="p">]</span>
|
||||
|
||||
<span class="c1"># categories that --post-command can be used with; these map to ExportResults fields</span>
|
||||
<span class="n">POST_COMMAND_CATEGORIES</span> <span class="o">=</span> <span class="p">{</span>
|
||||
<span class="s2">"exported"</span><span class="p">:</span> <span class="s2">"All exported files"</span><span class="p">,</span>
|
||||
<span class="s2">"new"</span><span class="p">:</span> <span class="s2">"When used with '--update', all newly exported files"</span><span class="p">,</span>
|
||||
<span class="s2">"updated"</span><span class="p">:</span> <span class="s2">"When used with '--update', all files which were previously exported but updated this time"</span><span class="p">,</span>
|
||||
<span class="s2">"skipped"</span><span class="p">:</span> <span class="s2">"When used with '--update', all files which were skipped (because they were previously exported and didn't change)"</span><span class="p">,</span>
|
||||
<span class="s2">"missing"</span><span class="p">:</span> <span class="s2">"All files which were not exported because they were missing from the Photos library"</span><span class="p">,</span>
|
||||
<span class="s2">"exif_updated"</span><span class="p">:</span> <span class="s2">"When used with '--exiftool', all files on which exiftool updated the metadata"</span><span class="p">,</span>
|
||||
<span class="s2">"touched"</span><span class="p">:</span> <span class="s2">"When used with '--touch-file', all files where the date was touched"</span><span class="p">,</span>
|
||||
<span class="s2">"converted_to_jpeg"</span><span class="p">:</span> <span class="s2">"When used with '--convert-to-jpeg', all files which were converted to jpeg"</span><span class="p">,</span>
|
||||
<span class="s2">"sidecar_json_written"</span><span class="p">:</span> <span class="s2">"When used with '--sidecar json', all JSON sidecar files which were written"</span><span class="p">,</span>
|
||||
<span class="s2">"sidecar_json_skipped"</span><span class="p">:</span> <span class="s2">"When used with '--sidecar json' and '--update', all JSON sidecar files which were skipped"</span><span class="p">,</span>
|
||||
<span class="s2">"sidecar_exiftool_written"</span><span class="p">:</span> <span class="s2">"When used with '--sidecar exiftool', all exiftool sidecar files which were written"</span><span class="p">,</span>
|
||||
<span class="s2">"sidecar_exiftool_skipped"</span><span class="p">:</span> <span class="s2">"When used with '--sidecar exiftool' and '--update, all exiftool sidecar files which were skipped"</span><span class="p">,</span>
|
||||
<span class="s2">"sidecar_xmp_written"</span><span class="p">:</span> <span class="s2">"When used with '--sidecar xmp', all XMP sidecar files which were written"</span><span class="p">,</span>
|
||||
<span class="s2">"sidecar_xmp_skipped"</span><span class="p">:</span> <span class="s2">"When used with '--sidecar xmp' and '--update', all XMP sidecar files which were skipped"</span><span class="p">,</span>
|
||||
<span class="s2">"error"</span><span class="p">:</span> <span class="s2">"All files which produced an error during export"</span><span class="p">,</span>
|
||||
<span class="c1"># "deleted_files": "When used with '--cleanup', all files deleted during the export",</span>
|
||||
<span class="c1"># "deleted_directories": "When used with '--cleanup', all directories deleted during the export",</span>
|
||||
<span class="s2">"exported"</span><span class="p">:</span> <span class="s2">"All exported files"</span><span class="p">,</span>
|
||||
<span class="s2">"new"</span><span class="p">:</span> <span class="s2">"When used with '--update', all newly exported files"</span><span class="p">,</span>
|
||||
<span class="s2">"updated"</span><span class="p">:</span> <span class="s2">"When used with '--update', all files which were previously exported but updated this time"</span><span class="p">,</span>
|
||||
<span class="s2">"skipped"</span><span class="p">:</span> <span class="s2">"When used with '--update', all files which were skipped (because they were previously exported and didn't change)"</span><span class="p">,</span>
|
||||
<span class="s2">"missing"</span><span class="p">:</span> <span class="s2">"All files which were not exported because they were missing from the Photos library"</span><span class="p">,</span>
|
||||
<span class="s2">"exif_updated"</span><span class="p">:</span> <span class="s2">"When used with '--exiftool', all files on which exiftool updated the metadata"</span><span class="p">,</span>
|
||||
<span class="s2">"touched"</span><span class="p">:</span> <span class="s2">"When used with '--touch-file', all files where the date was touched"</span><span class="p">,</span>
|
||||
<span class="s2">"converted_to_jpeg"</span><span class="p">:</span> <span class="s2">"When used with '--convert-to-jpeg', all files which were converted to jpeg"</span><span class="p">,</span>
|
||||
<span class="s2">"sidecar_json_written"</span><span class="p">:</span> <span class="s2">"When used with '--sidecar json', all JSON sidecar files which were written"</span><span class="p">,</span>
|
||||
<span class="s2">"sidecar_json_skipped"</span><span class="p">:</span> <span class="s2">"When used with '--sidecar json' and '--update', all JSON sidecar files which were skipped"</span><span class="p">,</span>
|
||||
<span class="s2">"sidecar_exiftool_written"</span><span class="p">:</span> <span class="s2">"When used with '--sidecar exiftool', all exiftool sidecar files which were written"</span><span class="p">,</span>
|
||||
<span class="s2">"sidecar_exiftool_skipped"</span><span class="p">:</span> <span class="s2">"When used with '--sidecar exiftool' and '--update, all exiftool sidecar files which were skipped"</span><span class="p">,</span>
|
||||
<span class="s2">"sidecar_xmp_written"</span><span class="p">:</span> <span class="s2">"When used with '--sidecar xmp', all XMP sidecar files which were written"</span><span class="p">,</span>
|
||||
<span class="s2">"sidecar_xmp_skipped"</span><span class="p">:</span> <span class="s2">"When used with '--sidecar xmp' and '--update', all XMP sidecar files which were skipped"</span><span class="p">,</span>
|
||||
<span class="s2">"error"</span><span class="p">:</span> <span class="s2">"All files which produced an error during export"</span><span class="p">,</span>
|
||||
<span class="c1"># "deleted_files": "When used with '--cleanup', all files deleted during the export",</span>
|
||||
<span class="c1"># "deleted_directories": "When used with '--cleanup', all directories deleted during the export",</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="AlbumSortOrder"><a class="viewcode-back" href="../../reference.html#osxphotos.AlbumSortOrder">[docs]</a><span class="k">class</span> <span class="nc">AlbumSortOrder</span><span class="p">(</span><span class="n">Enum</span><span class="p">):</span>
|
||||
<span class="sd">"""Album Sort Order"""</span>
|
||||
<span class="sd">"""Album Sort Order"""</span>
|
||||
|
||||
<span class="n">UNKNOWN</span> <span class="o">=</span> <span class="mi">0</span>
|
||||
<span class="n">MANUAL</span> <span class="o">=</span> <span class="mi">1</span>
|
||||
@@ -342,88 +505,61 @@
|
||||
|
||||
<span class="c1"># stat sort order for cProfile: https://docs.python.org/3/library/profile.html#pstats.Stats.sort_stats</span>
|
||||
<span class="n">PROFILE_SORT_KEYS</span> <span class="o">=</span> <span class="p">[</span>
|
||||
<span class="s2">"calls"</span><span class="p">,</span>
|
||||
<span class="s2">"cumulative"</span><span class="p">,</span>
|
||||
<span class="s2">"cumtime"</span><span class="p">,</span>
|
||||
<span class="s2">"file"</span><span class="p">,</span>
|
||||
<span class="s2">"filename"</span><span class="p">,</span>
|
||||
<span class="s2">"module"</span><span class="p">,</span>
|
||||
<span class="s2">"ncalls"</span><span class="p">,</span>
|
||||
<span class="s2">"pcalls"</span><span class="p">,</span>
|
||||
<span class="s2">"line"</span><span class="p">,</span>
|
||||
<span class="s2">"name"</span><span class="p">,</span>
|
||||
<span class="s2">"nfl"</span><span class="p">,</span>
|
||||
<span class="s2">"stdname"</span><span class="p">,</span>
|
||||
<span class="s2">"time"</span><span class="p">,</span>
|
||||
<span class="s2">"tottime"</span><span class="p">,</span>
|
||||
<span class="s2">"calls"</span><span class="p">,</span>
|
||||
<span class="s2">"cumulative"</span><span class="p">,</span>
|
||||
<span class="s2">"cumtime"</span><span class="p">,</span>
|
||||
<span class="s2">"file"</span><span class="p">,</span>
|
||||
<span class="s2">"filename"</span><span class="p">,</span>
|
||||
<span class="s2">"module"</span><span class="p">,</span>
|
||||
<span class="s2">"ncalls"</span><span class="p">,</span>
|
||||
<span class="s2">"pcalls"</span><span class="p">,</span>
|
||||
<span class="s2">"line"</span><span class="p">,</span>
|
||||
<span class="s2">"name"</span><span class="p">,</span>
|
||||
<span class="s2">"nfl"</span><span class="p">,</span>
|
||||
<span class="s2">"stdname"</span><span class="p">,</span>
|
||||
<span class="s2">"time"</span><span class="p">,</span>
|
||||
<span class="s2">"tottime"</span><span class="p">,</span>
|
||||
<span class="p">]</span>
|
||||
</pre></div>
|
||||
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
<footer>
|
||||
|
||||
<div class="related-pages">
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||||
<div class="sphinxsidebarwrapper">
|
||||
<h1 class="logo"><a href="../../index.html">osxphotos</a></h1>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../overview.html">osxphotos</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../tutorial.html">Tutorial</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../cli.html">osxphotos command line interface (CLI)</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../reference.html">osxphotos package</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="relations">
|
||||
<h3>Related Topics</h3>
|
||||
<ul>
|
||||
<li><a href="../../index.html">Documentation overview</a><ul>
|
||||
<li><a href="../index.html">Module code</a><ul>
|
||||
</ul></li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="searchbox" style="display: none" role="search">
|
||||
<h3 id="searchlabel">Quick search</h3>
|
||||
<div class="searchformwrapper">
|
||||
<form class="search" action="../../search.html" method="get">
|
||||
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
|
||||
<input type="submit" value="Go" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<script>$('#searchbox').show(0);</script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="bottom-of-page">
|
||||
<div class="left-details">
|
||||
<div class="copyright">
|
||||
Copyright © 2021, Rhet Turnbull
|
||||
</div>
|
||||
Made with <a href="https://www.sphinx-doc.org/">Sphinx</a> and <a class="muted-link" href="https://pradyunsg.me">@pradyunsg</a>'s
|
||||
|
||||
<a href="https://github.com/pradyunsg/furo">Furo</a>
|
||||
|
||||
</div>
|
||||
<div class="right-details">
|
||||
<div class="icons">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
|
||||
</footer>
|
||||
</div>
|
||||
<div class="footer">
|
||||
©2021, Rhet Turnbull.
|
||||
<aside class="toc-drawer no-toc">
|
||||
|
||||
|
|
||||
Powered by <a href="http://sphinx-doc.org/">Sphinx 4.4.0</a>
|
||||
& <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
|
||||
</aside>
|
||||
</div>
|
||||
</div><script data-url_root="../../" id="documentation_options" src="../../_static/documentation_options.js"></script>
|
||||
<script src="../../_static/jquery.js"></script>
|
||||
<script src="../../_static/underscore.js"></script>
|
||||
<script src="../../_static/doctools.js"></script>
|
||||
<script src="../../_static/scripts/furo.js"></script>
|
||||
<script src="../../_static/clipboard.min.js"></script>
|
||||
<script src="../../_static/copybutton.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,173 +1,325 @@
|
||||
<!doctype html>
|
||||
<html class="no-js">
|
||||
<head><meta charset="utf-8"/>
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1"/>
|
||||
<meta name="color-scheme" content="light dark"><link rel="index" title="Index" href="../../genindex.html" /><link rel="search" title="Search" href="../../search.html" />
|
||||
|
||||
<!DOCTYPE html>
|
||||
<meta name="generator" content="sphinx-4.4.0, furo 2022.04.07"/>
|
||||
<title>osxphotos.momentinfo - osxphotos 0.48.1 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="../../_static/styles/furo.css?digest=68f4518137b9aefe99b631505a2064c3c42c9852" />
|
||||
<link rel="stylesheet" type="text/css" href="../../_static/copybutton.css" />
|
||||
<link rel="stylesheet" type="text/css" href="../../_static/styles/furo-extensions.css?digest=30d1aed668e5c3a91c3e3bf6a60b675221979f0e" />
|
||||
|
||||
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>osxphotos.momentinfo — osxphotos 0.47.9 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="../../_static/alabaster.css" />
|
||||
<script data-url_root="../../" id="documentation_options" src="../../_static/documentation_options.js"></script>
|
||||
<script src="../../_static/jquery.js"></script>
|
||||
<script src="../../_static/underscore.js"></script>
|
||||
<script src="../../_static/doctools.js"></script>
|
||||
<link rel="index" title="Index" href="../../genindex.html" />
|
||||
<link rel="search" title="Search" href="../../search.html" />
|
||||
|
||||
<link rel="stylesheet" href="../../_static/custom.css" type="text/css" />
|
||||
|
||||
<style>
|
||||
body {
|
||||
--color-code-background: #f8f8f8;
|
||||
--color-code-foreground: black;
|
||||
|
||||
}
|
||||
@media not print {
|
||||
body[data-theme="dark"] {
|
||||
--color-code-background: #202020;
|
||||
--color-code-foreground: #d0d0d0;
|
||||
|
||||
}
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body:not([data-theme="light"]) {
|
||||
--color-code-background: #202020;
|
||||
--color-code-foreground: #d0d0d0;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</style></head>
|
||||
<body>
|
||||
|
||||
<script>
|
||||
document.body.dataset.theme = localStorage.getItem("theme") || "auto";
|
||||
</script>
|
||||
|
||||
|
||||
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
|
||||
<symbol id="svg-toc" viewBox="0 0 24 24">
|
||||
<title>Contents</title>
|
||||
<svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 1024 1024">
|
||||
<path d="M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM115.4 518.9L271.7 642c5.8 4.6 14.4.5 14.4-6.9V388.9c0-7.4-8.5-11.5-14.4-6.9L115.4 505.1a8.74 8.74 0 0 0 0 13.8z"/>
|
||||
</svg>
|
||||
</symbol>
|
||||
<symbol id="svg-menu" viewBox="0 0 24 24">
|
||||
<title>Menu</title>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather-menu">
|
||||
<line x1="3" y1="12" x2="21" y2="12"></line>
|
||||
<line x1="3" y1="6" x2="21" y2="6"></line>
|
||||
<line x1="3" y1="18" x2="21" y2="18"></line>
|
||||
</svg>
|
||||
</symbol>
|
||||
<symbol id="svg-arrow-right" viewBox="0 0 24 24">
|
||||
<title>Expand</title>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather-chevron-right">
|
||||
<polyline points="9 18 15 12 9 6"></polyline>
|
||||
</svg>
|
||||
</symbol>
|
||||
<symbol id="svg-sun" viewBox="0 0 24 24">
|
||||
<title>Light mode</title>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="feather-sun">
|
||||
<circle cx="12" cy="12" r="5"></circle>
|
||||
<line x1="12" y1="1" x2="12" y2="3"></line>
|
||||
<line x1="12" y1="21" x2="12" y2="23"></line>
|
||||
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
|
||||
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
|
||||
<line x1="1" y1="12" x2="3" y2="12"></line>
|
||||
<line x1="21" y1="12" x2="23" y2="12"></line>
|
||||
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
|
||||
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
|
||||
</svg>
|
||||
</symbol>
|
||||
<symbol id="svg-moon" viewBox="0 0 24 24">
|
||||
<title>Dark mode</title>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="icon-tabler-moon">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M12 3c.132 0 .263 0 .393 0a7.5 7.5 0 0 0 7.92 12.446a9 9 0 1 1 -8.313 -12.454z" />
|
||||
</svg>
|
||||
</symbol>
|
||||
<symbol id="svg-sun-half" viewBox="0 0 24 24">
|
||||
<title>Auto light/dark mode</title>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="icon-tabler-shadow">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"/>
|
||||
<circle cx="12" cy="12" r="9" />
|
||||
<path d="M13 12h5" />
|
||||
<path d="M13 15h4" />
|
||||
<path d="M13 18h1" />
|
||||
<path d="M13 9h4" />
|
||||
<path d="M13 6h1" />
|
||||
</svg>
|
||||
</symbol>
|
||||
</svg>
|
||||
|
||||
<input type="checkbox" class="sidebar-toggle" name="__navigation" id="__navigation">
|
||||
<input type="checkbox" class="sidebar-toggle" name="__toc" id="__toc">
|
||||
<label class="overlay sidebar-overlay" for="__navigation">
|
||||
<div class="visually-hidden">Hide navigation sidebar</div>
|
||||
</label>
|
||||
<label class="overlay toc-overlay" for="__toc">
|
||||
<div class="visually-hidden">Hide table of contents sidebar</div>
|
||||
</label>
|
||||
|
||||
|
||||
|
||||
<div class="page">
|
||||
<header class="mobile-header">
|
||||
<div class="header-left">
|
||||
<label class="nav-overlay-icon" for="__navigation">
|
||||
<div class="visually-hidden">Toggle site navigation sidebar</div>
|
||||
<i class="icon"><svg><use href="#svg-menu"></use></svg></i>
|
||||
</label>
|
||||
</div>
|
||||
<div class="header-center">
|
||||
<a href="../../index.html"><div class="brand">osxphotos 0.48.1 documentation</div></a>
|
||||
</div>
|
||||
<div class="header-right">
|
||||
<div class="theme-toggle-container theme-toggle-header">
|
||||
<button class="theme-toggle">
|
||||
<div class="visually-hidden">Toggle Light / Dark / Auto color theme</div>
|
||||
<svg class="theme-icon-when-auto"><use href="#svg-sun-half"></use></svg>
|
||||
<svg class="theme-icon-when-dark"><use href="#svg-moon"></use></svg>
|
||||
<svg class="theme-icon-when-light"><use href="#svg-sun"></use></svg>
|
||||
</button>
|
||||
</div>
|
||||
<label class="toc-overlay-icon toc-header-icon no-toc" for="__toc">
|
||||
<div class="visually-hidden">Toggle table of contents sidebar</div>
|
||||
<i class="icon"><svg><use href="#svg-toc"></use></svg></i>
|
||||
</label>
|
||||
</div>
|
||||
</header>
|
||||
<aside class="sidebar-drawer">
|
||||
<div class="sidebar-container">
|
||||
|
||||
<div class="sidebar-sticky"><a class="sidebar-brand" href="../../index.html">
|
||||
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
|
||||
|
||||
</head><body>
|
||||
<span class="sidebar-brand-text">osxphotos 0.48.1 documentation</span>
|
||||
|
||||
</a><form class="sidebar-search-container" method="get" action="../../search.html" role="search">
|
||||
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
|
||||
<input type="hidden" name="check_keywords" value="yes">
|
||||
<input type="hidden" name="area" value="default">
|
||||
</form>
|
||||
<div id="searchbox"></div><div class="sidebar-scroll"><div class="sidebar-tree">
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../overview.html">OSXPhotos</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../tutorial.html">OSXPhotos Tutorial</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../cli.html">OSXPhotos Command Line Interface (CLI)</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../template_help.html">OSXPhotos Template System</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../package_overview.html">OSXPhotos Python Package Overview</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../reference.html">OSXPhotos python API</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="document">
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="body" role="main">
|
||||
|
||||
<h1>Source code for osxphotos.momentinfo</h1><div class="highlight"><pre>
|
||||
<span></span><span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"MomentInfo"</span><span class="p">]</span>
|
||||
<span class="sd">"""MomentInfo class with details about photo moments."""</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</aside>
|
||||
<div class="main">
|
||||
<div class="content">
|
||||
<div class="article-container">
|
||||
<a href="#" class="back-to-top muted-link">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8v12z"></path>
|
||||
</svg>
|
||||
<span>Back to top</span>
|
||||
</a>
|
||||
<div class="content-icon-container"><div class="theme-toggle-container theme-toggle-content">
|
||||
<button class="theme-toggle">
|
||||
<div class="visually-hidden">Toggle Light / Dark / Auto color theme</div>
|
||||
<svg class="theme-icon-when-auto"><use href="#svg-sun-half"></use></svg>
|
||||
<svg class="theme-icon-when-dark"><use href="#svg-moon"></use></svg>
|
||||
<svg class="theme-icon-when-light"><use href="#svg-sun"></use></svg>
|
||||
</button>
|
||||
</div>
|
||||
<label class="toc-overlay-icon toc-content-icon no-toc" for="__toc">
|
||||
<div class="visually-hidden">Toggle table of contents sidebar</div>
|
||||
<i class="icon"><svg><use href="#svg-toc"></use></svg></i>
|
||||
</label>
|
||||
</div>
|
||||
<article role="main">
|
||||
<h1>Source code for osxphotos.momentinfo</h1><div class="highlight"><pre>
|
||||
<span></span><span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"MomentInfo"</span><span class="p">]</span>
|
||||
<span class="sd">"""MomentInfo class with details about photo moments."""</span>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="MomentInfo"><a class="viewcode-back" href="../../reference.html#osxphotos.MomentInfo">[docs]</a><span class="k">class</span> <span class="nc">MomentInfo</span><span class="p">:</span>
|
||||
<span class="sd">"""Info about a photo moment"""</span>
|
||||
<span class="sd">"""Info about a photo moment"""</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">db</span><span class="p">,</span> <span class="n">moment_pk</span><span class="p">):</span>
|
||||
<span class="sd">"""Initialize with a moment PK; returns None if PK not found."""</span>
|
||||
<span class="sd">"""Initialize with a moment PK; returns None if PK not found."""</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_db</span> <span class="o">=</span> <span class="n">db</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_pk</span> <span class="o">=</span> <span class="n">moment_pk</span>
|
||||
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_moment</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_db_moment_pk</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">moment_pk</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_moment</span><span class="p">:</span>
|
||||
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"No moment with PK </span><span class="si">{</span><span class="n">moment_pk</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
|
||||
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"No moment with PK </span><span class="si">{</span><span class="n">moment_pk</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">pk</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""Primary key of the moment."""</span>
|
||||
<span class="sd">"""Primary key of the moment."""</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_pk</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">location</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""Location of the moment."""</span>
|
||||
<span class="k">return</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_moment</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"latitude"</span><span class="p">),</span> <span class="bp">self</span><span class="o">.</span><span class="n">_moment</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"longitude"</span><span class="p">))</span>
|
||||
<span class="sd">"""Location of the moment."""</span>
|
||||
<span class="k">return</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_moment</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"latitude"</span><span class="p">),</span> <span class="bp">self</span><span class="o">.</span><span class="n">_moment</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"longitude"</span><span class="p">))</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">title</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""Title of the moment."""</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_moment</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"title"</span><span class="p">)</span>
|
||||
<span class="sd">"""Title of the moment."""</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_moment</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"title"</span><span class="p">)</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">subtitle</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""Subtitle of the moment."""</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_moment</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"subtitle"</span><span class="p">)</span>
|
||||
<span class="sd">"""Subtitle of the moment."""</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_moment</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"subtitle"</span><span class="p">)</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">start_date</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""Start date of the moment."""</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_moment</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"startDate"</span><span class="p">)</span>
|
||||
<span class="sd">"""Start date of the moment."""</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_moment</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"startDate"</span><span class="p">)</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">end_date</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""Stop date of the moment."""</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_moment</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"endDate"</span><span class="p">)</span>
|
||||
<span class="sd">"""Stop date of the moment."""</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_moment</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"endDate"</span><span class="p">)</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">date</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""Date of the moment."""</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_moment</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"representativeDate"</span><span class="p">)</span>
|
||||
<span class="sd">"""Date of the moment."""</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_moment</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"representativeDate"</span><span class="p">)</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">modification_date</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""Modification date of the moment."""</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_moment</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"modificationDate"</span><span class="p">)</span>
|
||||
<span class="sd">"""Modification date of the moment."""</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_moment</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"modificationDate"</span><span class="p">)</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">photos</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""All photos in this moment"""</span>
|
||||
<span class="sd">"""All photos in this moment"""</span>
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_photos</span>
|
||||
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
|
||||
<span class="n">photo_uuids</span> <span class="o">=</span> <span class="p">[</span>
|
||||
<span class="n">uuid</span>
|
||||
<span class="k">for</span> <span class="n">uuid</span><span class="p">,</span> <span class="n">photo</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_dbphotos</span><span class="o">.</span><span class="n">items</span><span class="p">()</span>
|
||||
<span class="k">if</span> <span class="n">photo</span><span class="p">[</span><span class="s2">"momentID"</span><span class="p">]</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">_pk</span>
|
||||
<span class="k">if</span> <span class="n">photo</span><span class="p">[</span><span class="s2">"momentID"</span><span class="p">]</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">_pk</span>
|
||||
<span class="p">]</span>
|
||||
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_photos</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">photos_by_uuid</span><span class="p">(</span><span class="n">photo_uuids</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_photos</span></div>
|
||||
</pre></div>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_photos</span>
|
||||
|
||||
</div>
|
||||
<div class="viewcode-block" id="MomentInfo.asdict"><a class="viewcode-back" href="../../reference.html#osxphotos.MomentInfo.asdict">[docs]</a> <span class="k">def</span> <span class="nf">asdict</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""Returns all moment info as dictionary"""</span>
|
||||
<span class="k">return</span> <span class="p">{</span>
|
||||
<span class="s2">"pk"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">pk</span><span class="p">,</span>
|
||||
<span class="s2">"location"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">location</span><span class="p">,</span>
|
||||
<span class="s2">"title"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">title</span><span class="p">,</span>
|
||||
<span class="s2">"subtitle"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">subtitle</span><span class="p">,</span>
|
||||
<span class="s2">"start_date"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">start_date</span><span class="o">.</span><span class="n">isoformat</span><span class="p">()</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">start_date</span> <span class="k">else</span> <span class="kc">None</span><span class="p">,</span>
|
||||
<span class="s2">"end_date"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">end_date</span><span class="o">.</span><span class="n">isoformat</span><span class="p">()</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">end_date</span> <span class="k">else</span> <span class="kc">None</span><span class="p">,</span>
|
||||
<span class="s2">"date"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">date</span><span class="o">.</span><span class="n">isoformat</span><span class="p">()</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">date</span> <span class="k">else</span> <span class="kc">None</span><span class="p">,</span>
|
||||
<span class="s2">"modification_date"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">modification_date</span><span class="o">.</span><span class="n">isoformat</span><span class="p">()</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">modification_date</span>
|
||||
<span class="k">else</span> <span class="kc">None</span><span class="p">,</span>
|
||||
<span class="s2">"photos"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">photos</span><span class="p">,</span>
|
||||
<span class="p">}</span></div></div>
|
||||
</pre></div>
|
||||
</article>
|
||||
</div>
|
||||
<footer>
|
||||
|
||||
<div class="related-pages">
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||||
<div class="sphinxsidebarwrapper">
|
||||
<h1 class="logo"><a href="../../index.html">osxphotos</a></h1>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../overview.html">osxphotos</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../tutorial.html">Tutorial</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../cli.html">osxphotos command line interface (CLI)</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../reference.html">osxphotos package</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="relations">
|
||||
<h3>Related Topics</h3>
|
||||
<ul>
|
||||
<li><a href="../../index.html">Documentation overview</a><ul>
|
||||
<li><a href="../index.html">Module code</a><ul>
|
||||
</ul></li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="searchbox" style="display: none" role="search">
|
||||
<h3 id="searchlabel">Quick search</h3>
|
||||
<div class="searchformwrapper">
|
||||
<form class="search" action="../../search.html" method="get">
|
||||
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
|
||||
<input type="submit" value="Go" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<script>$('#searchbox').show(0);</script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="bottom-of-page">
|
||||
<div class="left-details">
|
||||
<div class="copyright">
|
||||
Copyright © 2021, Rhet Turnbull
|
||||
</div>
|
||||
Made with <a href="https://www.sphinx-doc.org/">Sphinx</a> and <a class="muted-link" href="https://pradyunsg.me">@pradyunsg</a>'s
|
||||
|
||||
<a href="https://github.com/pradyunsg/furo">Furo</a>
|
||||
|
||||
</div>
|
||||
<div class="right-details">
|
||||
<div class="icons">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
|
||||
</footer>
|
||||
</div>
|
||||
<div class="footer">
|
||||
©2021, Rhet Turnbull.
|
||||
<aside class="toc-drawer no-toc">
|
||||
|
||||
|
|
||||
Powered by <a href="http://sphinx-doc.org/">Sphinx 4.4.0</a>
|
||||
& <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
|
||||
</aside>
|
||||
</div>
|
||||
</div><script data-url_root="../../" id="documentation_options" src="../../_static/documentation_options.js"></script>
|
||||
<script src="../../_static/jquery.js"></script>
|
||||
<script src="../../_static/underscore.js"></script>
|
||||
<script src="../../_static/doctools.js"></script>
|
||||
<script src="../../_static/scripts/furo.js"></script>
|
||||
<script src="../../_static/clipboard.min.js"></script>
|
||||
<script src="../../_static/copybutton.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -5,7 +5,7 @@
|
||||
<meta name="color-scheme" content="light dark"><link rel="index" title="Index" href="../../genindex.html" /><link rel="search" title="Search" href="../../search.html" />
|
||||
|
||||
<meta name="generator" content="sphinx-4.4.0, furo 2022.04.07"/>
|
||||
<title>osxphotos.photoinfo - osxphotos 0.47.9 documentation</title>
|
||||
<title>osxphotos.photoinfo - osxphotos 0.48.1 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="../../_static/styles/furo.css?digest=68f4518137b9aefe99b631505a2064c3c42c9852" />
|
||||
<link rel="stylesheet" type="text/css" href="../../_static/copybutton.css" />
|
||||
@@ -123,7 +123,7 @@
|
||||
</label>
|
||||
</div>
|
||||
<div class="header-center">
|
||||
<a href="../../index.html"><div class="brand">osxphotos 0.47.9 documentation</div></a>
|
||||
<a href="../../index.html"><div class="brand">osxphotos 0.48.1 documentation</div></a>
|
||||
</div>
|
||||
<div class="header-right">
|
||||
<div class="theme-toggle-container theme-toggle-header">
|
||||
@@ -146,7 +146,7 @@
|
||||
<div class="sidebar-sticky"><a class="sidebar-brand" href="../../index.html">
|
||||
|
||||
|
||||
<span class="sidebar-brand-text">osxphotos 0.47.9 documentation</span>
|
||||
<span class="sidebar-brand-text">osxphotos 0.48.1 documentation</span>
|
||||
|
||||
</a><form class="sidebar-search-container" method="get" action="../../search.html" role="search">
|
||||
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
|
||||
@@ -155,11 +155,12 @@
|
||||
</form>
|
||||
<div id="searchbox"></div><div class="sidebar-scroll"><div class="sidebar-tree">
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../overview.html">osxphotos</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../tutorial.html">osxphotos Tutorial</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../cli.html">osxphotos Command Line Interface (CLI)</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../package_overview.html">Example uses of the python package</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../reference.html">osxphotos python API</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../overview.html">OSXPhotos</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../tutorial.html">OSXPhotos Tutorial</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../cli.html">OSXPhotos Command Line Interface (CLI)</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../template_help.html">OSXPhotos Template System</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../package_overview.html">OSXPhotos Python Package Overview</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../reference.html">OSXPhotos python API</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
@@ -674,7 +675,7 @@
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_faceinfo</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">moment</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="k">def</span> <span class="nf">moment_info</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""Moment photo belongs to"""</span>
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_moment</span>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -5,7 +5,7 @@
|
||||
<meta name="color-scheme" content="light dark"><link rel="index" title="Index" href="../../genindex.html" /><link rel="search" title="Search" href="../../search.html" />
|
||||
|
||||
<meta name="generator" content="sphinx-4.4.0, furo 2022.04.07"/>
|
||||
<title>osxphotos.phototemplate - osxphotos 0.47.10 documentation</title>
|
||||
<title>osxphotos.phototemplate - osxphotos 0.48.1 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="../../_static/styles/furo.css?digest=68f4518137b9aefe99b631505a2064c3c42c9852" />
|
||||
<link rel="stylesheet" type="text/css" href="../../_static/copybutton.css" />
|
||||
@@ -123,7 +123,7 @@
|
||||
</label>
|
||||
</div>
|
||||
<div class="header-center">
|
||||
<a href="../../index.html"><div class="brand">osxphotos 0.47.10 documentation</div></a>
|
||||
<a href="../../index.html"><div class="brand">osxphotos 0.48.1 documentation</div></a>
|
||||
</div>
|
||||
<div class="header-right">
|
||||
<div class="theme-toggle-container theme-toggle-header">
|
||||
@@ -146,7 +146,7 @@
|
||||
<div class="sidebar-sticky"><a class="sidebar-brand" href="../../index.html">
|
||||
|
||||
|
||||
<span class="sidebar-brand-text">osxphotos 0.47.10 documentation</span>
|
||||
<span class="sidebar-brand-text">osxphotos 0.48.1 documentation</span>
|
||||
|
||||
</a><form class="sidebar-search-container" method="get" action="../../search.html" role="search">
|
||||
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
|
||||
@@ -155,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>
|
||||
@@ -333,6 +334,7 @@
|
||||
<span class="s2">"</span><span class="si">{exif.camera_make}</span><span class="s2">"</span><span class="p">:</span> <span class="s2">"Camera make from original photo's EXIF information as imported by Photos, e.g. 'Apple'"</span><span class="p">,</span>
|
||||
<span class="s2">"</span><span class="si">{exif.camera_model}</span><span class="s2">"</span><span class="p">:</span> <span class="s2">"Camera model from original photo's EXIF information as imported by Photos, e.g. 'iPhone 6s'"</span><span class="p">,</span>
|
||||
<span class="s2">"</span><span class="si">{exif.lens_model}</span><span class="s2">"</span><span class="p">:</span> <span class="s2">"Lens model from original photo's EXIF information as imported by Photos, e.g. 'iPhone 6s back camera 4.15mm f/2.2'"</span><span class="p">,</span>
|
||||
<span class="s2">"</span><span class="si">{moment}</span><span class="s2">"</span><span class="p">:</span> <span class="s2">"The moment title of the photo"</span><span class="p">,</span>
|
||||
<span class="s2">"</span><span class="si">{uuid}</span><span class="s2">"</span><span class="p">:</span> <span class="s2">"Photo's internal universally unique identifier (UUID) for the photo, a 36-character string unique to the photo, e.g. '128FB4C6-0B16-4E7D-9108-FB2E90DA1546'"</span><span class="p">,</span>
|
||||
<span class="s2">"</span><span class="si">{id}</span><span class="s2">"</span><span class="p">:</span> <span class="s2">"A unique number for the photo based on its primary key in the Photos database. "</span>
|
||||
<span class="o">+</span> <span class="s2">"A sequential integer, e.g. 1, 2, 3...etc. Each asset associated with a photo (e.g. an image and Live Photo preview) will share the same id. "</span>
|
||||
@@ -1169,6 +1171,8 @@
|
||||
<span class="n">value</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">photo</span><span class="o">.</span><span class="n">exif_info</span><span class="o">.</span><span class="n">camera_model</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">photo</span><span class="o">.</span><span class="n">exif_info</span> <span class="k">else</span> <span class="kc">None</span>
|
||||
<span class="k">elif</span> <span class="n">field</span> <span class="o">==</span> <span class="s2">"exif.lens_model"</span><span class="p">:</span>
|
||||
<span class="n">value</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">photo</span><span class="o">.</span><span class="n">exif_info</span><span class="o">.</span><span class="n">lens_model</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">photo</span><span class="o">.</span><span class="n">exif_info</span> <span class="k">else</span> <span class="kc">None</span>
|
||||
<span class="k">elif</span> <span class="n">field</span> <span class="o">==</span> <span class="s2">"moment"</span><span class="p">:</span>
|
||||
<span class="n">value</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">photo</span><span class="o">.</span><span class="n">moment_info</span><span class="o">.</span><span class="n">title</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">photo</span><span class="o">.</span><span class="n">moment_info</span> <span class="k">else</span> <span class="kc">None</span>
|
||||
<span class="k">elif</span> <span class="n">field</span> <span class="o">==</span> <span class="s2">"uuid"</span><span class="p">:</span>
|
||||
<span class="n">value</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">photo</span><span class="o">.</span><span class="n">uuid</span>
|
||||
<span class="k">elif</span> <span class="n">field</span> <span class="o">==</span> <span class="s2">"id"</span><span class="p">:</span>
|
||||
@@ -1590,6 +1594,19 @@
|
||||
<span class="k">return</span> <span class="n">md</span>
|
||||
|
||||
|
||||
<span class="k">def</span> <span class="nf">get_template_field_table</span><span class="p">():</span>
|
||||
<span class="sd">"""Return markdown table of template field substitutions"""</span>
|
||||
<span class="n">template_table</span> <span class="o">=</span> <span class="s2">"| Field | Description |"</span> <span class="o">+</span> <span class="s2">"</span><span class="se">\n</span><span class="s2">|--------------|-------------|"</span>
|
||||
<span class="k">for</span> <span class="n">subst</span><span class="p">,</span> <span class="n">descr</span> <span class="ow">in</span> <span class="p">[</span>
|
||||
<span class="o">*</span><span class="n">TEMPLATE_SUBSTITUTIONS</span><span class="o">.</span><span class="n">items</span><span class="p">(),</span>
|
||||
<span class="o">*</span><span class="n">TEMPLATE_SUBSTITUTIONS_MULTI_VALUED</span><span class="o">.</span><span class="n">items</span><span class="p">(),</span>
|
||||
<span class="p">]:</span>
|
||||
<span class="c1"># replace '|' with '\|' to avoid markdown parsing issues (e.g. in {pipe} description)</span>
|
||||
<span class="n">descr</span> <span class="o">=</span> <span class="n">descr</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s2">"'|'"</span><span class="p">,</span> <span class="s2">"'\|'"</span><span class="p">)</span>
|
||||
<span class="n">template_table</span> <span class="o">+=</span> <span class="sa">f</span><span class="s2">"</span><span class="se">\n</span><span class="s2">|</span><span class="si">{</span><span class="n">subst</span><span class="si">}</span><span class="s2">|</span><span class="si">{</span><span class="n">descr</span><span class="si">}</span><span class="s2">|"</span>
|
||||
<span class="k">return</span> <span class="n">template_table</span>
|
||||
|
||||
|
||||
<span class="k">def</span> <span class="nf">_get_pathlib_value</span><span class="p">(</span><span class="n">field</span><span class="p">,</span> <span class="n">value</span><span class="p">,</span> <span class="n">quote</span><span class="p">):</span>
|
||||
<span class="sd">"""Get the value for a pathlib.Path type template</span>
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
osxphotos Command Line Interface (CLI)
|
||||
OSXPhotos Command Line Interface (CLI)
|
||||
======================================
|
||||
|
||||
.. click:: osxphotos.cli:cli_main
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
You can adapt this file completely to your liking, but it should at least
|
||||
contain the root `toctree` directive.
|
||||
|
||||
Welcome to osxphotos's documentation!
|
||||
Welcome to OSXPhotos's documentation!
|
||||
=====================================
|
||||
|
||||
.. toctree::
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
osxphotos
|
||||
OSXPhotos
|
||||
=========
|
||||
|
||||
What is osxphotos?
|
||||
What is OSXPhotos?
|
||||
------------------
|
||||
|
||||
osxphotos provides both the ability to interact with and query Apple's Photos.app library on macOS directly from your python code
|
||||
OSXPhotos provides both the ability to interact with and query Apple's Photos.app library on macOS directly from your python code
|
||||
as well as a very flexible command line interface (CLI) app for exporting photos.
|
||||
You can query the Photos library database -- for example, file name, file path, and metadata such as keywords/tags, persons/faces, albums, etc.
|
||||
You can also easily export both the original and edited photos.
|
||||
@@ -74,8 +74,10 @@ This package will install a command line utility called ``osxphotos`` that allow
|
||||
run Run a python file using same environment as osxphotos
|
||||
snap Create snapshot of Photos database to use with diff command
|
||||
theme Manage osxphotos color themes.
|
||||
timewarp Adjust date/time/timezone of photos in Apple Photos.
|
||||
tutorial Display osxphotos tutorial.
|
||||
uninstall Uninstall Python packages from the osxphotos environment
|
||||
uuid Print out unique IDs (UUID) of photos selected in Photos
|
||||
version Check for new version of osxphotos.
|
||||
|
||||
To get help on a specific command, use ``osxphotos help <command_name>``
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
OSXPhotos Python Package Overview
|
||||
=================================
|
||||
|
||||
Example uses of the python package
|
||||
----------------------------------
|
||||
Example uses of the OSXPhotos python package
|
||||
--------------------------------------------
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -116,4 +118,76 @@ Example uses of the python package
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
export()
|
||||
export()
|
||||
|
||||
|
||||
OSXPhotos REPL
|
||||
--------------
|
||||
|
||||
The osxphotos command line interface includes a REPL (Run-Evaluate-Print Loop) for testing and development.
|
||||
|
||||
The REPL is started with the command: ``osxphotos repl``::
|
||||
|
||||
$ osxphotos repl
|
||||
python version: 3.10.2 (main, Feb 2 2022, 07:36:01) [Clang 12.0.0 (clang-1200.0.32.29)]
|
||||
osxphotos version: 0.47.10
|
||||
Using last opened Photos library: /Users/user/Pictures/Photos Library.photoslibrary
|
||||
Loading database
|
||||
Processing database /Users/user/Pictures/Photos Library.photoslibrary/database/photos.db
|
||||
Processing database /Users/user/Pictures/Photos Library.photoslibrary/database/Photos.sqlite
|
||||
Database locked, creating temporary copy.
|
||||
Processing database.
|
||||
Database version: 6000, 5.
|
||||
Processing persons in photos.
|
||||
Processing detected faces in photos.
|
||||
Processing albums.
|
||||
Processing keywords.
|
||||
Processing photo details.
|
||||
Processing import sessions.
|
||||
Processing additional photo details.
|
||||
Processing face details.
|
||||
Processing photo labels.
|
||||
Processing EXIF details.
|
||||
Processing computed aesthetic scores.
|
||||
Processing comments and likes for shared photos.
|
||||
Processing moments.
|
||||
Done processing details from Photos library.
|
||||
Done: took 18.54 seconds
|
||||
Getting photos
|
||||
Found 31581 photos in 0.77 seconds
|
||||
|
||||
The following classes have been imported from osxphotos:
|
||||
- AlbumInfo, ExifTool, PhotoInfo, PhotoExporter, ExportOptions, ExportResults, PhotosDB, PlaceInfo, QueryOptions, MomentInfo, ScoreInfo, SearchInfo
|
||||
|
||||
The following variables are defined:
|
||||
- photosdb: PhotosDB() instance for '/Users/user/Pictures/Photos Library.photoslibrary'
|
||||
- photos: list of PhotoInfo objects for all photos filtered with any query options passed on command line (len=31581)
|
||||
- all_photos: list of PhotoInfo objects for all photos in photosdb, including those in the trash (len=31581)
|
||||
- selected: list of PhotoInfo objects for any photos selected in Photos (len=0)
|
||||
|
||||
The following functions may be helpful:
|
||||
- get_photo(uuid): return a PhotoInfo object for photo with uuid; e.g. get_photo('B13F4485-94E0-41CD-AF71-913095D62E31')
|
||||
- get_selected(); return list of PhotoInfo objects for photos selected in Photos
|
||||
- show(photo): open a photo object in the default viewer; e.g. show(selected[0])
|
||||
- show(path): open a file at path in the default viewer; e.g. show('/path/to/photo.jpg')
|
||||
- spotlight(photo): open a photo and spotlight it in Photos
|
||||
- inspect(object): print information about an object; e.g. inspect(PhotoInfo)
|
||||
- explore(object): interactively explore an object with objexplore; e.g. explore(PhotoInfo)
|
||||
- q, quit, quit(), exit, exit(): exit this interactive shell
|
||||
|
||||
>>>
|
||||
|
||||
Using the osxphotos CLI to run python code
|
||||
------------------------------------------
|
||||
|
||||
The osxphotos CLI can also be used to run your own python code using the ``osxphotos run`` command.
|
||||
|
||||
This is useful if you have installed the CLI using ``pipx`` but want to use the osxphotos programmatic interface in your own scripts.
|
||||
|
||||
If you need to install any additional python packages to use in your own scripts, you can use the ``osxphotos install`` command
|
||||
which installs python packages just as ``pip`` does but into the same virtual environment that osxphotos is installed in.
|
||||
|
||||
Likewise, you can use ``osxphotos uninstall`` to uninstall any installed python packages.
|
||||
|
||||
These features are also useful for developing custom functions to use with ``--query-function`` and ``--post-function``
|
||||
as well as ``{function}`` templates and ``function:`` filters.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
osxphotos python API
|
||||
OSXPhotos python API
|
||||
====================
|
||||
|
||||
.. automodule:: osxphotos
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
|
||||
osxphotos Template System
|
||||
OSXPhotos Template System
|
||||
=========================
|
||||
|
||||
The templating system converts one or template statements, written in osxphotos metadata templating language, to one or more rendered values using information from the photo being processed.
|
||||
The templating system converts one or template statements, written in osxphotos metadata templating language, to one or more rendered values using information from the photo being processed.
|
||||
|
||||
In its simplest form, a template statement has the form: ``"{template_field}"``\ , for example ``"{title}"`` which would resolve to the title of the photo.
|
||||
|
||||
@@ -26,7 +26,7 @@ e.g. if Photo keywords are ``["foo","bar"]``\ :
|
||||
* ``"{; +keyword}"`` renders to: ``"foo; bar"``
|
||||
* ``"{+keyword}"`` renders to ``"foobar"``
|
||||
|
||||
``template_field``\ : The template field to resolve. See `Template Substitutions <#template-substitutions>`_ for full list of template fields.
|
||||
``template_field``\ : The template field to resolve. See `Template Substitutions <#template-substitutions>`_ for full list of template fields.
|
||||
|
||||
`:subfield`: Some templates have sub-fields, For example, `{exiftool:IPTC:Make}\ ``; the template_field is``\ exiftool\ ``and the sub-field is``\ IPTC:Make`.
|
||||
|
||||
@@ -70,7 +70,7 @@ e.g. If Photo is in ``Album1`` in ``Folder1``\ :
|
||||
|
||||
`[find,replace]`: optional text replacement to perform on rendered template value. For example, to replace "/" in an album name, you could use the template `"{album[/,-]}"`. Multiple replacements can be made by appending "|" and adding another find|replace pair. e.g. to replace both "/" and ":" in album name: ``"{album[/,-|:,-]}"``. find/replace pairs are not limited to single characters. The "|" character cannot be used in a find/replace pair.
|
||||
|
||||
`conditional`: optional conditional expression that is evaluated as boolean (True/False) for use with the `?bool_value` modifier. Conditional expressions take the form '` not operator value`' where `not` is an optional modifier that negates the `operator`. Note: the space before the conditional expression is required if you use a conditional expression. Valid comparison operators are:
|
||||
`conditional`: optional conditional expression that is evaluated as boolean (True/False) for use with the `?bool_value` modifier. Conditional expressions take the form '`not operator value`' where `not` is an optional modifier that negates the `operator`. Note: the space before the conditional expression is required if you use a conditional expression. Valid comparison operators are:
|
||||
|
||||
|
||||
* ``contains``\ : template field contains value, similar to python's ``in``
|
||||
@@ -118,7 +118,7 @@ and if it is not an HDR image,
|
||||
|
||||
* ``"{hdr?ISHDR,NOTHDR}"`` renders to ``"NOTHDR"``
|
||||
|
||||
``,default``\ : optional default value to use if the template name has no value. This modifier is also used for the value if False for boolean-type fields (see above) as well as to hold a sub-template for values like ``{created.strftime}``. If no default value provided, "_" is used.
|
||||
``,default``\ : optional default value to use if the template name has no value. This modifier is also used for the value if False for boolean-type fields (see above) as well as to hold a sub-template for values like ``{created.strftime}``. If no default value provided, "_" is used.
|
||||
|
||||
e.g., if photo has no title set,
|
||||
|
||||
@@ -133,7 +133,7 @@ e.g., if photo date is 4 February 2020, 19:07:38,
|
||||
|
||||
* ``"{created.strftime,%Y-%m-%d-%H%M%S}"`` renders to ``"2020-02-04-190738"``
|
||||
|
||||
Some template fields such as ``"{media_type}"`` use the default value to allow customization of the output. For example, ``"{media_type}"`` resolves to the special media type of the photo such as ``panorama`` or ``selfie``. You may use the default value to override these in form: ``"{media_type,video=vidéo;time_lapse=vidéo_accélérée}"``. In this example, if photo was a time_lapse photo, ``media_type`` would resolve to ``vidéo_accélérée`` instead of ``time_lapse``.
|
||||
Some template fields such as ``"{media_type}"`` use the default value to allow customization of the output. For example, ``"{media_type}"`` resolves to the special media type of the photo such as ``panorama`` or ``selfie``. You may use the default value to override these in form: ``"{media_type,video=vidéo;time_lapse=vidéo_accélérée}"``. In this example, if photo was a time_lapse photo, ``media_type`` would resolve to ``vidéo_accélérée`` instead of ``time_lapse``.
|
||||
|
||||
Either or both bool_value or default (False value) may be empty which would result in empty string ``""`` when rendered.
|
||||
|
||||
@@ -147,7 +147,7 @@ Template Substitutions
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
|
||||
* - Substitution
|
||||
* - Field
|
||||
- Description
|
||||
* - {name}
|
||||
- Current filename of the photo
|
||||
@@ -281,6 +281,8 @@ Template Substitutions
|
||||
- Camera model from original photo's EXIF information as imported by Photos, e.g. 'iPhone 6s'
|
||||
* - {exif.lens_model}
|
||||
- Lens model from original photo's EXIF information as imported by Photos, e.g. 'iPhone 6s back camera 4.15mm f/2.2'
|
||||
* - {moment}
|
||||
- The moment title of the photo
|
||||
* - {uuid}
|
||||
- Photo's internal universally unique identifier (UUID) for the photo, a 36-character string unique to the photo, e.g. '128FB4C6-0B16-4E7D-9108-FB2E90DA1546'
|
||||
* - {id}
|
||||
@@ -318,7 +320,7 @@ Template Substitutions
|
||||
* - {crlf}
|
||||
- a carriage return + line feed: '\r\n'
|
||||
* - {osxphotos_version}
|
||||
- The osxphotos version, e.g. '0.47.10'
|
||||
- The osxphotos version, e.g. '0.48.2'
|
||||
* - {osxphotos_cmd_line}
|
||||
- The full command line used to run osxphotos
|
||||
* - {album}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
|
||||
|
||||
osxphotos Tutorial
|
||||
OSXPhotos Tutorial
|
||||
==================
|
||||
|
||||
Overview
|
||||
|
||||
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.47.10',
|
||||
VERSION: '0.48.2',
|
||||
LANGUAGE: 'None',
|
||||
COLLAPSE_INDEX: false,
|
||||
BUILDER: 'html',
|
||||
|
||||
199
docs/cli.html
199
docs/cli.html
@@ -3,10 +3,10 @@
|
||||
<head><meta charset="utf-8"/>
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1"/>
|
||||
<meta name="color-scheme" content="light dark"><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
||||
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="Example uses of the python package" href="package_overview.html" /><link rel="prev" title="osxphotos Tutorial" href="tutorial.html" />
|
||||
<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.47.10 documentation</title>
|
||||
<title>OSXPhotos Command Line Interface (CLI) - osxphotos 0.48.2 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=68f4518137b9aefe99b631505a2064c3c42c9852" />
|
||||
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
|
||||
@@ -124,7 +124,7 @@
|
||||
</label>
|
||||
</div>
|
||||
<div class="header-center">
|
||||
<a href="index.html"><div class="brand">osxphotos 0.47.10 documentation</div></a>
|
||||
<a href="index.html"><div class="brand">osxphotos 0.48.2 documentation</div></a>
|
||||
</div>
|
||||
<div class="header-right">
|
||||
<div class="theme-toggle-container theme-toggle-header">
|
||||
@@ -147,7 +147,7 @@
|
||||
<div class="sidebar-sticky"><a class="sidebar-brand" href="index.html">
|
||||
|
||||
|
||||
<span class="sidebar-brand-text">osxphotos 0.47.10 documentation</span>
|
||||
<span class="sidebar-brand-text">osxphotos 0.48.2 documentation</span>
|
||||
|
||||
</a><form class="sidebar-search-container" method="get" action="search.html" role="search">
|
||||
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
|
||||
@@ -156,11 +156,12 @@
|
||||
</form>
|
||||
<div id="searchbox"></div><div class="sidebar-scroll"><div class="sidebar-tree">
|
||||
<ul class="current">
|
||||
<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 current current-page"><a class="current reference internal" href="#">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 current current-page"><a class="current reference internal" href="#">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>
|
||||
@@ -194,16 +195,17 @@
|
||||
</div>
|
||||
<article role="main">
|
||||
<section id="osxphotos-command-line-interface-cli">
|
||||
<h1>osxphotos Command Line Interface (CLI)<a class="headerlink" href="#osxphotos-command-line-interface-cli" title="Permalink to this headline">#</a></h1>
|
||||
<h1>OSXPhotos Command Line Interface (CLI)<a class="headerlink" href="#osxphotos-command-line-interface-cli" title="Permalink to this headline">#</a></h1>
|
||||
<section id="osxphotos">
|
||||
<h2>osxphotos<a class="headerlink" href="#osxphotos" title="Permalink to this headline">#</a></h2>
|
||||
<p>osxphotos: query and export your Photos library</p>
|
||||
<div class="highlight-shell notranslate"><div class="highlight"><pre><span></span>osxphotos <span class="o">[</span>OPTIONS<span class="o">]</span> COMMAND <span class="o">[</span>ARGS<span class="o">]</span>...
|
||||
</pre></div>
|
||||
</div>
|
||||
<p class="rubric">Options</p>
|
||||
<dl class="std option">
|
||||
<dt class="sig sig-object std" id="cmdoption-osxphotos-db">
|
||||
<span class="sig-name descname"><span class="pre">--db</span></span><span class="sig-prename descclassname"> <span class="pre"><Photos</span> <span class="pre">database</span> <span class="pre">path></span></span><a class="headerlink" href="#cmdoption-osxphotos-db" title="Permalink to this definition">#</a></dt>
|
||||
<span class="sig-name descname"><span class="pre">--db</span></span><span class="sig-prename descclassname"> <span class="pre"><PHOTOS_LIBRARY_PATH></span></span><a class="headerlink" href="#cmdoption-osxphotos-db" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>Specify Photos database path. Path to Photos library/database can be specified using either –db or directly as PHOTOS_LIBRARY positional argument. If neither –db or PHOTOS_LIBRARY provided, will attempt to find the library to use in the following order: 1. last opened library, 2. system library, 3. ~/Pictures/Photos Library.photoslibrary</p>
|
||||
</dd></dl>
|
||||
<dl class="std option">
|
||||
@@ -232,7 +234,7 @@
|
||||
<p class="rubric">Options</p>
|
||||
<dl class="std option">
|
||||
<dt class="sig sig-object std" id="cmdoption-osxphotos-albums-db">
|
||||
<span class="sig-name descname"><span class="pre">--db</span></span><span class="sig-prename descclassname"> <span class="pre"><Photos</span> <span class="pre">database</span> <span class="pre">path></span></span><a class="headerlink" href="#cmdoption-osxphotos-albums-db" title="Permalink to this definition">#</a></dt>
|
||||
<span class="sig-name descname"><span class="pre">--db</span></span><span class="sig-prename descclassname"> <span class="pre"><PHOTOS_LIBRARY_PATH></span></span><a class="headerlink" href="#cmdoption-osxphotos-albums-db" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>Specify Photos database path. Path to Photos library/database can be specified using either –db or directly as PHOTOS_LIBRARY positional argument. If neither –db or PHOTOS_LIBRARY provided, will attempt to find the library to use in the following order: 1. last opened library, 2. system library, 3. ~/Pictures/Photos Library.photoslibrary</p>
|
||||
</dd></dl>
|
||||
<dl class="std option">
|
||||
@@ -275,7 +277,7 @@ library specified by –db to the database specified by DB2</p>
|
||||
<p class="rubric">Options</p>
|
||||
<dl class="std option">
|
||||
<dt class="sig sig-object std" id="cmdoption-osxphotos-diff-db">
|
||||
<span class="sig-name descname"><span class="pre">--db</span></span><span class="sig-prename descclassname"> <span class="pre"><Photos</span> <span class="pre">database</span> <span class="pre">path></span></span><a class="headerlink" href="#cmdoption-osxphotos-diff-db" title="Permalink to this definition">#</a></dt>
|
||||
<span class="sig-name descname"><span class="pre">--db</span></span><span class="sig-prename descclassname"> <span class="pre"><PHOTOS_LIBRARY_PATH></span></span><a class="headerlink" href="#cmdoption-osxphotos-diff-db" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>Specify Photos database path. Path to Photos library/database can be specified using either –db or directly as PHOTOS_LIBRARY positional argument. If neither –db or PHOTOS_LIBRARY provided, will attempt to find the library to use in the following order: 1. last opened library, 2. system library, 3. ~/Pictures/Photos Library.photoslibrary</p>
|
||||
</dd></dl>
|
||||
<dl class="std option">
|
||||
@@ -316,7 +318,7 @@ library specified by –db to the database specified by DB2</p>
|
||||
<p class="rubric">Options</p>
|
||||
<dl class="std option">
|
||||
<dt class="sig sig-object std" id="cmdoption-osxphotos-dump-db">
|
||||
<span class="sig-name descname"><span class="pre">--db</span></span><span class="sig-prename descclassname"> <span class="pre"><Photos</span> <span class="pre">database</span> <span class="pre">path></span></span><a class="headerlink" href="#cmdoption-osxphotos-dump-db" title="Permalink to this definition">#</a></dt>
|
||||
<span class="sig-name descname"><span class="pre">--db</span></span><span class="sig-prename descclassname"> <span class="pre"><PHOTOS_LIBRARY_PATH></span></span><a class="headerlink" href="#cmdoption-osxphotos-dump-db" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>Specify Photos database path. Path to Photos library/database can be specified using either –db or directly as PHOTOS_LIBRARY positional argument. If neither –db or PHOTOS_LIBRARY provided, will attempt to find the library to use in the following order: 1. last opened library, 2. system library, 3. ~/Pictures/Photos Library.photoslibrary</p>
|
||||
</dd></dl>
|
||||
<dl class="std option">
|
||||
@@ -359,7 +361,7 @@ to modify this behavior.</p>
|
||||
<p class="rubric">Options</p>
|
||||
<dl class="std option">
|
||||
<dt class="sig sig-object std" id="cmdoption-osxphotos-export-db">
|
||||
<span class="sig-name descname"><span class="pre">--db</span></span><span class="sig-prename descclassname"> <span class="pre"><Photos</span> <span class="pre">database</span> <span class="pre">path></span></span><a class="headerlink" href="#cmdoption-osxphotos-export-db" title="Permalink to this definition">#</a></dt>
|
||||
<span class="sig-name descname"><span class="pre">--db</span></span><span class="sig-prename descclassname"> <span class="pre"><PHOTOS_LIBRARY_PATH></span></span><a class="headerlink" href="#cmdoption-osxphotos-export-db" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>Specify Photos database path. Path to Photos library/database can be specified using either –db or directly as PHOTOS_LIBRARY positional argument. If neither –db or PHOTOS_LIBRARY provided, will attempt to find the library to use in the following order: 1. last opened library, 2. system library, 3. ~/Pictures/Photos Library.photoslibrary</p>
|
||||
</dd></dl>
|
||||
<dl class="std option">
|
||||
@@ -981,7 +983,7 @@ to modify this behavior.</p>
|
||||
</dd></dl>
|
||||
<dl class="std option">
|
||||
<dt class="sig sig-object std" id="cmdoption-osxphotos-export-report">
|
||||
<span class="sig-name descname"><span class="pre">--report</span></span><span class="sig-prename descclassname"> <span class="pre"><path</span> <span class="pre">to</span> <span class="pre">export</span> <span class="pre">report></span></span><a class="headerlink" href="#cmdoption-osxphotos-export-report" title="Permalink to this definition">#</a></dt>
|
||||
<span class="sig-name descname"><span class="pre">--report</span></span><span class="sig-prename descclassname"> <span class="pre"><REPORT_FILE></span></span><a class="headerlink" href="#cmdoption-osxphotos-export-report" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>Write a CSV formatted report of all files that were exported.</p>
|
||||
</dd></dl>
|
||||
<dl class="std option">
|
||||
@@ -1031,12 +1033,12 @@ to modify this behavior.</p>
|
||||
</dd></dl>
|
||||
<dl class="std option">
|
||||
<dt class="sig sig-object std" id="cmdoption-osxphotos-export-load-config">
|
||||
<span class="sig-name descname"><span class="pre">--load-config</span></span><span class="sig-prename descclassname"> <span class="pre"><config</span> <span class="pre">file</span> <span class="pre">path></span></span><a class="headerlink" href="#cmdoption-osxphotos-export-load-config" title="Permalink to this definition">#</a></dt>
|
||||
<span class="sig-name descname"><span class="pre">--load-config</span></span><span class="sig-prename descclassname"> <span class="pre"><CONFIG_FILE></span></span><a class="headerlink" href="#cmdoption-osxphotos-export-load-config" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>Load options from file as written with –save-config. This allows you to save a complex export command to file for later reuse. For example: ‘osxphotos export <lots of options here> –save-config osxphotos.toml’ then ‘osxphotos export /path/to/export –load-config osxphotos.toml’. If any other command line options are used in conjunction with –load-config, they will override the corresponding values in the config file.</p>
|
||||
</dd></dl>
|
||||
<dl class="std option">
|
||||
<dt class="sig sig-object std" id="cmdoption-osxphotos-export-save-config">
|
||||
<span class="sig-name descname"><span class="pre">--save-config</span></span><span class="sig-prename descclassname"> <span class="pre"><config</span> <span class="pre">file</span> <span class="pre">path></span></span><a class="headerlink" href="#cmdoption-osxphotos-export-save-config" title="Permalink to this definition">#</a></dt>
|
||||
<span class="sig-name descname"><span class="pre">--save-config</span></span><span class="sig-prename descclassname"> <span class="pre"><CONFIG_FILE></span></span><a class="headerlink" href="#cmdoption-osxphotos-export-save-config" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>Save options to file for use with –load-config. File format is TOML. See also –config-only.</p>
|
||||
</dd></dl>
|
||||
<dl class="std option">
|
||||
@@ -1093,7 +1095,7 @@ to modify this behavior.</p>
|
||||
<p class="rubric">Options</p>
|
||||
<dl class="std option">
|
||||
<dt class="sig sig-object std" id="cmdoption-osxphotos-info-db">
|
||||
<span class="sig-name descname"><span class="pre">--db</span></span><span class="sig-prename descclassname"> <span class="pre"><Photos</span> <span class="pre">database</span> <span class="pre">path></span></span><a class="headerlink" href="#cmdoption-osxphotos-info-db" title="Permalink to this definition">#</a></dt>
|
||||
<span class="sig-name descname"><span class="pre">--db</span></span><span class="sig-prename descclassname"> <span class="pre"><PHOTOS_LIBRARY_PATH></span></span><a class="headerlink" href="#cmdoption-osxphotos-info-db" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>Specify Photos database path. Path to Photos library/database can be specified using either –db or directly as PHOTOS_LIBRARY positional argument. If neither –db or PHOTOS_LIBRARY provided, will attempt to find the library to use in the following order: 1. last opened library, 2. system library, 3. ~/Pictures/Photos Library.photoslibrary</p>
|
||||
</dd></dl>
|
||||
<dl class="std option">
|
||||
@@ -1136,7 +1138,7 @@ to modify this behavior.</p>
|
||||
<p class="rubric">Options</p>
|
||||
<dl class="std option">
|
||||
<dt class="sig sig-object std" id="cmdoption-osxphotos-keywords-db">
|
||||
<span class="sig-name descname"><span class="pre">--db</span></span><span class="sig-prename descclassname"> <span class="pre"><Photos</span> <span class="pre">database</span> <span class="pre">path></span></span><a class="headerlink" href="#cmdoption-osxphotos-keywords-db" title="Permalink to this definition">#</a></dt>
|
||||
<span class="sig-name descname"><span class="pre">--db</span></span><span class="sig-prename descclassname"> <span class="pre"><PHOTOS_LIBRARY_PATH></span></span><a class="headerlink" href="#cmdoption-osxphotos-keywords-db" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>Specify Photos database path. Path to Photos library/database can be specified using either –db or directly as PHOTOS_LIBRARY positional argument. If neither –db or PHOTOS_LIBRARY provided, will attempt to find the library to use in the following order: 1. last opened library, 2. system library, 3. ~/Pictures/Photos Library.photoslibrary</p>
|
||||
</dd></dl>
|
||||
<dl class="std option">
|
||||
@@ -1160,7 +1162,7 @@ to modify this behavior.</p>
|
||||
<p class="rubric">Options</p>
|
||||
<dl class="std option">
|
||||
<dt class="sig sig-object std" id="cmdoption-osxphotos-labels-db">
|
||||
<span class="sig-name descname"><span class="pre">--db</span></span><span class="sig-prename descclassname"> <span class="pre"><Photos</span> <span class="pre">database</span> <span class="pre">path></span></span><a class="headerlink" href="#cmdoption-osxphotos-labels-db" title="Permalink to this definition">#</a></dt>
|
||||
<span class="sig-name descname"><span class="pre">--db</span></span><span class="sig-prename descclassname"> <span class="pre"><PHOTOS_LIBRARY_PATH></span></span><a class="headerlink" href="#cmdoption-osxphotos-labels-db" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>Specify Photos database path. Path to Photos library/database can be specified using either –db or directly as PHOTOS_LIBRARY positional argument. If neither –db or PHOTOS_LIBRARY provided, will attempt to find the library to use in the following order: 1. last opened library, 2. system library, 3. ~/Pictures/Photos Library.photoslibrary</p>
|
||||
</dd></dl>
|
||||
<dl class="std option">
|
||||
@@ -1197,7 +1199,7 @@ to modify this behavior.</p>
|
||||
<p class="rubric">Options</p>
|
||||
<dl class="std option">
|
||||
<dt class="sig sig-object std" id="cmdoption-osxphotos-persons-db">
|
||||
<span class="sig-name descname"><span class="pre">--db</span></span><span class="sig-prename descclassname"> <span class="pre"><Photos</span> <span class="pre">database</span> <span class="pre">path></span></span><a class="headerlink" href="#cmdoption-osxphotos-persons-db" title="Permalink to this definition">#</a></dt>
|
||||
<span class="sig-name descname"><span class="pre">--db</span></span><span class="sig-prename descclassname"> <span class="pre"><PHOTOS_LIBRARY_PATH></span></span><a class="headerlink" href="#cmdoption-osxphotos-persons-db" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>Specify Photos database path. Path to Photos library/database can be specified using either –db or directly as PHOTOS_LIBRARY positional argument. If neither –db or PHOTOS_LIBRARY provided, will attempt to find the library to use in the following order: 1. last opened library, 2. system library, 3. ~/Pictures/Photos Library.photoslibrary</p>
|
||||
</dd></dl>
|
||||
<dl class="std option">
|
||||
@@ -1221,7 +1223,7 @@ to modify this behavior.</p>
|
||||
<p class="rubric">Options</p>
|
||||
<dl class="std option">
|
||||
<dt class="sig sig-object std" id="cmdoption-osxphotos-places-db">
|
||||
<span class="sig-name descname"><span class="pre">--db</span></span><span class="sig-prename descclassname"> <span class="pre"><Photos</span> <span class="pre">database</span> <span class="pre">path></span></span><a class="headerlink" href="#cmdoption-osxphotos-places-db" title="Permalink to this definition">#</a></dt>
|
||||
<span class="sig-name descname"><span class="pre">--db</span></span><span class="sig-prename descclassname"> <span class="pre"><PHOTOS_LIBRARY_PATH></span></span><a class="headerlink" href="#cmdoption-osxphotos-places-db" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>Specify Photos database path. Path to Photos library/database can be specified using either –db or directly as PHOTOS_LIBRARY positional argument. If neither –db or PHOTOS_LIBRARY provided, will attempt to find the library to use in the following order: 1. last opened library, 2. system library, 3. ~/Pictures/Photos Library.photoslibrary</p>
|
||||
</dd></dl>
|
||||
<dl class="std option">
|
||||
@@ -1247,7 +1249,7 @@ if more than one option is provided, they are treated as “AND”
|
||||
<p class="rubric">Options</p>
|
||||
<dl class="std option">
|
||||
<dt class="sig sig-object std" id="cmdoption-osxphotos-query-db">
|
||||
<span class="sig-name descname"><span class="pre">--db</span></span><span class="sig-prename descclassname"> <span class="pre"><Photos</span> <span class="pre">database</span> <span class="pre">path></span></span><a class="headerlink" href="#cmdoption-osxphotos-query-db" title="Permalink to this definition">#</a></dt>
|
||||
<span class="sig-name descname"><span class="pre">--db</span></span><span class="sig-prename descclassname"> <span class="pre"><PHOTOS_LIBRARY_PATH></span></span><a class="headerlink" href="#cmdoption-osxphotos-query-db" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>Specify Photos database path. Path to Photos library/database can be specified using either –db or directly as PHOTOS_LIBRARY positional argument. If neither –db or PHOTOS_LIBRARY provided, will attempt to find the library to use in the following order: 1. last opened library, 2. system library, 3. ~/Pictures/Photos Library.photoslibrary</p>
|
||||
</dd></dl>
|
||||
<dl class="std option">
|
||||
@@ -1651,7 +1653,7 @@ if more than one option is provided, they are treated as “AND”
|
||||
<p class="rubric">Options</p>
|
||||
<dl class="std option">
|
||||
<dt class="sig sig-object std" id="cmdoption-osxphotos-repl-db">
|
||||
<span class="sig-name descname"><span class="pre">--db</span></span><span class="sig-prename descclassname"> <span class="pre"><Photos</span> <span class="pre">database</span> <span class="pre">path></span></span><a class="headerlink" href="#cmdoption-osxphotos-repl-db" title="Permalink to this definition">#</a></dt>
|
||||
<span class="sig-name descname"><span class="pre">--db</span></span><span class="sig-prename descclassname"> <span class="pre"><PHOTOS_LIBRARY_PATH></span></span><a class="headerlink" href="#cmdoption-osxphotos-repl-db" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>Specify Photos database path. Path to Photos library/database can be specified using either –db or directly as PHOTOS_LIBRARY positional argument. If neither –db or PHOTOS_LIBRARY provided, will attempt to find the library to use in the following order: 1. last opened library, 2. system library, 3. ~/Pictures/Photos Library.photoslibrary</p>
|
||||
</dd></dl>
|
||||
<dl class="std option">
|
||||
@@ -2061,7 +2063,7 @@ uses ‘/private/tmp/osxphotos_snapshots’</p>
|
||||
<p class="rubric">Options</p>
|
||||
<dl class="std option">
|
||||
<dt class="sig sig-object std" id="cmdoption-osxphotos-snap-db">
|
||||
<span class="sig-name descname"><span class="pre">--db</span></span><span class="sig-prename descclassname"> <span class="pre"><Photos</span> <span class="pre">database</span> <span class="pre">path></span></span><a class="headerlink" href="#cmdoption-osxphotos-snap-db" title="Permalink to this definition">#</a></dt>
|
||||
<span class="sig-name descname"><span class="pre">--db</span></span><span class="sig-prename descclassname"> <span class="pre"><PHOTOS_LIBRARY_PATH></span></span><a class="headerlink" href="#cmdoption-osxphotos-snap-db" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>Specify Photos database path. Path to Photos library/database can be specified using either –db or directly as PHOTOS_LIBRARY positional argument. If neither –db or PHOTOS_LIBRARY provided, will attempt to find the library to use in the following order: 1. last opened library, 2. system library, 3. ~/Pictures/Photos Library.photoslibrary</p>
|
||||
</dd></dl>
|
||||
</section>
|
||||
@@ -2108,6 +2110,128 @@ uses ‘/private/tmp/osxphotos_snapshots’</p>
|
||||
<dd><p>Delete THEME.</p>
|
||||
</dd></dl>
|
||||
</section>
|
||||
<section id="osxphotos-timewarp">
|
||||
<h3>timewarp<a class="headerlink" href="#osxphotos-timewarp" title="Permalink to this headline">#</a></h3>
|
||||
<p>Adjust date/time/timezone of photos in Apple Photos.</p>
|
||||
<p>Changes will be applied to all photos currently selected in Photos.
|
||||
timewarp cannot operate on photos selected in a Smart Album;
|
||||
select photos in a regular album or in the ‘All Photos’ view.
|
||||
See Timewarp Overview below for additional information.</p>
|
||||
<div class="highlight-shell notranslate"><div class="highlight"><pre><span></span>osxphotos timewarp <span class="o">[</span>OPTIONS<span class="o">]</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p class="rubric">Options</p>
|
||||
<dl class="std option">
|
||||
<dt class="sig sig-object std" id="cmdoption-osxphotos-timewarp-d">
|
||||
<span id="cmdoption-osxphotos-timewarp-date"></span><span class="sig-name descname"><span class="pre">-d</span></span><span class="sig-prename descclassname"></span><span class="sig-prename descclassname"><span class="pre">,</span> </span><span class="sig-name descname"><span class="pre">--date</span></span><span class="sig-prename descclassname"> <span class="pre"><DATE></span></span><a class="headerlink" href="#cmdoption-osxphotos-timewarp-d" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>Set date for selected photos. Format is ‘YYYY-MM-DD’.</p>
|
||||
</dd></dl>
|
||||
<dl class="std option">
|
||||
<dt class="sig sig-object std" id="cmdoption-osxphotos-timewarp-D">
|
||||
<span id="cmdoption-osxphotos-timewarp-date-delta"></span><span class="sig-name descname"><span class="pre">-D</span></span><span class="sig-prename descclassname"></span><span class="sig-prename descclassname"><span class="pre">,</span> </span><span class="sig-name descname"><span class="pre">--date-delta</span></span><span class="sig-prename descclassname"> <span class="pre"><DELTA></span></span><a class="headerlink" href="#cmdoption-osxphotos-timewarp-D" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>Adjust date for selected photos by DELTA. Format is one of: ‘±D days’, ‘±W weeks’, ‘±D’ where D is days</p>
|
||||
</dd></dl>
|
||||
<dl class="std option">
|
||||
<dt class="sig sig-object std" id="cmdoption-osxphotos-timewarp-t">
|
||||
<span id="cmdoption-osxphotos-timewarp-time"></span><span class="sig-name descname"><span class="pre">-t</span></span><span class="sig-prename descclassname"></span><span class="sig-prename descclassname"><span class="pre">,</span> </span><span class="sig-name descname"><span class="pre">--time</span></span><span class="sig-prename descclassname"> <span class="pre"><TIME></span></span><a class="headerlink" href="#cmdoption-osxphotos-timewarp-t" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>Set time for selected photos. Format is one of ‘HH:MM:SS’, ‘HH:MM:SS.fff’, ‘HH:MM’.</p>
|
||||
</dd></dl>
|
||||
<dl class="std option">
|
||||
<dt class="sig sig-object std" id="cmdoption-osxphotos-timewarp-T">
|
||||
<span id="cmdoption-osxphotos-timewarp-time-delta"></span><span class="sig-name descname"><span class="pre">-T</span></span><span class="sig-prename descclassname"></span><span class="sig-prename descclassname"><span class="pre">,</span> </span><span class="sig-name descname"><span class="pre">--time-delta</span></span><span class="sig-prename descclassname"> <span class="pre"><DELTA></span></span><a class="headerlink" href="#cmdoption-osxphotos-timewarp-T" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>Adjust time for selected photos by DELTA time. Format is one of ‘±HH:MM:SS’, ‘±H hours’ (or hr), ‘±M minutes’ (or min), ‘±S seconds’ (or sec), ‘±S’ (where S is seconds)</p>
|
||||
</dd></dl>
|
||||
<dl class="std option">
|
||||
<dt class="sig sig-object std" id="cmdoption-osxphotos-timewarp-z">
|
||||
<span id="cmdoption-osxphotos-timewarp-timezone"></span><span class="sig-name descname"><span class="pre">-z</span></span><span class="sig-prename descclassname"></span><span class="sig-prename descclassname"><span class="pre">,</span> </span><span class="sig-name descname"><span class="pre">--timezone</span></span><span class="sig-prename descclassname"> <span class="pre"><TIMEZONE></span></span><a class="headerlink" href="#cmdoption-osxphotos-timewarp-z" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>Set timezone for selected photos as offset from UTC. Format is one of ‘±HH:MM’, ‘±H:MM’, or ‘±HHMM’. The actual time of the photo is not adjusted which means, somewhat counterintuitively, that the time in the new timezone will be different. For example, if photo has time of 12:00 and timezone of GMT+01:00 and new timezone is specified as ‘–timezone +02:00’ (one hour ahead of current GMT+01:00 timezone), the photo’s new time will be 13:00 GMT+02:00, which is equivalent to the old time of 12:00+01:00. This is the same behavior exhibited by Photos when manually adjusting timezone in the Get Info window. See also –match-time.</p>
|
||||
</dd></dl>
|
||||
<dl class="std option">
|
||||
<dt class="sig sig-object std" id="cmdoption-osxphotos-timewarp-i">
|
||||
<span id="cmdoption-osxphotos-timewarp-inspect"></span><span class="sig-name descname"><span class="pre">-i</span></span><span class="sig-prename descclassname"></span><span class="sig-prename descclassname"><span class="pre">,</span> </span><span class="sig-name descname"><span class="pre">--inspect</span></span><span class="sig-prename descclassname"></span><a class="headerlink" href="#cmdoption-osxphotos-timewarp-i" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>Print out the date/time/timezone for each selected photo without changing any information.</p>
|
||||
</dd></dl>
|
||||
<dl class="std option">
|
||||
<dt class="sig sig-object std" id="cmdoption-osxphotos-timewarp-c">
|
||||
<span id="cmdoption-osxphotos-timewarp-compare-exif"></span><span class="sig-name descname"><span class="pre">-c</span></span><span class="sig-prename descclassname"></span><span class="sig-prename descclassname"><span class="pre">,</span> </span><span class="sig-name descname"><span class="pre">--compare-exif</span></span><span class="sig-prename descclassname"></span><a class="headerlink" href="#cmdoption-osxphotos-timewarp-c" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>Compare the EXIF date/time/timezone for each selected photo to the same data in Photos. Requires the third-party exiftool utility be installed (see <a class="reference external" href="https://exiftool.org/">https://exiftool.org/</a>). See also –add-to-album.</p>
|
||||
</dd></dl>
|
||||
<dl class="std option">
|
||||
<dt class="sig sig-object std" id="cmdoption-osxphotos-timewarp-p">
|
||||
<span id="cmdoption-osxphotos-timewarp-push-exif"></span><span class="sig-name descname"><span class="pre">-p</span></span><span class="sig-prename descclassname"></span><span class="sig-prename descclassname"><span class="pre">,</span> </span><span class="sig-name descname"><span class="pre">--push-exif</span></span><span class="sig-prename descclassname"></span><a class="headerlink" href="#cmdoption-osxphotos-timewarp-p" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>Push date/time and timezone for selected photos from Photos to the EXIF metadata in the original file in the Photos library. Requires the third-party exiftool utility be installed (see <a class="reference external" href="https://exiftool.org/">https://exiftool.org/</a>). Using this option modifies the <em>original</em> file of the image in your Photos library. –push-exif will be executed after any other updates are performed on the photo. See also –pull-exif.</p>
|
||||
</dd></dl>
|
||||
<dl class="std option">
|
||||
<dt class="sig sig-object std" id="cmdoption-osxphotos-timewarp-P">
|
||||
<span id="cmdoption-osxphotos-timewarp-pull-exif"></span><span class="sig-name descname"><span class="pre">-P</span></span><span class="sig-prename descclassname"></span><span class="sig-prename descclassname"><span class="pre">,</span> </span><span class="sig-name descname"><span class="pre">--pull-exif</span></span><span class="sig-prename descclassname"></span><a class="headerlink" href="#cmdoption-osxphotos-timewarp-P" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>Pull date/time and timezone for selected photos from EXIF metadata in the original file into Photos and update the associated data in Photos to match the EXIF data. –pull-exif will be executed before any other updates are performed on the photo. It is possible for images to have missing EXIF data, for example the date/time could be set but there might be no timezone set in the EXIF metadata. Missing data will be handled thusly: if date/time/timezone are all present in the EXIF data, the photo’s date/time/timezone will be updated. If timezone is missing but date/time is present, only the photo’s date/time will be updated. If date/time is missing but the timezone is present, only the photo’s timezone will be updated unless –use-file-time is set in which case, the photo’s file modification date/time will be used in place of EXIF date/time. If the date is present but the time is missing, the time will be set to 00:00:00. Requires the third-party exiftool utility be installed (see <a class="reference external" href="https://exiftool.org/">https://exiftool.org/</a>). See also –push-exif.</p>
|
||||
</dd></dl>
|
||||
<dl class="std option">
|
||||
<dt class="sig sig-object std" id="cmdoption-osxphotos-timewarp-F">
|
||||
<span id="cmdoption-osxphotos-timewarp-f"></span><span id="cmdoption-osxphotos-timewarp-function"></span><span class="sig-name descname"><span class="pre">-F</span></span><span class="sig-prename descclassname"></span><span class="sig-prename descclassname"><span class="pre">,</span> </span><span class="sig-name descname"><span class="pre">--function</span></span><span class="sig-prename descclassname"> <span class="pre"><filename.py::function></span></span><a class="headerlink" href="#cmdoption-osxphotos-timewarp-F" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>Run python function to determine the date/time/timezone to apply to a photo. Use this in format: –function filename.py::function where filename.py is a python file you’ve created and function is the name of the function in the python file you want to call. The function will be passed information about the photo being processed and is expected to return a naive datetime.datetime object with time in local time and UTC timezone offset in seconds. See example function at https://github.com/RhetTbull/osxphotos/blob/master/examples/timewarp_function_example.py</p>
|
||||
</dd></dl>
|
||||
<dl class="std option">
|
||||
<dt class="sig sig-object std" id="cmdoption-osxphotos-timewarp-m">
|
||||
<span id="cmdoption-osxphotos-timewarp-match-time"></span><span class="sig-name descname"><span class="pre">-m</span></span><span class="sig-prename descclassname"></span><span class="sig-prename descclassname"><span class="pre">,</span> </span><span class="sig-name descname"><span class="pre">--match-time</span></span><span class="sig-prename descclassname"></span><a class="headerlink" href="#cmdoption-osxphotos-timewarp-m" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>When used with –timezone, adjusts the photo time so that the timestamp in the new timezone matches the timestamp in the old timezone. For example, if photo has time of 12:00 and timezone of GMT+01:00 and new timezone is specified as ‘–timezone +02:00’ (one hour ahead of current GMT+01:00 timezone), the photo’s new time will be 12:00 GMT+02:00. That is, the timezone will have changed but the timestamp of the photo will match the previous timestamp. Use –match-time when the camera’s time was correct for the time the photo was taken but the timezone was missing or wrong and you want to adjust the timezone while preserving the photo’s time. See also –timezone.</p>
|
||||
</dd></dl>
|
||||
<dl class="std option">
|
||||
<dt class="sig sig-object std" id="cmdoption-osxphotos-timewarp-0">
|
||||
<span id="cmdoption-osxphotos-timewarp-use-file-time"></span><span class="sig-name descname"><span class="pre">-f</span></span><span class="sig-prename descclassname"></span><span class="sig-prename descclassname"><span class="pre">,</span> </span><span class="sig-name descname"><span class="pre">--use-file-time</span></span><span class="sig-prename descclassname"></span><a class="headerlink" href="#cmdoption-osxphotos-timewarp-0" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>When used with –pull-exif, the file modification date/time will be used if date/time is missing from the EXIF data.</p>
|
||||
</dd></dl>
|
||||
<dl class="std option">
|
||||
<dt class="sig sig-object std" id="cmdoption-osxphotos-timewarp-a">
|
||||
<span id="cmdoption-osxphotos-timewarp-add-to-album"></span><span class="sig-name descname"><span class="pre">-a</span></span><span class="sig-prename descclassname"></span><span class="sig-prename descclassname"><span class="pre">,</span> </span><span class="sig-name descname"><span class="pre">--add-to-album</span></span><span class="sig-prename descclassname"> <span class="pre"><ALBUM></span></span><a class="headerlink" href="#cmdoption-osxphotos-timewarp-a" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>When used with –compare-exif, adds any photos with date/time/timezone differences between Photos/EXIF to album ALBUM. If ALBUM does not exist, it will be created.</p>
|
||||
</dd></dl>
|
||||
<dl class="std option">
|
||||
<dt class="sig sig-object std" id="cmdoption-osxphotos-timewarp-V">
|
||||
<span id="cmdoption-osxphotos-timewarp-v"></span><span id="cmdoption-osxphotos-timewarp-verbose"></span><span class="sig-name descname"><span class="pre">-V</span></span><span class="sig-prename descclassname"></span><span class="sig-prename descclassname"><span class="pre">,</span> </span><span class="sig-name descname"><span class="pre">--verbose</span></span><span class="sig-prename descclassname"></span><a class="headerlink" href="#cmdoption-osxphotos-timewarp-V" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>Show verbose output.</p>
|
||||
</dd></dl>
|
||||
<dl class="std option">
|
||||
<dt class="sig sig-object std" id="cmdoption-osxphotos-timewarp-L">
|
||||
<span id="cmdoption-osxphotos-timewarp-l"></span><span id="cmdoption-osxphotos-timewarp-library"></span><span class="sig-name descname"><span class="pre">-L</span></span><span class="sig-prename descclassname"></span><span class="sig-prename descclassname"><span class="pre">,</span> </span><span class="sig-name descname"><span class="pre">--library</span></span><span class="sig-prename descclassname"> <span class="pre"><PHOTOS_LIBRARY_PATH></span></span><a class="headerlink" href="#cmdoption-osxphotos-timewarp-L" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>Path to Photos library (e.g. ‘~/Pictures/PhotosLibrary.photoslibrary’). This is not likely needed as osxphotos will usually be able to locate the path to the open Photos library. Use –library only if you get an error that the Photos library cannot be located.</p>
|
||||
</dd></dl>
|
||||
<dl class="std option">
|
||||
<dt class="sig sig-object std" id="cmdoption-osxphotos-timewarp-e">
|
||||
<span id="cmdoption-osxphotos-timewarp-exiftool-path"></span><span class="sig-name descname"><span class="pre">-e</span></span><span class="sig-prename descclassname"></span><span class="sig-prename descclassname"><span class="pre">,</span> </span><span class="sig-name descname"><span class="pre">--exiftool-path</span></span><span class="sig-prename descclassname"> <span class="pre"><exiftool_path></span></span><a class="headerlink" href="#cmdoption-osxphotos-timewarp-e" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>Optional path to exiftool executable (will look in $PATH if not specified) for those options which require exiftool.</p>
|
||||
</dd></dl>
|
||||
<dl class="std option">
|
||||
<dt class="sig sig-object std" id="cmdoption-osxphotos-timewarp-o">
|
||||
<span id="cmdoption-osxphotos-timewarp-output-file"></span><span class="sig-name descname"><span class="pre">-o</span></span><span class="sig-prename descclassname"></span><span class="sig-prename descclassname"><span class="pre">,</span> </span><span class="sig-name descname"><span class="pre">--output-file</span></span><span class="sig-prename descclassname"> <span class="pre"><output_file></span></span><a class="headerlink" href="#cmdoption-osxphotos-timewarp-o" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>Output file. If not specified, output is written to stdout.</p>
|
||||
</dd></dl>
|
||||
<dl class="std option">
|
||||
<dt class="sig sig-object std" id="cmdoption-osxphotos-timewarp-timestamp">
|
||||
<span class="sig-name descname"><span class="pre">--timestamp</span></span><span class="sig-prename descclassname"></span><a class="headerlink" href="#cmdoption-osxphotos-timewarp-timestamp" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>Add time stamp to verbose output</p>
|
||||
</dd></dl>
|
||||
<dl class="std option">
|
||||
<dt class="sig sig-object std" id="cmdoption-osxphotos-timewarp-theme">
|
||||
<span class="sig-name descname"><span class="pre">--theme</span></span><span class="sig-prename descclassname"> <span class="pre"><THEME></span></span><a class="headerlink" href="#cmdoption-osxphotos-timewarp-theme" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>Specify the color theme to use for –verbose output. Valid themes are ‘dark’, ‘light’, ‘mono’, and ‘plain’. Defaults to ‘dark’ or ‘light’ depending on system dark mode setting.</p>
|
||||
<dl class="field-list simple">
|
||||
<dt class="field-odd">Options</dt>
|
||||
<dd class="field-odd"><p>dark | light | mono | plain</p>
|
||||
</dd>
|
||||
</dl>
|
||||
</dd></dl>
|
||||
<dl class="std option">
|
||||
<dt class="sig sig-object std" id="cmdoption-osxphotos-timewarp-plain">
|
||||
<span class="sig-name descname"><span class="pre">--plain</span></span><span class="sig-prename descclassname"></span><a class="headerlink" href="#cmdoption-osxphotos-timewarp-plain" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>Plain text mode. Do not use rich output.</p>
|
||||
</dd></dl>
|
||||
<dl class="std option">
|
||||
<dt class="sig sig-object std" id="cmdoption-osxphotos-timewarp-force">
|
||||
<span class="sig-name descname"><span class="pre">--force</span></span><span class="sig-prename descclassname"></span><a class="headerlink" href="#cmdoption-osxphotos-timewarp-force" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>Bypass confirmation prompt. Use with caution.</p>
|
||||
</dd></dl>
|
||||
</section>
|
||||
<section id="osxphotos-tutorial">
|
||||
<h3>tutorial<a class="headerlink" href="#osxphotos-tutorial" title="Permalink to this headline">#</a></h3>
|
||||
<p>Display osxphotos tutorial.</p>
|
||||
@@ -2154,6 +2278,19 @@ uses ‘/private/tmp/osxphotos_snapshots’</p>
|
||||
<dd><p>Include filename of selected photos in output</p>
|
||||
</dd></dl>
|
||||
</section>
|
||||
<section id="osxphotos-version">
|
||||
<h3>version<a class="headerlink" href="#osxphotos-version" title="Permalink to this headline">#</a></h3>
|
||||
<p>Check for new version of osxphotos.</p>
|
||||
<div class="highlight-shell notranslate"><div class="highlight"><pre><span></span>osxphotos version <span class="o">[</span>OPTIONS<span class="o">]</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p class="rubric">Options</p>
|
||||
<dl class="std option">
|
||||
<dt class="sig sig-object std" id="cmdoption-osxphotos-version-run">
|
||||
<span class="sig-name descname"><span class="pre">--run</span></span><span class="sig-prename descclassname"> <span class="pre"><COMMAND></span></span><a class="headerlink" href="#cmdoption-osxphotos-version-run" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>Run COMMAND if there is a new version of osxphotos available.</p>
|
||||
</dd></dl>
|
||||
</section>
|
||||
</section>
|
||||
<div class="highlight-text notranslate"><div class="highlight"><pre><span></span>Usage: python -m osxphotos [OPTIONS] COMMAND [ARGS]...
|
||||
|
||||
@@ -2201,12 +2338,12 @@ Commands:
|
||||
<footer>
|
||||
|
||||
<div class="related-pages">
|
||||
<a class="next-page" href="package_overview.html">
|
||||
<a class="next-page" href="template_help.html">
|
||||
<div class="page-info">
|
||||
<div class="context">
|
||||
<span>Next</span>
|
||||
</div>
|
||||
<div class="title">Example uses of the python package</div>
|
||||
<div class="title">OSXPhotos Template System</div>
|
||||
</div>
|
||||
<svg><use href="#svg-arrow-right"></use></svg>
|
||||
</a>
|
||||
@@ -2217,7 +2354,7 @@ Commands:
|
||||
<span>Previous</span>
|
||||
</div>
|
||||
|
||||
<div class="title">osxphotos Tutorial</div>
|
||||
<div class="title">OSXPhotos Tutorial</div>
|
||||
|
||||
</div>
|
||||
</a>
|
||||
@@ -2253,7 +2390,7 @@ Commands:
|
||||
<div class="toc-tree-container">
|
||||
<div class="toc-tree">
|
||||
<ul>
|
||||
<li><a class="reference internal" href="#">osxphotos Command Line Interface (CLI)</a><ul>
|
||||
<li><a class="reference internal" href="#">OSXPhotos Command Line Interface (CLI)</a><ul>
|
||||
<li><a class="reference internal" href="#osxphotos">osxphotos</a><ul>
|
||||
<li><a class="reference internal" href="#osxphotos-about">about</a></li>
|
||||
<li><a class="reference internal" href="#osxphotos-albums">albums</a></li>
|
||||
@@ -2274,9 +2411,11 @@ Commands:
|
||||
<li><a class="reference internal" href="#osxphotos-run">run</a></li>
|
||||
<li><a class="reference internal" href="#osxphotos-snap">snap</a></li>
|
||||
<li><a class="reference internal" href="#osxphotos-theme">theme</a></li>
|
||||
<li><a class="reference internal" href="#osxphotos-timewarp">timewarp</a></li>
|
||||
<li><a class="reference internal" href="#osxphotos-tutorial">tutorial</a></li>
|
||||
<li><a class="reference internal" href="#osxphotos-uninstall">uninstall</a></li>
|
||||
<li><a class="reference internal" href="#osxphotos-uuid">uuid</a></li>
|
||||
<li><a class="reference internal" href="#osxphotos-version">version</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -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.47.10 documentation</title>
|
||||
<meta name="generator" content="sphinx-4.4.0, furo 2022.04.07"/><title>Index - osxphotos 0.48.2 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=68f4518137b9aefe99b631505a2064c3c42c9852" />
|
||||
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
|
||||
@@ -122,7 +122,7 @@
|
||||
</label>
|
||||
</div>
|
||||
<div class="header-center">
|
||||
<a href="index.html"><div class="brand">osxphotos 0.47.10 documentation</div></a>
|
||||
<a href="index.html"><div class="brand">osxphotos 0.48.2 documentation</div></a>
|
||||
</div>
|
||||
<div class="header-right">
|
||||
<div class="theme-toggle-container theme-toggle-header">
|
||||
@@ -145,7 +145,7 @@
|
||||
<div class="sidebar-sticky"><a class="sidebar-brand" href="index.html">
|
||||
|
||||
|
||||
<span class="sidebar-brand-text">osxphotos 0.47.10 documentation</span>
|
||||
<span class="sidebar-brand-text">osxphotos 0.48.2 documentation</span>
|
||||
|
||||
</a><form class="sidebar-search-container" method="get" action="search.html" role="search">
|
||||
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
|
||||
@@ -154,12 +154,12 @@
|
||||
</form>
|
||||
<div id="searchbox"></div><div class="sidebar-scroll"><div class="sidebar-tree">
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="overview.html">osxphotos</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="tutorial.html">osxphotos Tutorial</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="cli.html">osxphotos Command Line Interface (CLI)</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="template_help.html">osxphotos Template System</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="package_overview.html">Example uses of the python package</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="reference.html">osxphotos python API</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="overview.html">OSXPhotos</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="tutorial.html">OSXPhotos Tutorial</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="cli.html">OSXPhotos Command Line Interface (CLI)</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="template_help.html">OSXPhotos Template System</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="package_overview.html">OSXPhotos Python Package Overview</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="reference.html">OSXPhotos python API</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
@@ -227,6 +227,8 @@
|
||||
|
||||
<ul>
|
||||
<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>
|
||||
@@ -279,6 +281,13 @@
|
||||
<li><a href="cli.html#cmdoption-osxphotos-query-cloudasset">osxphotos-query command line option</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-repl-cloudasset">osxphotos-repl command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
--compare-exif
|
||||
|
||||
<ul>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-c">osxphotos-timewarp command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
@@ -307,6 +316,20 @@
|
||||
|
||||
<ul>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-export-current-name">osxphotos-export command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
--date
|
||||
|
||||
<ul>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-d">osxphotos-timewarp command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
--date-delta
|
||||
|
||||
<ul>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-D">osxphotos-timewarp command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
@@ -506,6 +529,8 @@
|
||||
|
||||
<ul>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-export-exiftool-path">osxphotos-export command line option</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-e">osxphotos-timewarp command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
@@ -583,6 +608,13 @@
|
||||
<li><a href="cli.html#cmdoption-osxphotos-query-folder">osxphotos-query command line option</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-repl-folder">osxphotos-repl command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
--force
|
||||
|
||||
<ul>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-force">osxphotos-timewarp command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
@@ -612,6 +644,13 @@
|
||||
<li><a href="cli.html#cmdoption-osxphotos-query-from-time">osxphotos-query command line option</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-repl-from-time">osxphotos-repl command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
--function
|
||||
|
||||
<ul>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-F">osxphotos-timewarp command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
@@ -712,6 +751,13 @@
|
||||
<li><a href="cli.html#cmdoption-osxphotos-query-incloud">osxphotos-query command line option</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-repl-incloud">osxphotos-repl command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
--inspect
|
||||
|
||||
<ul>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-i">osxphotos-timewarp command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
@@ -791,6 +837,13 @@
|
||||
<li><a href="cli.html#cmdoption-osxphotos-query-label">osxphotos-query command line option</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-repl-label">osxphotos-repl command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
--library
|
||||
|
||||
<ul>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-L">osxphotos-timewarp command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
@@ -827,6 +880,13 @@
|
||||
<li><a href="cli.html#cmdoption-osxphotos-query-location">osxphotos-query command line option</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-repl-location">osxphotos-repl command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
--match-time
|
||||
|
||||
<ul>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-m">osxphotos-timewarp command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
@@ -935,8 +995,6 @@
|
||||
<li><a href="cli.html#cmdoption-osxphotos-export-no-progress">osxphotos-export command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
</ul></td>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li>
|
||||
--no-title
|
||||
|
||||
@@ -990,6 +1048,8 @@
|
||||
<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
|
||||
|
||||
@@ -1152,6 +1212,13 @@
|
||||
|
||||
<ul>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-export-original-suffix">osxphotos-export command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
--output-file
|
||||
|
||||
<ul>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-o">osxphotos-timewarp command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
@@ -1199,6 +1266,13 @@
|
||||
<li><a href="cli.html#cmdoption-osxphotos-query-place">osxphotos-query command line option</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-repl-place">osxphotos-repl command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
--plain
|
||||
|
||||
<ul>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-plain">osxphotos-timewarp command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
@@ -1247,6 +1321,20 @@
|
||||
|
||||
<ul>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-export-preview-suffix">osxphotos-export command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
--pull-exif
|
||||
|
||||
<ul>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-P">osxphotos-timewarp command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
--push-exif
|
||||
|
||||
<ul>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-p">osxphotos-timewarp command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
@@ -1315,6 +1403,13 @@
|
||||
|
||||
<ul>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-export-retry">osxphotos-export command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
--run
|
||||
|
||||
<ul>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-version-run">osxphotos-version command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
@@ -1461,6 +1556,22 @@
|
||||
|
||||
<ul>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-export-theme">osxphotos-export command line option</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-theme">osxphotos-timewarp command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
--time
|
||||
|
||||
<ul>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-t">osxphotos-timewarp command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
--time-delta
|
||||
|
||||
<ul>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-T">osxphotos-timewarp command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
@@ -1479,6 +1590,15 @@
|
||||
|
||||
<ul>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-export-timestamp">osxphotos-export command line option</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-timestamp">osxphotos-timewarp command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
--timezone
|
||||
|
||||
<ul>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-z">osxphotos-timewarp command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
@@ -1540,6 +1660,13 @@
|
||||
|
||||
<ul>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-install-U">osxphotos-install command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
--use-file-time
|
||||
|
||||
<ul>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-0">osxphotos-timewarp command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
@@ -1596,6 +1723,8 @@
|
||||
<li><a href="cli.html#cmdoption-osxphotos-diff-V">osxphotos-diff command line option</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-export-V">osxphotos-export command line option</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-V">osxphotos-timewarp command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
@@ -1628,12 +1757,56 @@
|
||||
|
||||
<ul>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-uninstall-y">osxphotos-uninstall command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
-a
|
||||
|
||||
<ul>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-a">osxphotos-timewarp command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
-c
|
||||
|
||||
<ul>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-c">osxphotos-timewarp command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
-D
|
||||
|
||||
<ul>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-D">osxphotos-timewarp command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
-d
|
||||
|
||||
<ul>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-d">osxphotos-timewarp command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
-e
|
||||
|
||||
<ul>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-e">osxphotos-timewarp command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
-F
|
||||
|
||||
<ul>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-F">osxphotos-timewarp command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
-f
|
||||
|
||||
<ul>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-0">osxphotos-timewarp command line option</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-uuid-f">osxphotos-uuid command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
@@ -1646,6 +1819,43 @@
|
||||
<li><a href="cli.html#cmdoption-osxphotos-query-i">osxphotos-query command line option</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-repl-i">osxphotos-repl command line option</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-i">osxphotos-timewarp command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
-L
|
||||
|
||||
<ul>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-L">osxphotos-timewarp command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
-m
|
||||
|
||||
<ul>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-m">osxphotos-timewarp command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
-o
|
||||
|
||||
<ul>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-o">osxphotos-timewarp command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
-P
|
||||
|
||||
<ul>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-P">osxphotos-timewarp command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
-p
|
||||
|
||||
<ul>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-p">osxphotos-timewarp command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
@@ -1660,6 +1870,20 @@
|
||||
|
||||
<ul>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-diff-s">osxphotos-diff command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
-T
|
||||
|
||||
<ul>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-T">osxphotos-timewarp command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
-t
|
||||
|
||||
<ul>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-t">osxphotos-timewarp command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
@@ -1676,6 +1900,8 @@
|
||||
<li><a href="cli.html#cmdoption-osxphotos-diff-V">osxphotos-diff command line option</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-export-V">osxphotos-export command line option</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-V">osxphotos-timewarp command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
@@ -1690,6 +1916,13 @@
|
||||
|
||||
<ul>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-uninstall-y">osxphotos-uninstall command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
-z
|
||||
|
||||
<ul>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-z">osxphotos-timewarp command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
</ul></td>
|
||||
@@ -1743,6 +1976,8 @@
|
||||
<li><a href="reference.html#osxphotos.ExifTool.asdict">asdict() (osxphotos.ExifTool method)</a>
|
||||
|
||||
<ul>
|
||||
<li><a href="reference.html#osxphotos.MomentInfo.asdict">(osxphotos.MomentInfo method)</a>
|
||||
</li>
|
||||
<li><a href="reference.html#osxphotos.PersonInfo.asdict">(osxphotos.PersonInfo method)</a>
|
||||
</li>
|
||||
<li><a href="reference.html#osxphotos.PhotoInfo.asdict">(osxphotos.PhotoInfo method)</a>
|
||||
@@ -2255,7 +2490,7 @@
|
||||
<li><a href="reference.html#module-osxphotos">osxphotos</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li><a href="reference.html#osxphotos.PhotoInfo.moment">moment (osxphotos.PhotoInfo property)</a>
|
||||
<li><a href="reference.html#osxphotos.PhotoInfo.moment_info">moment_info (osxphotos.PhotoInfo property)</a>
|
||||
</li>
|
||||
<li><a href="reference.html#osxphotos.MomentInfo">MomentInfo (class in osxphotos)</a>
|
||||
</li>
|
||||
@@ -2746,8 +2981,6 @@
|
||||
<li><a href="cli.html#cmdoption-osxphotos-labels-arg-PHOTOS_LIBRARY">PHOTOS_LIBRARY</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
</ul></td>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li>
|
||||
osxphotos-list command line option
|
||||
|
||||
@@ -2942,6 +3175,8 @@
|
||||
<li><a href="cli.html#cmdoption-osxphotos-query-arg-PHOTOS_LIBRARY">PHOTOS_LIBRARY</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
</ul></td>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li>
|
||||
osxphotos-repl command line option
|
||||
|
||||
@@ -3134,6 +3369,87 @@
|
||||
<li><a href="cli.html#cmdoption-osxphotos-theme-list">--list</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-theme-preview">--preview</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
osxphotos-timewarp command line option
|
||||
|
||||
<ul>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-a">--add-to-album</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-c">--compare-exif</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-d">--date</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-D">--date-delta</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-e">--exiftool-path</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-force">--force</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-F">--function</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-i">--inspect</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-L">--library</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-m">--match-time</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-o">--output-file</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-plain">--plain</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-P">--pull-exif</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-p">--push-exif</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-theme">--theme</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-t">--time</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-T">--time-delta</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-timestamp">--timestamp</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-z">--timezone</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-0">--use-file-time</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-V">--verbose</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-a">-a</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-c">-c</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-d">-d</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-D">-D</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-e">-e</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-F">-F</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-0">-f</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-i">-i</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-L">-L</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-m">-m</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-o">-o</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-p">-p</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-P">-P</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-t">-t</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-T">-T</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-V">-V</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-timewarp-z">-z</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
@@ -3161,6 +3477,13 @@
|
||||
<li><a href="cli.html#cmdoption-osxphotos-uuid-f">--filename</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-uuid-f">-f</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
osxphotos-version command line option
|
||||
|
||||
<ul>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-version-run">--run</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li><a href="reference.html#osxphotos.ExportOptions.overwrite">overwrite (osxphotos.ExportOptions attribute)</a>
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
<head><meta charset="utf-8"/>
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1"/>
|
||||
<meta name="color-scheme" content="light dark"><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
||||
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="osxphotos" href="overview.html" />
|
||||
<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.47.10 documentation</title>
|
||||
<title>osxphotos 0.48.2 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=68f4518137b9aefe99b631505a2064c3c42c9852" />
|
||||
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
|
||||
@@ -124,7 +124,7 @@
|
||||
</label>
|
||||
</div>
|
||||
<div class="header-center">
|
||||
<a href="#"><div class="brand">osxphotos 0.47.10 documentation</div></a>
|
||||
<a href="#"><div class="brand">osxphotos 0.48.2 documentation</div></a>
|
||||
</div>
|
||||
<div class="header-right">
|
||||
<div class="theme-toggle-container theme-toggle-header">
|
||||
@@ -147,7 +147,7 @@
|
||||
<div class="sidebar-sticky"><a class="sidebar-brand" href="#">
|
||||
|
||||
|
||||
<span class="sidebar-brand-text">osxphotos 0.47.10 documentation</span>
|
||||
<span class="sidebar-brand-text">osxphotos 0.48.2 documentation</span>
|
||||
|
||||
</a><form class="sidebar-search-container" method="get" action="search.html" role="search">
|
||||
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
|
||||
@@ -156,12 +156,12 @@
|
||||
</form>
|
||||
<div id="searchbox"></div><div class="sidebar-scroll"><div class="sidebar-tree">
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="overview.html">osxphotos</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="tutorial.html">osxphotos Tutorial</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="cli.html">osxphotos Command Line Interface (CLI)</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="template_help.html">osxphotos Template System</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="package_overview.html">Example uses of the python package</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="reference.html">osxphotos python API</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="overview.html">OSXPhotos</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="tutorial.html">OSXPhotos Tutorial</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="cli.html">OSXPhotos Command Line Interface (CLI)</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="template_help.html">OSXPhotos Template System</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="package_overview.html">OSXPhotos Python Package Overview</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="reference.html">OSXPhotos python API</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
@@ -195,17 +195,17 @@
|
||||
</div>
|
||||
<article role="main">
|
||||
<section id="welcome-to-osxphotos-s-documentation">
|
||||
<h1>Welcome to osxphotos’s documentation!<a class="headerlink" href="#welcome-to-osxphotos-s-documentation" title="Permalink to this headline">#</a></h1>
|
||||
<h1>Welcome to OSXPhotos’s documentation!<a class="headerlink" href="#welcome-to-osxphotos-s-documentation" title="Permalink to this headline">#</a></h1>
|
||||
<div class="toctree-wrapper compound">
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="overview.html">osxphotos</a><ul>
|
||||
<li class="toctree-l2"><a class="reference internal" href="overview.html#what-is-osxphotos">What is osxphotos?</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="overview.html">OSXPhotos</a><ul>
|
||||
<li class="toctree-l2"><a class="reference internal" href="overview.html#what-is-osxphotos">What is OSXPhotos?</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="overview.html#supported-operating-systems">Supported operating systems</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="overview.html#installation">Installation</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="overview.html#command-line-usage">Command Line Usage</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="tutorial.html">osxphotos Tutorial</a><ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="tutorial.html">OSXPhotos Tutorial</a><ul>
|
||||
<li class="toctree-l2"><a class="reference internal" href="tutorial.html#overview">Overview</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="tutorial.html#export-your-photos">Export your photos</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="tutorial.html#export-by-date">Export by date</a></li>
|
||||
@@ -230,7 +230,7 @@
|
||||
<li class="toctree-l2"><a class="reference internal" href="tutorial.html#conclusion">Conclusion</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="cli.html">osxphotos Command Line Interface (CLI)</a><ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="cli.html">OSXPhotos Command Line Interface (CLI)</a><ul>
|
||||
<li class="toctree-l2"><a class="reference internal" href="cli.html#osxphotos">osxphotos</a><ul>
|
||||
<li class="toctree-l3"><a class="reference internal" href="cli.html#osxphotos-about">about</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="cli.html#osxphotos-albums">albums</a></li>
|
||||
@@ -251,19 +251,26 @@
|
||||
<li class="toctree-l3"><a class="reference internal" href="cli.html#osxphotos-run">run</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="cli.html#osxphotos-snap">snap</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="cli.html#osxphotos-theme">theme</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="cli.html#osxphotos-timewarp">timewarp</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="cli.html#osxphotos-tutorial">tutorial</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="cli.html#osxphotos-uninstall">uninstall</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="cli.html#osxphotos-uuid">uuid</a></li>
|
||||
<li class="toctree-l3"><a class="reference internal" href="cli.html#osxphotos-version">version</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="template_help.html">osxphotos Template System</a><ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="template_help.html">OSXPhotos Template System</a><ul>
|
||||
<li class="toctree-l2"><a class="reference internal" href="template_help.html#id1">Template Substitutions</a></li>
|
||||
</ul>
|
||||
</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="package_overview.html">OSXPhotos Python Package Overview</a><ul>
|
||||
<li class="toctree-l2"><a class="reference internal" href="package_overview.html#example-uses-of-the-osxphotos-python-package">Example uses of the OSXPhotos python package</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="package_overview.html#osxphotos-repl">OSXPhotos REPL</a></li>
|
||||
<li class="toctree-l2"><a class="reference internal" href="package_overview.html#using-the-osxphotos-cli-to-run-python-code">Using the osxphotos CLI to run python code</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="reference.html">OSXPhotos python API</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
@@ -286,7 +293,7 @@
|
||||
<div class="context">
|
||||
<span>Next</span>
|
||||
</div>
|
||||
<div class="title">osxphotos</div>
|
||||
<div class="title">OSXPhotos</div>
|
||||
</div>
|
||||
<svg><use href="#svg-arrow-right"></use></svg>
|
||||
</a>
|
||||
@@ -323,7 +330,7 @@
|
||||
<div class="toc-tree-container">
|
||||
<div class="toc-tree">
|
||||
<ul>
|
||||
<li><a class="reference internal" href="#">Welcome to osxphotos’s documentation!</a></li>
|
||||
<li><a class="reference internal" href="#">Welcome to OSXPhotos’s documentation!</a></li>
|
||||
<li><a class="reference internal" href="#indices-and-tables">Indices and tables</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
BIN
docs/objects.inv
BIN
docs/objects.inv
Binary file not shown.
@@ -3,10 +3,10 @@
|
||||
<head><meta charset="utf-8"/>
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1"/>
|
||||
<meta name="color-scheme" content="light dark"><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
||||
<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" />
|
||||
<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.47.10 documentation</title>
|
||||
<title>OSXPhotos - osxphotos 0.48.2 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=68f4518137b9aefe99b631505a2064c3c42c9852" />
|
||||
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
|
||||
@@ -124,7 +124,7 @@
|
||||
</label>
|
||||
</div>
|
||||
<div class="header-center">
|
||||
<a href="index.html"><div class="brand">osxphotos 0.47.10 documentation</div></a>
|
||||
<a href="index.html"><div class="brand">osxphotos 0.48.2 documentation</div></a>
|
||||
</div>
|
||||
<div class="header-right">
|
||||
<div class="theme-toggle-container theme-toggle-header">
|
||||
@@ -147,7 +147,7 @@
|
||||
<div class="sidebar-sticky"><a class="sidebar-brand" href="index.html">
|
||||
|
||||
|
||||
<span class="sidebar-brand-text">osxphotos 0.47.10 documentation</span>
|
||||
<span class="sidebar-brand-text">osxphotos 0.48.2 documentation</span>
|
||||
|
||||
</a><form class="sidebar-search-container" method="get" action="search.html" role="search">
|
||||
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
|
||||
@@ -156,11 +156,12 @@
|
||||
</form>
|
||||
<div id="searchbox"></div><div class="sidebar-scroll"><div class="sidebar-tree">
|
||||
<ul class="current">
|
||||
<li class="toctree-l1 current current-page"><a class="current reference internal" href="#">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 current current-page"><a class="current reference internal" href="#">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>
|
||||
@@ -194,10 +195,10 @@
|
||||
</div>
|
||||
<article role="main">
|
||||
<section id="osxphotos">
|
||||
<h1>osxphotos<a class="headerlink" href="#osxphotos" title="Permalink to this headline">#</a></h1>
|
||||
<h1>OSXPhotos<a class="headerlink" href="#osxphotos" title="Permalink to this headline">#</a></h1>
|
||||
<section id="what-is-osxphotos">
|
||||
<h2>What is osxphotos?<a class="headerlink" href="#what-is-osxphotos" title="Permalink to this headline">#</a></h2>
|
||||
<p>osxphotos provides both the ability to interact with and query Apple’s Photos.app library on macOS directly from your python code
|
||||
<h2>What is OSXPhotos?<a class="headerlink" href="#what-is-osxphotos" title="Permalink to this headline">#</a></h2>
|
||||
<p>OSXPhotos provides both the ability to interact with and query Apple’s Photos.app library on macOS directly from your python code
|
||||
as well as a very flexible command line interface (CLI) app for exporting photos.
|
||||
You can query the Photos library database – for example, file name, file path, and metadata such as keywords/tags, persons/faces, albums, etc.
|
||||
You can also easily export both the original and edited photos.</p>
|
||||
@@ -259,9 +260,11 @@ E.g. you can read a database created with Photos 5.0 on MacOS 10.15 on a machine
|
||||
<span class="n">run</span> <span class="n">Run</span> <span class="n">a</span> <span class="n">python</span> <span class="n">file</span> <span class="n">using</span> <span class="n">same</span> <span class="n">environment</span> <span class="k">as</span> <span class="n">osxphotos</span>
|
||||
<span class="n">snap</span> <span class="n">Create</span> <span class="n">snapshot</span> <span class="n">of</span> <span class="n">Photos</span> <span class="n">database</span> <span class="n">to</span> <span class="n">use</span> <span class="k">with</span> <span class="n">diff</span> <span class="n">command</span>
|
||||
<span class="n">theme</span> <span class="n">Manage</span> <span class="n">osxphotos</span> <span class="n">color</span> <span class="n">themes</span><span class="o">.</span>
|
||||
<span class="n">timewarp</span> <span class="n">Adjust</span> <span class="n">date</span><span class="o">/</span><span class="n">time</span><span class="o">/</span><span class="n">timezone</span> <span class="n">of</span> <span class="n">photos</span> <span class="ow">in</span> <span class="n">Apple</span> <span class="n">Photos</span><span class="o">.</span>
|
||||
<span class="n">tutorial</span> <span class="n">Display</span> <span class="n">osxphotos</span> <span class="n">tutorial</span><span class="o">.</span>
|
||||
<span class="n">uninstall</span> <span class="n">Uninstall</span> <span class="n">Python</span> <span class="n">packages</span> <span class="kn">from</span> <span class="nn">the</span> <span class="n">osxphotos</span> <span class="n">environment</span>
|
||||
<span class="n">uuid</span> <span class="n">Print</span> <span class="n">out</span> <span class="n">unique</span> <span class="n">IDs</span> <span class="p">(</span><span class="n">UUID</span><span class="p">)</span> <span class="n">of</span> <span class="n">photos</span> <span class="n">selected</span> <span class="ow">in</span> <span class="n">Photos</span>
|
||||
<span class="n">version</span> <span class="n">Check</span> <span class="k">for</span> <span class="n">new</span> <span class="n">version</span> <span class="n">of</span> <span class="n">osxphotos</span><span class="o">.</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
<p>To get help on a specific command, use <code class="docutils literal notranslate"><span class="pre">osxphotos</span> <span class="pre">help</span> <span class="pre"><command_name></span></code></p>
|
||||
@@ -278,7 +281,7 @@ E.g. you can read a database created with Photos 5.0 on MacOS 10.15 on a machine
|
||||
<div class="context">
|
||||
<span>Next</span>
|
||||
</div>
|
||||
<div class="title">osxphotos Tutorial</div>
|
||||
<div class="title">OSXPhotos Tutorial</div>
|
||||
</div>
|
||||
<svg><use href="#svg-arrow-right"></use></svg>
|
||||
</a>
|
||||
@@ -325,8 +328,8 @@ E.g. you can read a database created with Photos 5.0 on MacOS 10.15 on a machine
|
||||
<div class="toc-tree-container">
|
||||
<div class="toc-tree">
|
||||
<ul>
|
||||
<li><a class="reference internal" href="#">osxphotos</a><ul>
|
||||
<li><a class="reference internal" href="#what-is-osxphotos">What is osxphotos?</a></li>
|
||||
<li><a class="reference internal" href="#">OSXPhotos</a><ul>
|
||||
<li><a class="reference internal" href="#what-is-osxphotos">What is OSXPhotos?</a></li>
|
||||
<li><a class="reference internal" href="#supported-operating-systems">Supported operating systems</a></li>
|
||||
<li><a class="reference internal" href="#installation">Installation</a></li>
|
||||
<li><a class="reference internal" href="#command-line-usage">Command Line Usage</a></li>
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
<head><meta charset="utf-8"/>
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1"/>
|
||||
<meta name="color-scheme" content="light dark"><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
||||
<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 Command Line Interface (CLI)" href="cli.html" />
|
||||
<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>Example uses of the python package - osxphotos 0.47.10 documentation</title>
|
||||
<title>OSXPhotos Python Package Overview - osxphotos 0.48.2 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=68f4518137b9aefe99b631505a2064c3c42c9852" />
|
||||
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
|
||||
@@ -124,7 +124,7 @@
|
||||
</label>
|
||||
</div>
|
||||
<div class="header-center">
|
||||
<a href="index.html"><div class="brand">osxphotos 0.47.10 documentation</div></a>
|
||||
<a href="index.html"><div class="brand">osxphotos 0.48.2 documentation</div></a>
|
||||
</div>
|
||||
<div class="header-right">
|
||||
<div class="theme-toggle-container theme-toggle-header">
|
||||
@@ -135,7 +135,7 @@
|
||||
<svg class="theme-icon-when-light"><use href="#svg-sun"></use></svg>
|
||||
</button>
|
||||
</div>
|
||||
<label class="toc-overlay-icon toc-header-icon no-toc" for="__toc">
|
||||
<label class="toc-overlay-icon toc-header-icon" for="__toc">
|
||||
<div class="visually-hidden">Toggle table of contents sidebar</div>
|
||||
<i class="icon"><svg><use href="#svg-toc"></use></svg></i>
|
||||
</label>
|
||||
@@ -147,7 +147,7 @@
|
||||
<div class="sidebar-sticky"><a class="sidebar-brand" href="index.html">
|
||||
|
||||
|
||||
<span class="sidebar-brand-text">osxphotos 0.47.10 documentation</span>
|
||||
<span class="sidebar-brand-text">osxphotos 0.48.2 documentation</span>
|
||||
|
||||
</a><form class="sidebar-search-container" method="get" action="search.html" role="search">
|
||||
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
|
||||
@@ -156,11 +156,12 @@
|
||||
</form>
|
||||
<div id="searchbox"></div><div class="sidebar-scroll"><div class="sidebar-tree">
|
||||
<ul class="current">
|
||||
<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 current current-page"><a class="current reference internal" href="#">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 current current-page"><a class="current reference internal" href="#">OSXPhotos Python Package Overview</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="reference.html">OSXPhotos python API</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
@@ -187,14 +188,16 @@
|
||||
<svg class="theme-icon-when-light"><use href="#svg-sun"></use></svg>
|
||||
</button>
|
||||
</div>
|
||||
<label class="toc-overlay-icon toc-content-icon no-toc" for="__toc">
|
||||
<label class="toc-overlay-icon toc-content-icon" for="__toc">
|
||||
<div class="visually-hidden">Toggle table of contents sidebar</div>
|
||||
<i class="icon"><svg><use href="#svg-toc"></use></svg></i>
|
||||
</label>
|
||||
</div>
|
||||
<article role="main">
|
||||
<section id="example-uses-of-the-python-package">
|
||||
<h1>Example uses of the python package<a class="headerlink" href="#example-uses-of-the-python-package" title="Permalink to this headline">#</a></h1>
|
||||
<section id="osxphotos-python-package-overview">
|
||||
<h1>OSXPhotos Python Package Overview<a class="headerlink" href="#osxphotos-python-package-overview" title="Permalink to this headline">#</a></h1>
|
||||
<section id="example-uses-of-the-osxphotos-python-package">
|
||||
<h2>Example uses of the OSXPhotos python package<a class="headerlink" href="#example-uses-of-the-osxphotos-python-package" title="Permalink to this headline">#</a></h2>
|
||||
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="sd">""" Simple usage of the package """</span>
|
||||
<span class="kn">import</span> <span class="nn">osxphotos</span>
|
||||
|
||||
@@ -309,6 +312,72 @@
|
||||
<span class="n">export</span><span class="p">()</span>
|
||||
</pre></div>
|
||||
</div>
|
||||
</section>
|
||||
<section id="osxphotos-repl">
|
||||
<h2>OSXPhotos REPL<a class="headerlink" href="#osxphotos-repl" title="Permalink to this headline">#</a></h2>
|
||||
<p>The osxphotos command line interface includes a REPL (Run-Evaluate-Print Loop) for testing and development.</p>
|
||||
<p>The REPL is started with the command: <code class="docutils literal notranslate"><span class="pre">osxphotos</span> <span class="pre">repl</span></code>:</p>
|
||||
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span>$ osxphotos repl
|
||||
python version: 3.10.2 (main, Feb 2 2022, 07:36:01) [Clang 12.0.0 (clang-1200.0.32.29)]
|
||||
osxphotos version: 0.47.10
|
||||
Using last opened Photos library: /Users/user/Pictures/Photos Library.photoslibrary
|
||||
Loading database
|
||||
Processing database /Users/user/Pictures/Photos Library.photoslibrary/database/photos.db
|
||||
Processing database /Users/user/Pictures/Photos Library.photoslibrary/database/Photos.sqlite
|
||||
Database locked, creating temporary copy.
|
||||
Processing database.
|
||||
Database version: 6000, 5.
|
||||
Processing persons in photos.
|
||||
Processing detected faces in photos.
|
||||
Processing albums.
|
||||
Processing keywords.
|
||||
Processing photo details.
|
||||
Processing import sessions.
|
||||
Processing additional photo details.
|
||||
Processing face details.
|
||||
Processing photo labels.
|
||||
Processing EXIF details.
|
||||
Processing computed aesthetic scores.
|
||||
Processing comments and likes for shared photos.
|
||||
Processing moments.
|
||||
Done processing details from Photos library.
|
||||
Done: took 18.54 seconds
|
||||
Getting photos
|
||||
Found 31581 photos in 0.77 seconds
|
||||
|
||||
The following classes have been imported from osxphotos:
|
||||
- AlbumInfo, ExifTool, PhotoInfo, PhotoExporter, ExportOptions, ExportResults, PhotosDB, PlaceInfo, QueryOptions, MomentInfo, ScoreInfo, SearchInfo
|
||||
|
||||
The following variables are defined:
|
||||
- photosdb: PhotosDB() instance for '/Users/user/Pictures/Photos Library.photoslibrary'
|
||||
- photos: list of PhotoInfo objects for all photos filtered with any query options passed on command line (len=31581)
|
||||
- all_photos: list of PhotoInfo objects for all photos in photosdb, including those in the trash (len=31581)
|
||||
- selected: list of PhotoInfo objects for any photos selected in Photos (len=0)
|
||||
|
||||
The following functions may be helpful:
|
||||
- get_photo(uuid): return a PhotoInfo object for photo with uuid; e.g. get_photo('B13F4485-94E0-41CD-AF71-913095D62E31')
|
||||
- get_selected(); return list of PhotoInfo objects for photos selected in Photos
|
||||
- show(photo): open a photo object in the default viewer; e.g. show(selected[0])
|
||||
- show(path): open a file at path in the default viewer; e.g. show('/path/to/photo.jpg')
|
||||
- spotlight(photo): open a photo and spotlight it in Photos
|
||||
- inspect(object): print information about an object; e.g. inspect(PhotoInfo)
|
||||
- explore(object): interactively explore an object with objexplore; e.g. explore(PhotoInfo)
|
||||
- q, quit, quit(), exit, exit(): exit this interactive shell
|
||||
|
||||
>>>
|
||||
</pre></div>
|
||||
</div>
|
||||
</section>
|
||||
<section id="using-the-osxphotos-cli-to-run-python-code">
|
||||
<h2>Using the osxphotos CLI to run python code<a class="headerlink" href="#using-the-osxphotos-cli-to-run-python-code" title="Permalink to this headline">#</a></h2>
|
||||
<p>The osxphotos CLI can also be used to run your own python code using the <code class="docutils literal notranslate"><span class="pre">osxphotos</span> <span class="pre">run</span></code> command.</p>
|
||||
<p>This is useful if you have installed the CLI using <code class="docutils literal notranslate"><span class="pre">pipx</span></code> but want to use the osxphotos programmatic interface in your own scripts.</p>
|
||||
<p>If you need to install any additional python packages to use in your own scripts, you can use the <code class="docutils literal notranslate"><span class="pre">osxphotos</span> <span class="pre">install</span></code> command
|
||||
which installs python packages just as <code class="docutils literal notranslate"><span class="pre">pip</span></code> does but into the same virtual environment that osxphotos is installed in.</p>
|
||||
<p>Likewise, you can use <code class="docutils literal notranslate"><span class="pre">osxphotos</span> <span class="pre">uninstall</span></code> to uninstall any installed python packages.</p>
|
||||
<p>These features are also useful for developing custom functions to use with <code class="docutils literal notranslate"><span class="pre">--query-function</span></code> and <code class="docutils literal notranslate"><span class="pre">--post-function</span></code>
|
||||
as well as <code class="docutils literal notranslate"><span class="pre">{function}</span></code> templates and <code class="docutils literal notranslate"><span class="pre">function:</span></code> filters.</p>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
</article>
|
||||
@@ -321,18 +390,18 @@
|
||||
<div class="context">
|
||||
<span>Next</span>
|
||||
</div>
|
||||
<div class="title">osxphotos python API</div>
|
||||
<div class="title">OSXPhotos python API</div>
|
||||
</div>
|
||||
<svg><use href="#svg-arrow-right"></use></svg>
|
||||
</a>
|
||||
<a class="prev-page" href="cli.html">
|
||||
<a class="prev-page" href="template_help.html">
|
||||
<svg><use href="#svg-arrow-right"></use></svg>
|
||||
<div class="page-info">
|
||||
<div class="context">
|
||||
<span>Previous</span>
|
||||
</div>
|
||||
|
||||
<div class="title">osxphotos Command Line Interface (CLI)</div>
|
||||
<div class="title">OSXPhotos Template System</div>
|
||||
|
||||
</div>
|
||||
</a>
|
||||
@@ -356,9 +425,30 @@
|
||||
|
||||
</footer>
|
||||
</div>
|
||||
<aside class="toc-drawer no-toc">
|
||||
<aside class="toc-drawer">
|
||||
|
||||
|
||||
<div class="toc-sticky toc-scroll">
|
||||
<div class="toc-title-container">
|
||||
<span class="toc-title">
|
||||
Contents
|
||||
</span>
|
||||
</div>
|
||||
<div class="toc-tree-container">
|
||||
<div class="toc-tree">
|
||||
<ul>
|
||||
<li><a class="reference internal" href="#">OSXPhotos Python Package Overview</a><ul>
|
||||
<li><a class="reference internal" href="#example-uses-of-the-osxphotos-python-package">Example uses of the OSXPhotos python package</a></li>
|
||||
<li><a class="reference internal" href="#osxphotos-repl">OSXPhotos REPL</a></li>
|
||||
<li><a class="reference internal" href="#using-the-osxphotos-cli-to-run-python-code">Using the osxphotos CLI to run python code</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</aside>
|
||||
</div>
|
||||
|
||||
@@ -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.47.10 documentation</title>
|
||||
<meta name="generator" content="sphinx-4.4.0, furo 2022.04.07"/><title>Python Module Index - osxphotos 0.48.2 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=68f4518137b9aefe99b631505a2064c3c42c9852" />
|
||||
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
|
||||
@@ -122,7 +122,7 @@
|
||||
</label>
|
||||
</div>
|
||||
<div class="header-center">
|
||||
<a href="index.html"><div class="brand">osxphotos 0.47.10 documentation</div></a>
|
||||
<a href="index.html"><div class="brand">osxphotos 0.48.2 documentation</div></a>
|
||||
</div>
|
||||
<div class="header-right">
|
||||
<div class="theme-toggle-container theme-toggle-header">
|
||||
@@ -145,7 +145,7 @@
|
||||
<div class="sidebar-sticky"><a class="sidebar-brand" href="index.html">
|
||||
|
||||
|
||||
<span class="sidebar-brand-text">osxphotos 0.47.10 documentation</span>
|
||||
<span class="sidebar-brand-text">osxphotos 0.48.2 documentation</span>
|
||||
|
||||
</a><form class="sidebar-search-container" method="get" action="search.html" role="search">
|
||||
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
|
||||
@@ -154,12 +154,12 @@
|
||||
</form>
|
||||
<div id="searchbox"></div><div class="sidebar-scroll"><div class="sidebar-tree">
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="overview.html">osxphotos</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="tutorial.html">osxphotos Tutorial</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="cli.html">osxphotos Command Line Interface (CLI)</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="template_help.html">osxphotos Template System</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="package_overview.html">Example uses of the python package</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="reference.html">osxphotos python API</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="overview.html">OSXPhotos</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="tutorial.html">OSXPhotos Tutorial</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="cli.html">OSXPhotos Command Line Interface (CLI)</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="template_help.html">OSXPhotos Template System</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="package_overview.html">OSXPhotos Python Package Overview</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="reference.html">OSXPhotos python API</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
<head><meta charset="utf-8"/>
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1"/>
|
||||
<meta name="color-scheme" content="light dark"><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
||||
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="prev" title="Example uses of the python package" href="package_overview.html" />
|
||||
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="prev" title="OSXPhotos Python Package Overview" href="package_overview.html" />
|
||||
|
||||
<meta name="generator" content="sphinx-4.4.0, furo 2022.04.07"/>
|
||||
<title>osxphotos python API - osxphotos 0.47.10 documentation</title>
|
||||
<title>OSXPhotos python API - osxphotos 0.48.2 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=68f4518137b9aefe99b631505a2064c3c42c9852" />
|
||||
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
|
||||
@@ -124,7 +124,7 @@
|
||||
</label>
|
||||
</div>
|
||||
<div class="header-center">
|
||||
<a href="index.html"><div class="brand">osxphotos 0.47.10 documentation</div></a>
|
||||
<a href="index.html"><div class="brand">osxphotos 0.48.2 documentation</div></a>
|
||||
</div>
|
||||
<div class="header-right">
|
||||
<div class="theme-toggle-container theme-toggle-header">
|
||||
@@ -147,7 +147,7 @@
|
||||
<div class="sidebar-sticky"><a class="sidebar-brand" href="index.html">
|
||||
|
||||
|
||||
<span class="sidebar-brand-text">osxphotos 0.47.10 documentation</span>
|
||||
<span class="sidebar-brand-text">osxphotos 0.48.2 documentation</span>
|
||||
|
||||
</a><form class="sidebar-search-container" method="get" action="search.html" role="search">
|
||||
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
|
||||
@@ -156,11 +156,12 @@
|
||||
</form>
|
||||
<div id="searchbox"></div><div class="sidebar-scroll"><div class="sidebar-tree">
|
||||
<ul class="current">
|
||||
<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 current current-page"><a class="current reference internal" href="#">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 current current-page"><a class="current reference internal" href="#">OSXPhotos python API</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
@@ -194,7 +195,7 @@
|
||||
</div>
|
||||
<article role="main">
|
||||
<section id="module-osxphotos">
|
||||
<span id="osxphotos-python-api"></span><h1>osxphotos python API<a class="headerlink" href="#module-osxphotos" title="Permalink to this headline">#</a></h1>
|
||||
<span id="osxphotos-python-api"></span><h1>OSXPhotos python API<a class="headerlink" href="#module-osxphotos" title="Permalink to this headline">#</a></h1>
|
||||
<dl class="py class">
|
||||
<dt class="sig sig-object py" id="osxphotos.AlbumInfo">
|
||||
<em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">osxphotos.</span></span><span class="sig-name descname"><span class="pre">AlbumInfo</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">db</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">uuid</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/osxphotos/albuminfo.html#AlbumInfo"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#osxphotos.AlbumInfo" title="Permalink to this definition">#</a></dt>
|
||||
@@ -395,7 +396,7 @@ If called in context manager, returns True (execution is delayed until exiting c
|
||||
<dt class="sig sig-object py" id="osxphotos.ExportDB.get_file_record">
|
||||
<span class="sig-name descname"><span class="pre">get_file_record</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">filename</span></span><span class="p"><span class="pre">:</span></span><span class="w"> </span><span class="n"><span class="pre">Union</span><span class="p"><span class="pre">[</span></span><span class="pre">pathlib.Path</span><span class="p"><span class="pre">,</span></span><span class="w"> </span><span class="pre">str</span><span class="p"><span class="pre">]</span></span></span></em><span class="sig-paren">)</span> <span class="sig-return"><span class="sig-return-icon">→</span> <span class="sig-return-typehint"><span class="pre">osxphotos.export_db.ExportRecord</span></span></span><a class="reference internal" href="_modules/osxphotos/export_db.html#ExportDB.get_file_record"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#osxphotos.ExportDB.get_file_record" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>get info for filename and uuid</p>
|
||||
<p>Returns: an ExportRecord object</p>
|
||||
<p>Returns: an ExportRecord object or None if filename not found</p>
|
||||
</dd></dl>
|
||||
<dl class="py method">
|
||||
<dt class="sig sig-object py" id="osxphotos.ExportDB.get_photoinfo_for_uuid">
|
||||
@@ -1030,6 +1031,11 @@ including folders, albums, etc</p>
|
||||
<dt class="sig sig-object py" id="osxphotos.MomentInfo">
|
||||
<em class="property"><span class="pre">class</span><span class="w"> </span></em><span class="sig-prename descclassname"><span class="pre">osxphotos.</span></span><span class="sig-name descname"><span class="pre">MomentInfo</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">db</span></span></em>, <em class="sig-param"><span class="n"><span class="pre">moment_pk</span></span></em><span class="sig-paren">)</span><a class="reference internal" href="_modules/osxphotos/momentinfo.html#MomentInfo"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#osxphotos.MomentInfo" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>Info about a photo moment</p>
|
||||
<dl class="py method">
|
||||
<dt class="sig sig-object py" id="osxphotos.MomentInfo.asdict">
|
||||
<span class="sig-name descname"><span class="pre">asdict</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="reference internal" href="_modules/osxphotos/momentinfo.html#MomentInfo.asdict"><span class="viewcode-link"><span class="pre">[source]</span></span></a><a class="headerlink" href="#osxphotos.MomentInfo.asdict" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>Returns all moment info as dictionary</p>
|
||||
</dd></dl>
|
||||
<dl class="py property">
|
||||
<dt class="sig sig-object py" id="osxphotos.MomentInfo.date">
|
||||
<em class="property"><span class="pre">property</span><span class="w"> </span></em><span class="sig-name descname"><span class="pre">date</span></span><a class="headerlink" href="#osxphotos.MomentInfo.date" title="Permalink to this definition">#</a></dt>
|
||||
@@ -1452,8 +1458,8 @@ only valid on Photos 5, on older libraries returns empty list</p>
|
||||
<dd><p>returns (latitude, longitude) as float in degrees or None</p>
|
||||
</dd></dl>
|
||||
<dl class="py property">
|
||||
<dt class="sig sig-object py" id="osxphotos.PhotoInfo.moment">
|
||||
<em class="property"><span class="pre">property</span><span class="w"> </span></em><span class="sig-name descname"><span class="pre">moment</span></span><a class="headerlink" href="#osxphotos.PhotoInfo.moment" title="Permalink to this definition">#</a></dt>
|
||||
<dt class="sig sig-object py" id="osxphotos.PhotoInfo.moment_info">
|
||||
<em class="property"><span class="pre">property</span><span class="w"> </span></em><span class="sig-name descname"><span class="pre">moment_info</span></span><a class="headerlink" href="#osxphotos.PhotoInfo.moment_info" title="Permalink to this definition">#</a></dt>
|
||||
<dd><p>Moment photo belongs to</p>
|
||||
</dd></dl>
|
||||
<dl class="py property">
|
||||
@@ -2894,7 +2900,7 @@ Projects are cards, calendars, slideshows, etc.</p>
|
||||
<span>Previous</span>
|
||||
</div>
|
||||
|
||||
<div class="title">Example uses of the python package</div>
|
||||
<div class="title">OSXPhotos Python Package Overview</div>
|
||||
|
||||
</div>
|
||||
</a>
|
||||
|
||||
@@ -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.47.10 documentation</title><link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
||||
<meta name="generator" content="sphinx-4.4.0, furo 2022.04.07"/><title>Search - osxphotos 0.48.2 documentation</title><link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=68f4518137b9aefe99b631505a2064c3c42c9852" />
|
||||
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
|
||||
<link rel="stylesheet" type="text/css" href="_static/styles/furo-extensions.css?digest=30d1aed668e5c3a91c3e3bf6a60b675221979f0e" />
|
||||
@@ -121,7 +121,7 @@
|
||||
</label>
|
||||
</div>
|
||||
<div class="header-center">
|
||||
<a href="index.html"><div class="brand">osxphotos 0.47.10 documentation</div></a>
|
||||
<a href="index.html"><div class="brand">osxphotos 0.48.2 documentation</div></a>
|
||||
</div>
|
||||
<div class="header-right">
|
||||
<div class="theme-toggle-container theme-toggle-header">
|
||||
@@ -144,7 +144,7 @@
|
||||
<div class="sidebar-sticky"><a class="sidebar-brand" href="index.html">
|
||||
|
||||
|
||||
<span class="sidebar-brand-text">osxphotos 0.47.10 documentation</span>
|
||||
<span class="sidebar-brand-text">osxphotos 0.48.2 documentation</span>
|
||||
|
||||
</a><form class="sidebar-search-container" method="get" action="#" role="search">
|
||||
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
|
||||
@@ -153,12 +153,12 @@
|
||||
</form>
|
||||
<div id="searchbox"></div><div class="sidebar-scroll"><div class="sidebar-tree">
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="overview.html">osxphotos</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="tutorial.html">osxphotos Tutorial</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="cli.html">osxphotos Command Line Interface (CLI)</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="template_help.html">osxphotos Template System</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="package_overview.html">Example uses of the python package</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="reference.html">osxphotos python API</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="overview.html">OSXPhotos</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="tutorial.html">OSXPhotos Tutorial</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="cli.html">OSXPhotos Command Line Interface (CLI)</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="template_help.html">OSXPhotos Template System</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="package_overview.html">OSXPhotos Python Package Overview</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="reference.html">OSXPhotos python API</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -3,10 +3,10 @@
|
||||
<head><meta charset="utf-8"/>
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1"/>
|
||||
<meta name="color-scheme" content="light dark"><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
||||
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="Example uses of the python package" href="package_overview.html" /><link rel="prev" title="osxphotos Command Line Interface (CLI)" href="cli.html" />
|
||||
<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.47.10 documentation</title>
|
||||
<title>OSXPhotos Template System - osxphotos 0.48.2 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=68f4518137b9aefe99b631505a2064c3c42c9852" />
|
||||
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
|
||||
@@ -124,7 +124,7 @@
|
||||
</label>
|
||||
</div>
|
||||
<div class="header-center">
|
||||
<a href="index.html"><div class="brand">osxphotos 0.47.10 documentation</div></a>
|
||||
<a href="index.html"><div class="brand">osxphotos 0.48.2 documentation</div></a>
|
||||
</div>
|
||||
<div class="header-right">
|
||||
<div class="theme-toggle-container theme-toggle-header">
|
||||
@@ -147,7 +147,7 @@
|
||||
<div class="sidebar-sticky"><a class="sidebar-brand" href="index.html">
|
||||
|
||||
|
||||
<span class="sidebar-brand-text">osxphotos 0.47.10 documentation</span>
|
||||
<span class="sidebar-brand-text">osxphotos 0.48.2 documentation</span>
|
||||
|
||||
</a><form class="sidebar-search-container" method="get" action="search.html" role="search">
|
||||
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
|
||||
@@ -156,12 +156,12 @@
|
||||
</form>
|
||||
<div id="searchbox"></div><div class="sidebar-scroll"><div class="sidebar-tree">
|
||||
<ul class="current">
|
||||
<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 current current-page"><a class="current reference internal" href="#">osxphotos Template System</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="package_overview.html">Example uses of the python package</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="reference.html">osxphotos python API</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="overview.html">OSXPhotos</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="tutorial.html">OSXPhotos Tutorial</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="cli.html">OSXPhotos Command Line Interface (CLI)</a></li>
|
||||
<li class="toctree-l1 current current-page"><a class="current reference internal" href="#">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>
|
||||
@@ -195,7 +195,7 @@
|
||||
</div>
|
||||
<article role="main">
|
||||
<section id="osxphotos-template-system">
|
||||
<h1>osxphotos Template System<a class="headerlink" href="#osxphotos-template-system" title="Permalink to this headline">#</a></h1>
|
||||
<h1>OSXPhotos Template System<a class="headerlink" href="#osxphotos-template-system" title="Permalink to this headline">#</a></h1>
|
||||
<p>The templating system converts one or template statements, written in osxphotos metadata templating language, to one or more rendered values using information from the photo being processed.</p>
|
||||
<p>In its simplest form, a template statement has the form: <code class="docutils literal notranslate"><span class="pre">"{template_field}"</span></code>, for example <code class="docutils literal notranslate"><span class="pre">"{title}"</span></code> which would resolve to the title of the photo.</p>
|
||||
<p>Template statements may contain one or more modifiers. The full syntax is:</p>
|
||||
@@ -246,7 +246,7 @@
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">"{folder_album()}"</span></code> renders to <code class="docutils literal notranslate"><span class="pre">["Folder1Album1"]</span></code></p></li>
|
||||
</ul>
|
||||
<p><cite>[find,replace]</cite>: optional text replacement to perform on rendered template value. For example, to replace “/” in an album name, you could use the template <cite>“{album[/,-]}”</cite>. Multiple replacements can be made by appending “|” and adding another find|replace pair. e.g. to replace both “/” and “:” in album name: <code class="docutils literal notranslate"><span class="pre">"{album[/,-|:,-]}"</span></code>. find/replace pairs are not limited to single characters. The “|” character cannot be used in a find/replace pair.</p>
|
||||
<p><cite>conditional</cite>: optional conditional expression that is evaluated as boolean (True/False) for use with the <cite>?bool_value</cite> modifier. Conditional expressions take the form ‘` not operator value`’ where <cite>not</cite> is an optional modifier that negates the <cite>operator</cite>. Note: the space before the conditional expression is required if you use a conditional expression. Valid comparison operators are:</p>
|
||||
<p><cite>conditional</cite>: optional conditional expression that is evaluated as boolean (True/False) for use with the <cite>?bool_value</cite> modifier. Conditional expressions take the form ‘<cite>not operator value</cite>’ where <cite>not</cite> is an optional modifier that negates the <cite>operator</cite>. Note: the space before the conditional expression is required if you use a conditional expression. Valid comparison operators are:</p>
|
||||
<ul class="simple">
|
||||
<li><p><code class="docutils literal notranslate"><span class="pre">contains</span></code>: template field contains value, similar to python’s <code class="docutils literal notranslate"><span class="pre">in</span></code></p></li>
|
||||
<li><p><cite>matches</cite>: template field contains exactly value, unlike <cite>contains</cite>: does not match partial matches</p></li>
|
||||
@@ -306,7 +306,7 @@
|
||||
<col style="width: 50%"/>
|
||||
</colgroup>
|
||||
<thead>
|
||||
<tr class="row-odd"><th class="head"><p>Substitution</p></th>
|
||||
<tr class="row-odd"><th class="head"><p>Field</p></th>
|
||||
<th class="head"><p>Description</p></th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -509,124 +509,127 @@
|
||||
<tr class="row-odd"><td><p>{exif.lens_model}</p></td>
|
||||
<td><p>Lens model from original photo’s EXIF information as imported by Photos, e.g. ‘iPhone 6s back camera 4.15mm f/2.2’</p></td>
|
||||
</tr>
|
||||
<tr class="row-even"><td><p>{uuid}</p></td>
|
||||
<tr class="row-even"><td><p>{moment}</p></td>
|
||||
<td><p>The moment title of the photo</p></td>
|
||||
</tr>
|
||||
<tr class="row-odd"><td><p>{uuid}</p></td>
|
||||
<td><p>Photo’s internal universally unique identifier (UUID) for the photo, a 36-character string unique to the photo, e.g. ‘128FB4C6-0B16-4E7D-9108-FB2E90DA1546’</p></td>
|
||||
</tr>
|
||||
<tr class="row-odd"><td><p>{id}</p></td>
|
||||
<tr class="row-even"><td><p>{id}</p></td>
|
||||
<td><p>A unique number for the photo based on its primary key in the Photos database. A sequential integer, e.g. 1, 2, 3…etc. Each asset associated with a photo (e.g. an image and Live Photo preview) will share the same id. May be formatted using a python string format code. For example, to format as a 5-digit integer and pad with zeros, use ‘{id:05d}’ which results in 00001, 00002, 00003…etc.</p></td>
|
||||
</tr>
|
||||
<tr class="row-even"><td><p>{album_seq}</p></td>
|
||||
<tr class="row-odd"><td><p>{album_seq}</p></td>
|
||||
<td><p>An integer, starting at 0, indicating the photo’s index (sequence) in the containing album. Only valid when used in a ‘–filename’ template and only when ‘{album}’ or ‘{folder_album}’ is used in the ‘–directory’ template. For example ‘–directory “{folder_album}” –filename “{album<em>seq}</em>{original_name}”’. To start counting at a value other than 0, append append a period and the starting value to the field name. For example, to start counting at 1 instead of 0: ‘{album_seq.1}’. May be formatted using a python string format code. For example, to format as a 5-digit integer and pad with zeros, use ‘{album_seq:05d}’ which results in 00000, 00001, 00002…etc. This may result in incorrect sequences if you have duplicate albums with the same name; see also ‘{folder_album_seq}’.</p></td>
|
||||
</tr>
|
||||
<tr class="row-odd"><td><p>{folder_album_seq}</p></td>
|
||||
<tr class="row-even"><td><p>{folder_album_seq}</p></td>
|
||||
<td><p>An integer, starting at 0, indicating the photo’s index (sequence) in the containing album and folder path. Only valid when used in a ‘–filename’ template and only when ‘{folder_album}’ is used in the ‘–directory’ template. For example ‘–directory “{folder_album}” –filename “{folder_album<em>seq}</em>{original_name}”’. To start counting at a value other than 0, append append a period and the starting value to the field name. For example, to start counting at 1 instead of 0: ‘{folder_album_seq.1}’ May be formatted using a python string format code. For example, to format as a 5-digit integer and pad with zeros, use ‘{folder_album_seq:05d}’ which results in 00000, 00001, 00002…etc. This may result in incorrect sequences if you have duplicate albums with the same name in the same folder; see also ‘{album_seq}’.</p></td>
|
||||
</tr>
|
||||
<tr class="row-even"><td><p>{comma}</p></td>
|
||||
<tr class="row-odd"><td><p>{comma}</p></td>
|
||||
<td><p>A comma: ‘,’</p></td>
|
||||
</tr>
|
||||
<tr class="row-odd"><td><p>{semicolon}</p></td>
|
||||
<tr class="row-even"><td><p>{semicolon}</p></td>
|
||||
<td><p>A semicolon: ‘;’</p></td>
|
||||
</tr>
|
||||
<tr class="row-even"><td><p>{questionmark}</p></td>
|
||||
<tr class="row-odd"><td><p>{questionmark}</p></td>
|
||||
<td><p>A question mark: ‘?’</p></td>
|
||||
</tr>
|
||||
<tr class="row-odd"><td><p>{pipe}</p></td>
|
||||
<tr class="row-even"><td><p>{pipe}</p></td>
|
||||
<td><p>A vertical pipe: ‘|’</p></td>
|
||||
</tr>
|
||||
<tr class="row-even"><td><p>{openbrace}</p></td>
|
||||
<tr class="row-odd"><td><p>{openbrace}</p></td>
|
||||
<td><p>An open brace: ‘{’</p></td>
|
||||
</tr>
|
||||
<tr class="row-odd"><td><p>{closebrace}</p></td>
|
||||
<tr class="row-even"><td><p>{closebrace}</p></td>
|
||||
<td><p>A close brace: ‘}’</p></td>
|
||||
</tr>
|
||||
<tr class="row-even"><td><p>{openparens}</p></td>
|
||||
<tr class="row-odd"><td><p>{openparens}</p></td>
|
||||
<td><p>An open parentheses: ‘(’</p></td>
|
||||
</tr>
|
||||
<tr class="row-odd"><td><p>{closeparens}</p></td>
|
||||
<tr class="row-even"><td><p>{closeparens}</p></td>
|
||||
<td><p>A close parentheses: ‘)’</p></td>
|
||||
</tr>
|
||||
<tr class="row-even"><td><p>{openbracket}</p></td>
|
||||
<tr class="row-odd"><td><p>{openbracket}</p></td>
|
||||
<td><p>An open bracket: ‘[’</p></td>
|
||||
</tr>
|
||||
<tr class="row-odd"><td><p>{closebracket}</p></td>
|
||||
<tr class="row-even"><td><p>{closebracket}</p></td>
|
||||
<td><p>A close bracket: ‘]’</p></td>
|
||||
</tr>
|
||||
<tr class="row-even"><td><p>{newline}</p></td>
|
||||
<tr class="row-odd"><td><p>{newline}</p></td>
|
||||
<td><p>A newline: ‘n’</p></td>
|
||||
</tr>
|
||||
<tr class="row-odd"><td><p>{lf}</p></td>
|
||||
<tr class="row-even"><td><p>{lf}</p></td>
|
||||
<td><p>A line feed: ‘n’, alias for {newline}</p></td>
|
||||
</tr>
|
||||
<tr class="row-even"><td><p>{cr}</p></td>
|
||||
<tr class="row-odd"><td><p>{cr}</p></td>
|
||||
<td><p>A carriage return: ‘r’</p></td>
|
||||
</tr>
|
||||
<tr class="row-odd"><td><p>{crlf}</p></td>
|
||||
<tr class="row-even"><td><p>{crlf}</p></td>
|
||||
<td><p>a carriage return + line feed: ‘rn’</p></td>
|
||||
</tr>
|
||||
<tr class="row-even"><td><p>{osxphotos_version}</p></td>
|
||||
<td><p>The osxphotos version, e.g. ‘0.47.10’</p></td>
|
||||
<tr class="row-odd"><td><p>{osxphotos_version}</p></td>
|
||||
<td><p>The osxphotos version, e.g. ‘0.48.2’</p></td>
|
||||
</tr>
|
||||
<tr class="row-odd"><td><p>{osxphotos_cmd_line}</p></td>
|
||||
<tr class="row-even"><td><p>{osxphotos_cmd_line}</p></td>
|
||||
<td><p>The full command line used to run osxphotos</p></td>
|
||||
</tr>
|
||||
<tr class="row-even"><td><p>{album}</p></td>
|
||||
<tr class="row-odd"><td><p>{album}</p></td>
|
||||
<td><p>Album(s) photo is contained in</p></td>
|
||||
</tr>
|
||||
<tr class="row-odd"><td><p>{folder_album}</p></td>
|
||||
<tr class="row-even"><td><p>{folder_album}</p></td>
|
||||
<td><p>Folder path + album photo is contained in. e.g. ‘Folder/Subfolder/Album’ or just ‘Album’ if no enclosing folder</p></td>
|
||||
</tr>
|
||||
<tr class="row-even"><td><p>{project}</p></td>
|
||||
<tr class="row-odd"><td><p>{project}</p></td>
|
||||
<td><p>Project(s) photo is contained in (such as greeting cards, calendars, slideshows)</p></td>
|
||||
</tr>
|
||||
<tr class="row-odd"><td><p>{album_project}</p></td>
|
||||
<tr class="row-even"><td><p>{album_project}</p></td>
|
||||
<td><p>Album(s) and project(s) photo is contained in; treats projects as regular albums</p></td>
|
||||
</tr>
|
||||
<tr class="row-even"><td><p>{folder_album_project}</p></td>
|
||||
<tr class="row-odd"><td><p>{folder_album_project}</p></td>
|
||||
<td><p>Folder path + album (includes projects as albums) photo is contained in. e.g. ‘Folder/Subfolder/Album’ or just ‘Album’ if no enclosing folder</p></td>
|
||||
</tr>
|
||||
<tr class="row-odd"><td><p>{keyword}</p></td>
|
||||
<tr class="row-even"><td><p>{keyword}</p></td>
|
||||
<td><p>Keyword(s) assigned to photo</p></td>
|
||||
</tr>
|
||||
<tr class="row-even"><td><p>{person}</p></td>
|
||||
<tr class="row-odd"><td><p>{person}</p></td>
|
||||
<td><p>Person(s) / face(s) in a photo</p></td>
|
||||
</tr>
|
||||
<tr class="row-odd"><td><p>{label}</p></td>
|
||||
<tr class="row-even"><td><p>{label}</p></td>
|
||||
<td><p>Image categorization label associated with a photo (Photos 5+ only). Labels are added automatically by Photos using machine learning algorithms to categorize images. These are not the same as {keyword} which refers to the user-defined keywords/tags applied in Photos.</p></td>
|
||||
</tr>
|
||||
<tr class="row-even"><td><p>{label_normalized}</p></td>
|
||||
<tr class="row-odd"><td><p>{label_normalized}</p></td>
|
||||
<td><p>All lower case version of ‘label’ (Photos 5+ only)</p></td>
|
||||
</tr>
|
||||
<tr class="row-odd"><td><p>{comment}</p></td>
|
||||
<tr class="row-even"><td><p>{comment}</p></td>
|
||||
<td><p>Comment(s) on shared Photos; format is ‘Person name: comment text’ (Photos 5+ only)</p></td>
|
||||
</tr>
|
||||
<tr class="row-even"><td><p>{exiftool}</p></td>
|
||||
<tr class="row-odd"><td><p>{exiftool}</p></td>
|
||||
<td><p>Format: ‘{exiftool:GROUP:TAGNAME}’; use exiftool (https://exiftool.org) to extract metadata, in form GROUP:TAGNAME, from image. E.g. ‘{exiftool:EXIF:Make}’ to get camera make, or {exiftool:IPTC:Keywords} to extract keywords. See https://exiftool.org/TagNames/ for list of valid tag names. You must specify group (e.g. EXIF, IPTC, etc) as used in <code class="docutils literal notranslate"><span class="pre">exiftool</span> <span class="pre">-G</span></code>. exiftool must be installed in the path to use this template.</p></td>
|
||||
</tr>
|
||||
<tr class="row-odd"><td><p>{searchinfo.holiday}</p></td>
|
||||
<tr class="row-even"><td><p>{searchinfo.holiday}</p></td>
|
||||
<td><p>Holiday names associated with a photo, e.g. ‘Christmas Day’; (Photos 5+ only, applied automatically by Photos’ image categorization algorithms).</p></td>
|
||||
</tr>
|
||||
<tr class="row-even"><td><p>{searchinfo.activity}</p></td>
|
||||
<tr class="row-odd"><td><p>{searchinfo.activity}</p></td>
|
||||
<td><p>Activities associated with a photo, e.g. ‘Sporting Event’; (Photos 5+ only, applied automatically by Photos’ image categorization algorithms).</p></td>
|
||||
</tr>
|
||||
<tr class="row-odd"><td><p>{searchinfo.venue}</p></td>
|
||||
<tr class="row-even"><td><p>{searchinfo.venue}</p></td>
|
||||
<td><p>Venues associated with a photo, e.g. name of restaurant; (Photos 5+ only, applied automatically by Photos’ image categorization algorithms).</p></td>
|
||||
</tr>
|
||||
<tr class="row-even"><td><p>{searchinfo.venue_type}</p></td>
|
||||
<tr class="row-odd"><td><p>{searchinfo.venue_type}</p></td>
|
||||
<td><p>Venue types associated with a photo, e.g. ‘Restaurant’; (Photos 5+ only, applied automatically by Photos’ image categorization algorithms).</p></td>
|
||||
</tr>
|
||||
<tr class="row-odd"><td><p>{photo}</p></td>
|
||||
<tr class="row-even"><td><p>{photo}</p></td>
|
||||
<td><p>Provides direct access to the PhotoInfo object for the photo. Must be used in format ‘{photo.property}’ where ‘property’ represents a PhotoInfo property. For example: ‘{photo.favorite}’ is the same as ‘{favorite}’ and ‘{photo.place.name}’ is the same as ‘{place.name}’. ‘{photo}’ provides access to properties that are not available as separate template fields but it assumes some knowledge of the underlying PhotoInfo class. See <a class="reference external" href="https://rhettbull.github.io/osxphotos/">https://rhettbull.github.io/osxphotos/</a> for additional documentation on the PhotoInfo class.</p></td>
|
||||
</tr>
|
||||
<tr class="row-even"><td><p>{detected_text}</p></td>
|
||||
<tr class="row-odd"><td><p>{detected_text}</p></td>
|
||||
<td><p>List of text strings found in the image after performing text detection. Using ‘{detected_text}’ will cause osxphotos to perform text detection on your photos using the built-in macOS text detection algorithms which will slow down your export. The results for each photo will be cached in the export database so that future exports with ‘–update’ do not need to reprocess each photo. You may pass a confidence threshold value between 0.0 and 1.0 after a colon as in ‘{detected_text:0.5}’; The default confidence threshold is 0.75. ‘{detected_text}’ works only on macOS Catalina (10.15) or later. Note: this feature is not the same thing as Live Text in macOS Monterey, which osxphotos does not yet support.</p></td>
|
||||
</tr>
|
||||
<tr class="row-odd"><td><p>{shell_quote}</p></td>
|
||||
<tr class="row-even"><td><p>{shell_quote}</p></td>
|
||||
<td><p>Use in form ‘{shell_quote,TEMPLATE}’; quotes the rendered TEMPLATE value(s) for safe usage in the shell, e.g. My file.jpeg => ‘My file.jpeg’; only adds quotes if needed.</p></td>
|
||||
</tr>
|
||||
<tr class="row-even"><td><p>{strip}</p></td>
|
||||
<tr class="row-odd"><td><p>{strip}</p></td>
|
||||
<td><p>Use in form ‘{strip,TEMPLATE}’; strips whitespace from begining and end of rendered TEMPLATE value(s).</p></td>
|
||||
</tr>
|
||||
<tr class="row-odd"><td><p>{function}</p></td>
|
||||
<tr class="row-even"><td><p>{function}</p></td>
|
||||
<td><p>Execute a python function from an external file and use return value as template substitution. Use in format: {function:file.py::function_name} where ‘file.py’ is the name of the python file and ‘function_name’ is the name of the function to call. The function will be passed the PhotoInfo object for the photo. See https://github.com/RhetTbull/osxphotos/blob/master/examples/template_function.py for an example of how to implement a template function.</p></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@@ -644,7 +647,7 @@
|
||||
<div class="context">
|
||||
<span>Next</span>
|
||||
</div>
|
||||
<div class="title">Example uses of the python package</div>
|
||||
<div class="title">OSXPhotos Python Package Overview</div>
|
||||
</div>
|
||||
<svg><use href="#svg-arrow-right"></use></svg>
|
||||
</a>
|
||||
@@ -655,7 +658,7 @@
|
||||
<span>Previous</span>
|
||||
</div>
|
||||
|
||||
<div class="title">osxphotos Command Line Interface (CLI)</div>
|
||||
<div class="title">OSXPhotos Command Line Interface (CLI)</div>
|
||||
|
||||
</div>
|
||||
</a>
|
||||
@@ -691,7 +694,7 @@
|
||||
<div class="toc-tree-container">
|
||||
<div class="toc-tree">
|
||||
<ul>
|
||||
<li><a class="reference internal" href="#">osxphotos Template System</a><ul>
|
||||
<li><a class="reference internal" href="#">OSXPhotos Template System</a><ul>
|
||||
<li><a class="reference internal" href="#id1">Template Substitutions</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
<head><meta charset="utf-8"/>
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1"/>
|
||||
<meta name="color-scheme" content="light dark"><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
||||
<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" />
|
||||
<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.47.10 documentation</title>
|
||||
<title>OSXPhotos Tutorial - osxphotos 0.48.2 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=68f4518137b9aefe99b631505a2064c3c42c9852" />
|
||||
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
|
||||
@@ -124,7 +124,7 @@
|
||||
</label>
|
||||
</div>
|
||||
<div class="header-center">
|
||||
<a href="index.html"><div class="brand">osxphotos 0.47.10 documentation</div></a>
|
||||
<a href="index.html"><div class="brand">osxphotos 0.48.2 documentation</div></a>
|
||||
</div>
|
||||
<div class="header-right">
|
||||
<div class="theme-toggle-container theme-toggle-header">
|
||||
@@ -147,7 +147,7 @@
|
||||
<div class="sidebar-sticky"><a class="sidebar-brand" href="index.html">
|
||||
|
||||
|
||||
<span class="sidebar-brand-text">osxphotos 0.47.10 documentation</span>
|
||||
<span class="sidebar-brand-text">osxphotos 0.48.2 documentation</span>
|
||||
|
||||
</a><form class="sidebar-search-container" method="get" action="search.html" role="search">
|
||||
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
|
||||
@@ -156,12 +156,12 @@
|
||||
</form>
|
||||
<div id="searchbox"></div><div class="sidebar-scroll"><div class="sidebar-tree">
|
||||
<ul class="current">
|
||||
<li class="toctree-l1"><a class="reference internal" href="overview.html">osxphotos</a></li>
|
||||
<li class="toctree-l1 current current-page"><a class="current reference internal" href="#">osxphotos Tutorial</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="cli.html">osxphotos Command Line Interface (CLI)</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="template_help.html">osxphotos Template System</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="package_overview.html">Example uses of the python package</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="reference.html">osxphotos python API</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="overview.html">OSXPhotos</a></li>
|
||||
<li class="toctree-l1 current current-page"><a class="current reference internal" href="#">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>
|
||||
@@ -195,7 +195,7 @@
|
||||
</div>
|
||||
<article role="main">
|
||||
<!-- OSXPHOTOS-TUTORIAL-HEADER:START --><section id="osxphotos-tutorial">
|
||||
<h1>osxphotos Tutorial<a class="headerlink" href="#osxphotos-tutorial" title="Permalink to this headline">#</a></h1>
|
||||
<h1>OSXPhotos Tutorial<a class="headerlink" href="#osxphotos-tutorial" title="Permalink to this headline">#</a></h1>
|
||||
<section id="overview">
|
||||
<h2>Overview<a class="headerlink" href="#overview" title="Permalink to this headline">#</a></h2>
|
||||
<!-- OSXPHOTOS-TUTORIAL-HEADER:END --><p>The design philosophy for osxphotos is “make the easy things easy and make the hard things possible”. To “make the hard things possible”, osxphotos is very flexible and has many, many configuration options – the <code class="docutils literal notranslate"><span class="pre">export</span></code> command for example, has over 100 command line options. Thus, osxphotos may seem daunting at first. The purpose of this tutorial is to explain a number of common use cases with examples and, hopefully, make osxphotos less daunting to use. osxphotos includes several commands for retrieving information from your Photos library but the one most users are interested in is the <code class="docutils literal notranslate"><span class="pre">export</span></code> command which exports photos from the library so that’s the focus of this tutorial.</p>
|
||||
@@ -508,7 +508,7 @@ template fields.
|
||||
<div class="context">
|
||||
<span>Next</span>
|
||||
</div>
|
||||
<div class="title">osxphotos Command Line Interface (CLI)</div>
|
||||
<div class="title">OSXPhotos Command Line Interface (CLI)</div>
|
||||
</div>
|
||||
<svg><use href="#svg-arrow-right"></use></svg>
|
||||
</a>
|
||||
@@ -519,7 +519,7 @@ template fields.
|
||||
<span>Previous</span>
|
||||
</div>
|
||||
|
||||
<div class="title">osxphotos</div>
|
||||
<div class="title">OSXPhotos</div>
|
||||
|
||||
</div>
|
||||
</a>
|
||||
@@ -555,7 +555,7 @@ template fields.
|
||||
<div class="toc-tree-container">
|
||||
<div class="toc-tree">
|
||||
<ul>
|
||||
<li><a class="reference internal" href="#">osxphotos Tutorial</a><ul>
|
||||
<li><a class="reference internal" href="#">OSXPhotos Tutorial</a><ul>
|
||||
<li><a class="reference internal" href="#overview">Overview</a></li>
|
||||
<li><a class="reference internal" href="#export-your-photos">Export your photos</a></li>
|
||||
<li><a class="reference internal" href="#export-by-date">Export by date</a></li>
|
||||
|
||||
@@ -2,12 +2,17 @@
|
||||
|
||||
I'm still trying to learn sphinx and come up with a workflow for building docs. Right now it's pretty kludgy.
|
||||
|
||||
- `pip install sphinx`
|
||||
- `pip install sphinx-rtd-theme`
|
||||
- `pip install m2r2`
|
||||
- `python3 -m pip -r dev_requirements.txt`
|
||||
- Download and install [MacTeX](https://tug.org/mactex/)
|
||||
- Add `/Library/TeX/texbin` to your `$PATH`
|
||||
- `cd docs`
|
||||
- `make html`
|
||||
- `make latexpdf`
|
||||
- `cp _build/latex/osxphotos.pdf .`
|
||||
|
||||
The `build.sh` script in the main repo directory will build the documents for you and is the preferred way to build the docs.
|
||||
|
||||
The following files are generated by `build.sh` and should not be directly edited:
|
||||
|
||||
- source/template_help.rst
|
||||
- source/tutorial.rst
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
osxphotos Command Line Interface (CLI)
|
||||
OSXPhotos Command Line Interface (CLI)
|
||||
======================================
|
||||
|
||||
.. click:: osxphotos.cli:cli_main
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
You can adapt this file completely to your liking, but it should at least
|
||||
contain the root `toctree` directive.
|
||||
|
||||
Welcome to osxphotos's documentation!
|
||||
Welcome to OSXPhotos's documentation!
|
||||
=====================================
|
||||
|
||||
.. toctree::
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
osxphotos
|
||||
OSXPhotos
|
||||
=========
|
||||
|
||||
What is osxphotos?
|
||||
What is OSXPhotos?
|
||||
------------------
|
||||
|
||||
osxphotos provides both the ability to interact with and query Apple's Photos.app library on macOS directly from your python code
|
||||
OSXPhotos provides both the ability to interact with and query Apple's Photos.app library on macOS directly from your python code
|
||||
as well as a very flexible command line interface (CLI) app for exporting photos.
|
||||
You can query the Photos library database -- for example, file name, file path, and metadata such as keywords/tags, persons/faces, albums, etc.
|
||||
You can also easily export both the original and edited photos.
|
||||
@@ -74,8 +74,10 @@ This package will install a command line utility called ``osxphotos`` that allow
|
||||
run Run a python file using same environment as osxphotos
|
||||
snap Create snapshot of Photos database to use with diff command
|
||||
theme Manage osxphotos color themes.
|
||||
timewarp Adjust date/time/timezone of photos in Apple Photos.
|
||||
tutorial Display osxphotos tutorial.
|
||||
uninstall Uninstall Python packages from the osxphotos environment
|
||||
uuid Print out unique IDs (UUID) of photos selected in Photos
|
||||
version Check for new version of osxphotos.
|
||||
|
||||
To get help on a specific command, use ``osxphotos help <command_name>``
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
OSXPhotos Python Package Overview
|
||||
=================================
|
||||
|
||||
Example uses of the python package
|
||||
----------------------------------
|
||||
Example uses of the OSXPhotos python package
|
||||
--------------------------------------------
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -116,4 +118,76 @@ Example uses of the python package
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
export()
|
||||
export()
|
||||
|
||||
|
||||
OSXPhotos REPL
|
||||
--------------
|
||||
|
||||
The osxphotos command line interface includes a REPL (Run-Evaluate-Print Loop) for testing and development.
|
||||
|
||||
The REPL is started with the command: ``osxphotos repl``::
|
||||
|
||||
$ osxphotos repl
|
||||
python version: 3.10.2 (main, Feb 2 2022, 07:36:01) [Clang 12.0.0 (clang-1200.0.32.29)]
|
||||
osxphotos version: 0.47.10
|
||||
Using last opened Photos library: /Users/user/Pictures/Photos Library.photoslibrary
|
||||
Loading database
|
||||
Processing database /Users/user/Pictures/Photos Library.photoslibrary/database/photos.db
|
||||
Processing database /Users/user/Pictures/Photos Library.photoslibrary/database/Photos.sqlite
|
||||
Database locked, creating temporary copy.
|
||||
Processing database.
|
||||
Database version: 6000, 5.
|
||||
Processing persons in photos.
|
||||
Processing detected faces in photos.
|
||||
Processing albums.
|
||||
Processing keywords.
|
||||
Processing photo details.
|
||||
Processing import sessions.
|
||||
Processing additional photo details.
|
||||
Processing face details.
|
||||
Processing photo labels.
|
||||
Processing EXIF details.
|
||||
Processing computed aesthetic scores.
|
||||
Processing comments and likes for shared photos.
|
||||
Processing moments.
|
||||
Done processing details from Photos library.
|
||||
Done: took 18.54 seconds
|
||||
Getting photos
|
||||
Found 31581 photos in 0.77 seconds
|
||||
|
||||
The following classes have been imported from osxphotos:
|
||||
- AlbumInfo, ExifTool, PhotoInfo, PhotoExporter, ExportOptions, ExportResults, PhotosDB, PlaceInfo, QueryOptions, MomentInfo, ScoreInfo, SearchInfo
|
||||
|
||||
The following variables are defined:
|
||||
- photosdb: PhotosDB() instance for '/Users/user/Pictures/Photos Library.photoslibrary'
|
||||
- photos: list of PhotoInfo objects for all photos filtered with any query options passed on command line (len=31581)
|
||||
- all_photos: list of PhotoInfo objects for all photos in photosdb, including those in the trash (len=31581)
|
||||
- selected: list of PhotoInfo objects for any photos selected in Photos (len=0)
|
||||
|
||||
The following functions may be helpful:
|
||||
- get_photo(uuid): return a PhotoInfo object for photo with uuid; e.g. get_photo('B13F4485-94E0-41CD-AF71-913095D62E31')
|
||||
- get_selected(); return list of PhotoInfo objects for photos selected in Photos
|
||||
- show(photo): open a photo object in the default viewer; e.g. show(selected[0])
|
||||
- show(path): open a file at path in the default viewer; e.g. show('/path/to/photo.jpg')
|
||||
- spotlight(photo): open a photo and spotlight it in Photos
|
||||
- inspect(object): print information about an object; e.g. inspect(PhotoInfo)
|
||||
- explore(object): interactively explore an object with objexplore; e.g. explore(PhotoInfo)
|
||||
- q, quit, quit(), exit, exit(): exit this interactive shell
|
||||
|
||||
>>>
|
||||
|
||||
Using the osxphotos CLI to run python code
|
||||
------------------------------------------
|
||||
|
||||
The osxphotos CLI can also be used to run your own python code using the ``osxphotos run`` command.
|
||||
|
||||
This is useful if you have installed the CLI using ``pipx`` but want to use the osxphotos programmatic interface in your own scripts.
|
||||
|
||||
If you need to install any additional python packages to use in your own scripts, you can use the ``osxphotos install`` command
|
||||
which installs python packages just as ``pip`` does but into the same virtual environment that osxphotos is installed in.
|
||||
|
||||
Likewise, you can use ``osxphotos uninstall`` to uninstall any installed python packages.
|
||||
|
||||
These features are also useful for developing custom functions to use with ``--query-function`` and ``--post-function``
|
||||
as well as ``{function}`` templates and ``function:`` filters.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
osxphotos python API
|
||||
OSXPhotos python API
|
||||
====================
|
||||
|
||||
.. automodule:: osxphotos
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
|
||||
osxphotos Template System
|
||||
OSXPhotos Template System
|
||||
=========================
|
||||
|
||||
The templating system converts one or template statements, written in osxphotos metadata templating language, to one or more rendered values using information from the photo being processed.
|
||||
The templating system converts one or template statements, written in osxphotos metadata templating language, to one or more rendered values using information from the photo being processed.
|
||||
|
||||
In its simplest form, a template statement has the form: ``"{template_field}"``\ , for example ``"{title}"`` which would resolve to the title of the photo.
|
||||
|
||||
@@ -26,7 +26,7 @@ e.g. if Photo keywords are ``["foo","bar"]``\ :
|
||||
* ``"{; +keyword}"`` renders to: ``"foo; bar"``
|
||||
* ``"{+keyword}"`` renders to ``"foobar"``
|
||||
|
||||
``template_field``\ : The template field to resolve. See `Template Substitutions <#template-substitutions>`_ for full list of template fields.
|
||||
``template_field``\ : The template field to resolve. See `Template Substitutions <#template-substitutions>`_ for full list of template fields.
|
||||
|
||||
`:subfield`: Some templates have sub-fields, For example, `{exiftool:IPTC:Make}\ ``; the template_field is``\ exiftool\ ``and the sub-field is``\ IPTC:Make`.
|
||||
|
||||
@@ -70,7 +70,7 @@ e.g. If Photo is in ``Album1`` in ``Folder1``\ :
|
||||
|
||||
`[find,replace]`: optional text replacement to perform on rendered template value. For example, to replace "/" in an album name, you could use the template `"{album[/,-]}"`. Multiple replacements can be made by appending "|" and adding another find|replace pair. e.g. to replace both "/" and ":" in album name: ``"{album[/,-|:,-]}"``. find/replace pairs are not limited to single characters. The "|" character cannot be used in a find/replace pair.
|
||||
|
||||
`conditional`: optional conditional expression that is evaluated as boolean (True/False) for use with the `?bool_value` modifier. Conditional expressions take the form '` not operator value`' where `not` is an optional modifier that negates the `operator`. Note: the space before the conditional expression is required if you use a conditional expression. Valid comparison operators are:
|
||||
`conditional`: optional conditional expression that is evaluated as boolean (True/False) for use with the `?bool_value` modifier. Conditional expressions take the form '`not operator value`' where `not` is an optional modifier that negates the `operator`. Note: the space before the conditional expression is required if you use a conditional expression. Valid comparison operators are:
|
||||
|
||||
|
||||
* ``contains``\ : template field contains value, similar to python's ``in``
|
||||
@@ -118,7 +118,7 @@ and if it is not an HDR image,
|
||||
|
||||
* ``"{hdr?ISHDR,NOTHDR}"`` renders to ``"NOTHDR"``
|
||||
|
||||
``,default``\ : optional default value to use if the template name has no value. This modifier is also used for the value if False for boolean-type fields (see above) as well as to hold a sub-template for values like ``{created.strftime}``. If no default value provided, "_" is used.
|
||||
``,default``\ : optional default value to use if the template name has no value. This modifier is also used for the value if False for boolean-type fields (see above) as well as to hold a sub-template for values like ``{created.strftime}``. If no default value provided, "_" is used.
|
||||
|
||||
e.g., if photo has no title set,
|
||||
|
||||
@@ -133,7 +133,7 @@ e.g., if photo date is 4 February 2020, 19:07:38,
|
||||
|
||||
* ``"{created.strftime,%Y-%m-%d-%H%M%S}"`` renders to ``"2020-02-04-190738"``
|
||||
|
||||
Some template fields such as ``"{media_type}"`` use the default value to allow customization of the output. For example, ``"{media_type}"`` resolves to the special media type of the photo such as ``panorama`` or ``selfie``. You may use the default value to override these in form: ``"{media_type,video=vidéo;time_lapse=vidéo_accélérée}"``. In this example, if photo was a time_lapse photo, ``media_type`` would resolve to ``vidéo_accélérée`` instead of ``time_lapse``.
|
||||
Some template fields such as ``"{media_type}"`` use the default value to allow customization of the output. For example, ``"{media_type}"`` resolves to the special media type of the photo such as ``panorama`` or ``selfie``. You may use the default value to override these in form: ``"{media_type,video=vidéo;time_lapse=vidéo_accélérée}"``. In this example, if photo was a time_lapse photo, ``media_type`` would resolve to ``vidéo_accélérée`` instead of ``time_lapse``.
|
||||
|
||||
Either or both bool_value or default (False value) may be empty which would result in empty string ``""`` when rendered.
|
||||
|
||||
@@ -147,7 +147,7 @@ Template Substitutions
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
|
||||
* - Substitution
|
||||
* - Field
|
||||
- Description
|
||||
* - {name}
|
||||
- Current filename of the photo
|
||||
@@ -281,6 +281,8 @@ Template Substitutions
|
||||
- Camera model from original photo's EXIF information as imported by Photos, e.g. 'iPhone 6s'
|
||||
* - {exif.lens_model}
|
||||
- Lens model from original photo's EXIF information as imported by Photos, e.g. 'iPhone 6s back camera 4.15mm f/2.2'
|
||||
* - {moment}
|
||||
- The moment title of the photo
|
||||
* - {uuid}
|
||||
- Photo's internal universally unique identifier (UUID) for the photo, a 36-character string unique to the photo, e.g. '128FB4C6-0B16-4E7D-9108-FB2E90DA1546'
|
||||
* - {id}
|
||||
@@ -318,7 +320,7 @@ Template Substitutions
|
||||
* - {crlf}
|
||||
- a carriage return + line feed: '\r\n'
|
||||
* - {osxphotos_version}
|
||||
- The osxphotos version, e.g. '0.47.10'
|
||||
- The osxphotos version, e.g. '0.48.2'
|
||||
* - {osxphotos_cmd_line}
|
||||
- The full command line used to run osxphotos
|
||||
* - {album}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
|
||||
|
||||
osxphotos Tutorial
|
||||
OSXPhotos Tutorial
|
||||
==================
|
||||
|
||||
Overview
|
||||
|
||||
46
examples/timewarp_function_example.py
Normal file
46
examples/timewarp_function_example.py
Normal file
@@ -0,0 +1,46 @@
|
||||
"""Example function for use with `osxphotos timewarp --function`
|
||||
|
||||
Call this as: `osxphotos timewarp --function timewarp_function_example.py::get_date_time_timezone`
|
||||
"""
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
from typing import Callable, Optional, Tuple
|
||||
|
||||
from photoscript import Photo
|
||||
|
||||
|
||||
def get_date_time_timezone(
|
||||
photo: Photo, path: Optional[str], tz_sec: int, tz_name: str, verbose: Callable
|
||||
) -> Tuple[datetime, int]:
|
||||
"""Example function for use with `osxphotos timewarp --function`
|
||||
|
||||
Args:
|
||||
photo: Photo object
|
||||
path: path to photo, which may be None if photo is not on disk
|
||||
tz_sec: timezone offset from UTC in seconds
|
||||
tz_name: timezone name
|
||||
verbose: function to print verbose messages
|
||||
|
||||
Returns:
|
||||
tuple of (new date/time as datetime.datetime, and new timezone offset from UTC in seconds as int)
|
||||
"""
|
||||
|
||||
# this example adds 3 hours to the date/time and subtracts 1 hour from the timezone
|
||||
|
||||
# the photo's date/time can be accessed as photo.date
|
||||
# photo.date is a datetime.datetime object
|
||||
# the date/time is naive (timezone unaware) as will be in local timezone
|
||||
date = photo.date
|
||||
|
||||
# add 3 hours
|
||||
date = date + timedelta(hours=3)
|
||||
|
||||
# subtract 1 hour from timezone
|
||||
timezone = tz_sec - 3600
|
||||
|
||||
# verbose(msg) prints a message to the console if user used --verbose option
|
||||
# otherwise it does nothing
|
||||
# photo's filename can be access as photo.filename
|
||||
verbose(f"Updating {photo.filename} date/time: {date} and timezone: {timezone}")
|
||||
|
||||
return date, timezone
|
||||
@@ -1,3 +1,3 @@
|
||||
""" version info """
|
||||
|
||||
__version__ = "0.47.10"
|
||||
__version__ = "0.48.2"
|
||||
|
||||
@@ -1,21 +1,15 @@
|
||||
"""about command for osxphotos CLI"""
|
||||
|
||||
from textwrap import dedent
|
||||
|
||||
import click
|
||||
|
||||
from osxphotos._constants import OSXPHOTOS_URL
|
||||
from osxphotos._version import __version__
|
||||
|
||||
|
||||
@click.command(name="about")
|
||||
@click.pass_obj
|
||||
@click.pass_context
|
||||
def about(ctx, cli_obj):
|
||||
"""Print information about osxphotos including license."""
|
||||
license = """
|
||||
MIT_LICENSE = """
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019-2021 Rhet Turnbull
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
@@ -33,10 +27,213 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
"""
|
||||
|
||||
osxphotos uses the following 3rd party software licensed under the BSD-3-Clause License:
|
||||
Click (Copyright 2014 Pallets), ptpython (Copyright (c) 2015, Jonathan Slenders)
|
||||
APACHE_2_0_LICENSE = """
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
"""
|
||||
|
||||
BSD_3_CLAUSE_LICENSE = """
|
||||
Redistribution and use in source and binary forms, with or without modification, are
|
||||
permitted provided that the following conditions are met:
|
||||
|
||||
@@ -60,7 +257,33 @@ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON A
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
"""
|
||||
click.echo(f"osxphotos, version {__version__}")
|
||||
click.echo("")
|
||||
click.echo(f"Source code available at: {OSXPHOTOS_URL}")
|
||||
click.echo(license)
|
||||
|
||||
LICENSE = dedent(
|
||||
f"""
|
||||
osxphotos is copyright (c) 2019-2022 by Rhet Turnbull and is licensed under the MIT license:
|
||||
|
||||
{MIT_LICENSE}
|
||||
|
||||
osxphotos uses the following 3rd party software licensed under the BSD-3-Clause License:
|
||||
Click (Copyright 2014 Pallets), ptpython (Copyright (c) 2015, Jonathan Slenders)
|
||||
|
||||
{BSD_3_CLAUSE_LICENSE}
|
||||
|
||||
osxphotos uses the following 3rd party software licensed under the Apache 2.0 License:
|
||||
tenacity (Copyright Julien Danjou)
|
||||
|
||||
{APACHE_2_0_LICENSE}
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
@click.command(name="about")
|
||||
@click.pass_obj
|
||||
@click.pass_context
|
||||
def about(ctx, cli_obj):
|
||||
"""Print information about osxphotos including license."""
|
||||
click.echo_via_pager(
|
||||
f"osxphotos, version {__version__}\n\n"
|
||||
f"Source code available at: {OSXPHOTOS_URL}\n"
|
||||
f"{LICENSE}"
|
||||
)
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
import click
|
||||
|
||||
import osxphotos
|
||||
from osxphotos._version import __version__
|
||||
|
||||
from .about import about
|
||||
@@ -19,15 +18,17 @@ from .info import info
|
||||
from .install_uninstall_run import install, run, uninstall
|
||||
from .keywords import keywords
|
||||
from .labels import labels
|
||||
from .list import _list_libraries, list_libraries
|
||||
from .list import list_libraries
|
||||
from .persons import persons
|
||||
from .places import places
|
||||
from .query import query
|
||||
from .repl import repl
|
||||
from .snap_diff import diff, snap
|
||||
from .theme import theme
|
||||
from .timewarp import timewarp
|
||||
from .tutorial import tutorial
|
||||
from .uuid import uuid
|
||||
from .version import version
|
||||
|
||||
|
||||
# Click CLI object & context settings
|
||||
@@ -54,6 +55,7 @@ CTX_SETTINGS = dict(help_option_names=["-h", "--help"])
|
||||
@click.version_option(__version__, "--version", "-v")
|
||||
@click.pass_context
|
||||
def cli_main(ctx, db, json_, debug):
|
||||
"""osxphotos: query and export your Photos library"""
|
||||
ctx.obj = CLI_Obj(db=db, json=json_, group=cli_main)
|
||||
|
||||
|
||||
@@ -81,8 +83,10 @@ for command in [
|
||||
run,
|
||||
snap,
|
||||
theme,
|
||||
timewarp,
|
||||
tutorial,
|
||||
uninstall,
|
||||
uuid,
|
||||
version,
|
||||
]:
|
||||
cli_main.add_command(command)
|
||||
|
||||
@@ -22,23 +22,26 @@ __all__ = [
|
||||
|
||||
|
||||
THEME_STYLES = [
|
||||
"bar.back",
|
||||
"bar.complete",
|
||||
"bar.finished",
|
||||
"bar.pulse",
|
||||
"change",
|
||||
"color",
|
||||
"count",
|
||||
"error",
|
||||
"filename",
|
||||
"filepath",
|
||||
"highlight",
|
||||
"no_change",
|
||||
"num",
|
||||
"time",
|
||||
"uuid",
|
||||
"warning",
|
||||
"bar.back",
|
||||
"bar.complete",
|
||||
"bar.finished",
|
||||
"bar.pulse",
|
||||
"progress.elapsed",
|
||||
"progress.percentage",
|
||||
"progress.remaining",
|
||||
"time",
|
||||
"tz",
|
||||
"uuid",
|
||||
"warning",
|
||||
]
|
||||
|
||||
COLOR_THEMES = {
|
||||
@@ -48,23 +51,26 @@ COLOR_THEMES = {
|
||||
tags=["dark"],
|
||||
styles={
|
||||
# color pallette from https://github.com/dracula/dracula-theme
|
||||
"bar.back": Style(color="rgb(68,71,90)"),
|
||||
"bar.complete": Style(color="rgb(249,38,114)"),
|
||||
"bar.finished": Style(color="rgb(80,250,123)"),
|
||||
"bar.pulse": Style(color="rgb(98,114,164)"),
|
||||
"change": Style(color="bright_red", bold=True),
|
||||
"color": Style(color="rgb(248,248,242)"),
|
||||
"count": Style(color="rgb(139,233,253)"),
|
||||
"error": Style(color="rgb(255,85,85)", bold=True),
|
||||
"filename": Style(color="rgb(189,147,249)", bold=True),
|
||||
"filepath": Style(color="rgb(80,250,123)", bold=True),
|
||||
"highlight": Style(color="#000000", bgcolor="#d73a49", bold=True),
|
||||
"no_change": Style(color="bright_green", bold=True),
|
||||
"num": Style(color="rgb(139,233,253)", bold=True),
|
||||
"time": Style(color="rgb(139,233,253)", bold=True),
|
||||
"uuid": Style(color="rgb(255,184,108)"),
|
||||
"warning": Style(color="rgb(241,250,140)", bold=True),
|
||||
"bar.back": Style(color="rgb(68,71,90)"),
|
||||
"bar.complete": Style(color="rgb(249,38,114)"),
|
||||
"bar.finished": Style(color="rgb(80,250,123)"),
|
||||
"bar.pulse": Style(color="rgb(98,114,164)"),
|
||||
"progress.elapsed": Style(color="rgb(139,233,253)"),
|
||||
"progress.percentage": Style(color="rgb(255,121,198)"),
|
||||
"progress.remaining": Style(color="rgb(139,233,253)"),
|
||||
"time": Style(color="rgb(139,233,253)", bold=True),
|
||||
"tz": Style(color="bright_cyan", bold=True),
|
||||
"uuid": Style(color="rgb(255,184,108)"),
|
||||
"warning": Style(color="rgb(241,250,140)", bold=True),
|
||||
# "headers": Style(color="rgb(165,194,97)"),
|
||||
# "options": Style(color="rgb(255,198,109)"),
|
||||
# "metavar": Style(color="rgb(12,125,157)"),
|
||||
@@ -74,23 +80,26 @@ COLOR_THEMES = {
|
||||
name="light",
|
||||
description="Light mode theme",
|
||||
styles={
|
||||
"bar.back": Style(color="grey23"),
|
||||
"bar.complete": Style(color="rgb(249,38,114)"),
|
||||
"bar.finished": Style(color="rgb(114,156,31)"),
|
||||
"bar.pulse": Style(color="rgb(249,38,114)"),
|
||||
"change": "bold dark_red",
|
||||
"color": Style(color="#000000"),
|
||||
"count": Style(color="#005cc5", bold=True),
|
||||
"error": Style(color="#b31d28", bold=True, underline=True, italic=True),
|
||||
"filename": Style(color="#6f42c1", bold=True),
|
||||
"filepath": Style(color="#22863a", bold=True),
|
||||
"highlight": Style(color="#ffffff", bgcolor="#d73a49", bold=True),
|
||||
"no_change": "bold dark_green",
|
||||
"num": Style(color="#005cc5", bold=True),
|
||||
"time": Style(color="#032f62", bold=True),
|
||||
"uuid": Style(color="#d73a49", bold=True),
|
||||
"warning": Style(color="#e36209", bold=True, underline=True, italic=True),
|
||||
"bar.back": Style(color="grey23"),
|
||||
"bar.complete": Style(color="rgb(249,38,114)"),
|
||||
"bar.finished": Style(color="rgb(114,156,31)"),
|
||||
"bar.pulse": Style(color="rgb(249,38,114)"),
|
||||
"progress.elapsed": Style(color="#032f62", bold=True),
|
||||
"progress.percentage": Style(color="#6f42c1", bold=True),
|
||||
"progress.remaining": Style(color="#032f62", bold=True),
|
||||
"time": Style(color="#032f62", bold=True),
|
||||
"tz": "bold cyan",
|
||||
"uuid": Style(color="#d73a49", bold=True),
|
||||
"warning": Style(color="#e36209", bold=True, underline=True, italic=True),
|
||||
# "headers": Style(color="rgb(254,212,66)"),
|
||||
# "options": Style(color="rgb(227,98,9)"),
|
||||
# "metavar": Style(color="rgb(111,66,193)"),
|
||||
@@ -101,22 +110,25 @@ COLOR_THEMES = {
|
||||
description="Monochromatic theme",
|
||||
tags=["mono", "colorblind"],
|
||||
styles={
|
||||
"bar.back": "",
|
||||
"bar.complete": "reverse",
|
||||
"bar.finished": "bold",
|
||||
"bar.pulse": "bold",
|
||||
"change": "reverse",
|
||||
"count": "bold",
|
||||
"error": "reverse italic",
|
||||
"filename": "bold",
|
||||
"filepath": "bold underline",
|
||||
"highlight": "reverse italic",
|
||||
"no_change": "",
|
||||
"num": "bold",
|
||||
"time": "bold",
|
||||
"uuid": "bold",
|
||||
"warning": "bold italic",
|
||||
"bar.back": "",
|
||||
"bar.complete": "reverse",
|
||||
"bar.finished": "bold",
|
||||
"bar.pulse": "bold",
|
||||
"progress.elapsed": "",
|
||||
"progress.percentage": "bold",
|
||||
"progress.remaining": "bold",
|
||||
"time": "bold",
|
||||
"tz": "",
|
||||
"uuid": "bold",
|
||||
"warning": "bold italic",
|
||||
# "headers": "bold",
|
||||
# "options": "bold",
|
||||
# "metavar": "bold",
|
||||
@@ -127,23 +139,26 @@ COLOR_THEMES = {
|
||||
description="Plain theme with no colors",
|
||||
tags=["colorblind"],
|
||||
styles={
|
||||
"bar.back": "",
|
||||
"bar.complete": "",
|
||||
"bar.finished": "",
|
||||
"bar.pulse": "",
|
||||
"change": "",
|
||||
"color": "",
|
||||
"count": "",
|
||||
"error": "",
|
||||
"filename": "",
|
||||
"filepath": "",
|
||||
"highlight": "",
|
||||
"no_change": "",
|
||||
"num": "",
|
||||
"time": "",
|
||||
"uuid": "",
|
||||
"warning": "",
|
||||
"bar.back": "",
|
||||
"bar.complete": "",
|
||||
"bar.finished": "",
|
||||
"bar.pulse": "",
|
||||
"progress.elapsed": "",
|
||||
"progress.percentage": "",
|
||||
"progress.remaining": "",
|
||||
"time": "",
|
||||
"tz": "",
|
||||
"uuid": "",
|
||||
"warning": "",
|
||||
# "headers": "",
|
||||
# "options": "",
|
||||
# "metavar": "",
|
||||
@@ -162,7 +177,9 @@ def get_theme_dir() -> pathlib.Path:
|
||||
|
||||
def get_theme_manager() -> ThemeManager:
|
||||
"""Return theme manager instance"""
|
||||
return ThemeManager(theme_dir=str(get_theme_dir()), themes=COLOR_THEMES.values())
|
||||
return ThemeManager(
|
||||
theme_dir=str(get_theme_dir()), themes=COLOR_THEMES.values(), update=True
|
||||
)
|
||||
|
||||
|
||||
def get_theme(
|
||||
|
||||
@@ -6,10 +6,12 @@ import pathlib
|
||||
from datetime import datetime
|
||||
|
||||
import click
|
||||
from packaging import version
|
||||
|
||||
import osxphotos
|
||||
from osxphotos._constants import APP_NAME
|
||||
from osxphotos._version import __version__
|
||||
from osxphotos.utils import get_latest_version
|
||||
|
||||
from .param_types import *
|
||||
|
||||
@@ -85,10 +87,12 @@ def get_photos_db(*db_options):
|
||||
return None
|
||||
|
||||
|
||||
VERSION_CHECK_OPTION = click.option("--no-version-check", required=False, is_flag=True)
|
||||
|
||||
DB_OPTION = click.option(
|
||||
"--db",
|
||||
required=False,
|
||||
metavar="<Photos database path>",
|
||||
metavar="PHOTOS_LIBRARY_PATH",
|
||||
default=None,
|
||||
help=(
|
||||
"Specify Photos database path. "
|
||||
@@ -547,8 +551,22 @@ def load_uuid_from_file(filename):
|
||||
|
||||
|
||||
def get_config_dir() -> pathlib.Path:
|
||||
"""Get the directory where config files are stored."""
|
||||
"""Get the directory where config files are stored; create it if necessary."""
|
||||
config_dir = pathlib.Path.home() / ".config" / APP_NAME
|
||||
if not config_dir.is_dir():
|
||||
config_dir.mkdir(parents=True)
|
||||
return config_dir
|
||||
|
||||
|
||||
def check_version():
|
||||
"""Check for updates"""
|
||||
latest_version, _ = get_latest_version()
|
||||
if latest_version and version.parse(latest_version) > version.parse(__version__):
|
||||
click.echo(
|
||||
f"New version {latest_version} available; you are running {__version__}\n"
|
||||
"Run `pipx upgrade osxphotos` to upgrade.\n"
|
||||
"Use --no-version-check or set environment variable OSXPHOTOS_NO_VERSION_CHECK=1 "
|
||||
"to suppress this message and prevent osxphotos from checking for latest version.",
|
||||
err=True,
|
||||
)
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
import pathlib
|
||||
import shutil
|
||||
import zipfile
|
||||
from typing import Optional
|
||||
|
||||
import click
|
||||
@@ -18,14 +19,11 @@ def docs(ctx, cli_obj):
|
||||
"""Open osxphotos documentation in your browser."""
|
||||
|
||||
docs_dir = get_config_dir() / "docs"
|
||||
if not docs_dir.exists():
|
||||
docs_dir.mkdir(parents=True)
|
||||
|
||||
docs_version = get_docs_version(docs_dir)
|
||||
if not docs_version or docs_version != __version__:
|
||||
click.echo(f"Copying docs for osxphotos version {__version__}")
|
||||
shutil.rmtree(str(docs_dir), ignore_errors=True)
|
||||
copy_docs(docs_dir)
|
||||
copy_docs()
|
||||
|
||||
cli_docs = docs_dir / "index.html"
|
||||
click.echo(f"Opening {cli_docs}")
|
||||
@@ -46,17 +44,22 @@ def get_docs_version(docs_dir: pathlib.Path) -> Optional[str]:
|
||||
return f.read().strip()
|
||||
|
||||
|
||||
def copy_docs(docs_dir: pathlib.Path):
|
||||
"""Copy the latest docs to the docs directory"""
|
||||
def copy_docs():
|
||||
"""Copy the latest docs to the config directory"""
|
||||
# there must be a better way to do this
|
||||
# docs are in osxphotos/docs and this file is in osxphotos/cli
|
||||
src_dir = pathlib.Path(__file__).parent.parent / "docs"
|
||||
shutil.copytree(str(src_dir), str(docs_dir))
|
||||
set_docs_version(docs_dir, __version__)
|
||||
docs_zip = src_dir / "docs.zip"
|
||||
config_dir = get_config_dir()
|
||||
with zipfile.ZipFile(str(docs_zip), "r") as zf:
|
||||
zf.extractall(path=str(config_dir))
|
||||
set_docs_version(config_dir / "docs", __version__)
|
||||
|
||||
|
||||
def set_docs_version(docs_dir: pathlib.Path, version: str):
|
||||
"""Set the version of the docs directory"""
|
||||
if not docs_dir.exists():
|
||||
docs_dir.mkdir(parents=True)
|
||||
version_file = docs_dir / ".version"
|
||||
if version_file.exists():
|
||||
version_file.unlink()
|
||||
|
||||
@@ -505,7 +505,7 @@ from .verbose import get_verbose_console, time_stamp, verbose_print
|
||||
)
|
||||
@click.option(
|
||||
"--report",
|
||||
metavar="<path to export report>",
|
||||
metavar="REPORT_FILE",
|
||||
help="Write a CSV formatted report of all files that were exported.",
|
||||
type=click.Path(),
|
||||
)
|
||||
@@ -600,7 +600,7 @@ from .verbose import get_verbose_console, time_stamp, verbose_print
|
||||
@click.option(
|
||||
"--load-config",
|
||||
required=False,
|
||||
metavar="<config file path>",
|
||||
metavar="CONFIG_FILE",
|
||||
default=None,
|
||||
help=(
|
||||
"Load options from file as written with --save-config. "
|
||||
@@ -615,7 +615,7 @@ from .verbose import get_verbose_console, time_stamp, verbose_print
|
||||
@click.option(
|
||||
"--save-config",
|
||||
required=False,
|
||||
metavar="<config file path>",
|
||||
metavar="CONFIG_FILE",
|
||||
default=None,
|
||||
help="Save options to file for use with --load-config. File format is TOML. "
|
||||
"See also --config-only.",
|
||||
|
||||
@@ -5,19 +5,26 @@ import pathlib
|
||||
|
||||
import bitmath
|
||||
import click
|
||||
import pytimeparse
|
||||
|
||||
from osxphotos.export_db_utils import export_db_get_version
|
||||
from osxphotos.photoinfo import PhotoInfoNone
|
||||
from osxphotos.phototemplate import PhotoTemplate, RenderOptions
|
||||
from osxphotos.timeutils import time_string_to_datetime, utc_offset_string_to_seconds
|
||||
from osxphotos.timezones import Timezone
|
||||
from osxphotos.utils import expand_and_validate_filepath, load_function
|
||||
|
||||
__all__ = [
|
||||
"BitMathSize",
|
||||
"DateOffset",
|
||||
"DateTimeISO8601",
|
||||
"ExportDBType",
|
||||
"FunctionCall",
|
||||
"TimeISO8601",
|
||||
"TemplateString",
|
||||
"TimeISO8601",
|
||||
"TimeOffset",
|
||||
"TimeString",
|
||||
"UTCOffset",
|
||||
]
|
||||
|
||||
|
||||
@@ -129,3 +136,75 @@ class TemplateString(click.ParamType):
|
||||
return value
|
||||
except ValueError as e:
|
||||
self.fail(e)
|
||||
|
||||
|
||||
class TimeString(click.ParamType):
|
||||
"""A timestring in format HH:MM:SS, HH:MM:SS.fff, HH:MM"""
|
||||
|
||||
name = "TIMESTRING"
|
||||
|
||||
def convert(self, value, param, ctx):
|
||||
try:
|
||||
return time_string_to_datetime(value)
|
||||
except ValueError:
|
||||
self.fail(
|
||||
f"Invalid time format: {value}. "
|
||||
"Valid format for time: 'HH:MM:SS', 'HH:MM:SS.fff', 'HH:MM'"
|
||||
)
|
||||
|
||||
|
||||
class DateOffset(click.ParamType):
|
||||
"""A date offset string in the format ±D days, ±W weeks, ±Y years, ±D where D is days"""
|
||||
|
||||
name = "DATEOFFSET"
|
||||
|
||||
def convert(self, value, param, ctx):
|
||||
offset = pytimeparse.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 "
|
||||
)
|
||||
|
||||
|
||||
class TimeOffset(click.ParamType):
|
||||
"""A time offset string in the format [+-]HH:MM[:SS[.fff[fff]]] or +1 days, -2 hours, -18000, etc"""
|
||||
|
||||
name = "TIMEOFFSET"
|
||||
|
||||
def convert(self, value, param, ctx):
|
||||
offset = pytimeparse.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)"
|
||||
)
|
||||
|
||||
|
||||
class UTCOffset(click.ParamType):
|
||||
"""A UTC offset timezone in format ±[hh]:[mm], ±[h]:[mm], or ±[hh][mm]"""
|
||||
|
||||
name = "UTC_OFFSET"
|
||||
|
||||
def convert(self, value, param, ctx):
|
||||
try:
|
||||
offset_seconds = utc_offset_string_to_seconds(value)
|
||||
return Timezone(offset_seconds)
|
||||
except Exception:
|
||||
self.fail(
|
||||
f"Invalid timezone format: {value}. "
|
||||
"Valid format for timezone offset: '±HH:MM', '±H:MM', or '±HHMM'"
|
||||
)
|
||||
|
||||
695
osxphotos/cli/timewarp.py
Normal file
695
osxphotos/cli/timewarp.py
Normal file
@@ -0,0 +1,695 @@
|
||||
""" Fix time / date / timezone for photos in Apple Photos """
|
||||
|
||||
import datetime
|
||||
import os
|
||||
import sys
|
||||
from functools import partial
|
||||
from textwrap import dedent
|
||||
from typing import Callable, Optional
|
||||
|
||||
import click
|
||||
from photoscript import Photo, PhotosLibrary
|
||||
from rich.console import Console
|
||||
|
||||
from osxphotos._constants import APP_NAME
|
||||
from osxphotos.compare_exif import PhotoCompare
|
||||
from osxphotos.datetime_utils import datetime_naive_to_local, datetime_to_new_tz
|
||||
from osxphotos.exif_datetime_updater import ExifDateTimeUpdater
|
||||
from osxphotos.exiftool import get_exiftool_path
|
||||
from osxphotos.photosalbum import PhotosAlbumPhotoScript
|
||||
from osxphotos.phototz import PhotoTimeZone, PhotoTimeZoneUpdater
|
||||
from osxphotos.timeutils import update_datetime
|
||||
from osxphotos.timezones import Timezone
|
||||
from osxphotos.utils import noop, pluralize
|
||||
|
||||
from .click_rich_echo import (
|
||||
rich_click_echo,
|
||||
rich_echo,
|
||||
rich_echo_error,
|
||||
set_rich_console,
|
||||
set_rich_theme,
|
||||
set_rich_timestamp,
|
||||
)
|
||||
from .color_themes import get_theme
|
||||
from .common import THEME_OPTION
|
||||
from .darkmode import is_dark_mode
|
||||
from .help import HELP_WIDTH, rich_text
|
||||
from .param_types import (
|
||||
DateOffset,
|
||||
DateTimeISO8601,
|
||||
FunctionCall,
|
||||
TimeOffset,
|
||||
TimeString,
|
||||
UTCOffset,
|
||||
)
|
||||
from .rich_progress import rich_progress
|
||||
from .verbose import get_verbose_console, verbose_print
|
||||
|
||||
# format for pretty printing date/times
|
||||
DATETIME_FORMAT = "%Y-%m-%d %H:%M:%S%z"
|
||||
|
||||
|
||||
def update_photo_date_time(
|
||||
photo: Photo,
|
||||
date,
|
||||
time,
|
||||
date_delta,
|
||||
time_delta,
|
||||
verbose_print: Callable,
|
||||
):
|
||||
"""Update date, time in photo"""
|
||||
photo_date = photo.date
|
||||
new_photo_date = update_datetime(
|
||||
photo_date, date=date, time=time, date_delta=date_delta, time_delta=time_delta
|
||||
)
|
||||
filename = photo.filename
|
||||
uuid = photo.uuid
|
||||
if new_photo_date != photo_date:
|
||||
photo.date = new_photo_date
|
||||
verbose_print(
|
||||
f"Updated date/time for photo [filename]{filename}[/filename] "
|
||||
f"([uuid]{uuid}[/uuid]) from: [time]{photo_date}[/time] to [time]{new_photo_date}[/time]"
|
||||
)
|
||||
else:
|
||||
verbose_print(
|
||||
f"Skipped date/time update for photo [filename]{filename}[/filename] "
|
||||
f"([uuid]{uuid}[/uuid]): nothing to do"
|
||||
)
|
||||
|
||||
|
||||
def update_photo_time_for_new_timezone(
|
||||
library_path: str,
|
||||
photo: Photo,
|
||||
new_timezone: Timezone,
|
||||
verbose_print: Callable,
|
||||
):
|
||||
"""Update time in photo to keep it the same time but in a new timezone
|
||||
|
||||
For example, photo time is 12:00+0100 and new timezone is +0200,
|
||||
so adjust photo time by 1 hour so it will now be 12:00+0200 instead of
|
||||
13:00+0200 as it would be with no adjustment to the time"""
|
||||
old_timezone = PhotoTimeZone(library_path=library_path).get_timezone(photo)[0]
|
||||
# need to move time in opposite direction of timezone offset so that
|
||||
# photo time is the same time but in the new timezone
|
||||
delta = old_timezone - new_timezone.offset
|
||||
photo_date = photo.date
|
||||
new_photo_date = update_datetime(
|
||||
dt=photo_date, time_delta=datetime.timedelta(seconds=delta)
|
||||
)
|
||||
filename = photo.filename
|
||||
uuid = photo.uuid
|
||||
if photo_date != new_photo_date:
|
||||
photo.date = new_photo_date
|
||||
verbose_print(
|
||||
f"Adjusted date/time for photo [filename]{filename}[/filename] ([uuid]{uuid}[/uuid]) to match "
|
||||
f"previous time [time]{photo_date}[time] but in new timezone [tz]{new_timezone}[/tz]."
|
||||
)
|
||||
else:
|
||||
verbose_print(
|
||||
f"Skipping date/time update for photo [filename]{filename}[/filename] ([uuid]{photo.uuid}[/uuid]), "
|
||||
f"already matches new timezone [tz]{new_timezone}[/tz]"
|
||||
)
|
||||
|
||||
|
||||
def update_photo_from_function(
|
||||
library_path: str,
|
||||
function: Callable,
|
||||
verbose_print: Callable,
|
||||
photo: Photo,
|
||||
path: Optional[str],
|
||||
):
|
||||
"""Update photo from function call"""
|
||||
photo_tz_sec, _, photo_tz_name = PhotoTimeZone(
|
||||
library_path=library_path
|
||||
).get_timezone(photo)
|
||||
dt_new, tz_new = function(
|
||||
photo=photo,
|
||||
path=path,
|
||||
tz_sec=photo_tz_sec,
|
||||
tz_name=photo_tz_name,
|
||||
verbose=verbose_print,
|
||||
)
|
||||
if dt_new != photo.date:
|
||||
old_date = photo.date
|
||||
photo.date = dt_new
|
||||
verbose_print(
|
||||
f"Updated date/time for photo [filename]{photo.filename}[/filename] "
|
||||
f"([uuid]{photo.uuid}[/uuid]) from: [time]{old_date}[/time] to [time]{dt_new}[/time]"
|
||||
)
|
||||
else:
|
||||
verbose_print(
|
||||
f"Skipped date/time update for photo [filename]{photo.filename}[/filename] "
|
||||
f"([uuid]{photo.uuid}[/uuid]): nothing to do"
|
||||
)
|
||||
if tz_new != photo_tz_sec:
|
||||
tz_updater = PhotoTimeZoneUpdater(
|
||||
timezone=Timezone(tz_new), verbose=verbose_print, library_path=library_path
|
||||
)
|
||||
tz_updater.update_photo(photo)
|
||||
else:
|
||||
verbose_print(
|
||||
f"Skipped timezone update for photo [filename]{photo.filename}[/filename] "
|
||||
f"([uuid]{photo.uuid}[/uuid]): nothing to do"
|
||||
)
|
||||
|
||||
|
||||
class TimeWarpCommand(click.Command):
|
||||
"""Custom click.Command that overrides get_help() to show additional help info for export"""
|
||||
|
||||
def get_help(self, ctx):
|
||||
help_text = super().get_help(ctx)
|
||||
formatter = click.HelpFormatter(width=HELP_WIDTH)
|
||||
formatter.write("\n\n")
|
||||
formatter.write(
|
||||
rich_text(
|
||||
dedent(
|
||||
"""
|
||||
# Timewarp Overview
|
||||
|
||||
Timewarp operates on photos selected in Apple Photos. To use it, open Photos, select the photos for which you'd like to adjust the date/time/timezone, then run osxphotos timewarp from the command line:
|
||||
|
||||
`osxphotos timewarp --date 2021-09-10 --time-delta "-1 hour" --timezone -0700 --verbose`
|
||||
|
||||
This example sets the date for all selected photos to `2021-09-10`, subtracts 1 hour from the time of each photo, and sets the timezone of each photo to `GMT -07:00` (Pacific Daylight Time).
|
||||
|
||||
osxphotos timewarp has been well tested on macOS Catalina (10.15). It should work on macOS Big Sur (11.0) and macOS Monterey (12.0) but I have not been able to test this. It will not work on macOS Mojave (10.14) or earlier as the Photos database format is different.
|
||||
|
||||
**Caution**: This app directly modifies your Photos library database using undocumented features. It may corrupt, damage, or destroy your Photos library. Use at your own caution. I strongly recommend you make a backup of your Photos library before using this script (e.g. use Time Machine).
|
||||
|
||||
## Examples
|
||||
|
||||
**Add 1 day to the date of each photo**
|
||||
|
||||
`osxphotos timewarp --date-delta 1`
|
||||
|
||||
or
|
||||
|
||||
`osxphotos timewarp --date-delta "+1 day"`
|
||||
|
||||
**Set the date of each photo to 23 April 2020 and add 3 hours to the time**
|
||||
|
||||
`osxphotos timewarp --date 2020-04-23 --time-delta "+3 hours"`
|
||||
|
||||
or
|
||||
|
||||
`osxphotos timewarp --date 2020-04-23 --time-delta "+03:00:00"`
|
||||
|
||||
**Set the time of each photo to 14:30 and set the timezone to UTC +1:00 (Central European Time)**
|
||||
|
||||
`osxphotos timewarp --time 14:30 --timezone +01:00`
|
||||
|
||||
or
|
||||
|
||||
`osxphotos timewarp --time 14:30 --timezone +0100`
|
||||
|
||||
**Subtract 1 week from the date for each photo, add 3 hours to the time, set the timezone to UTC -07:00 (Pacific Daylight Time) and also use exiftool to update the EXIF metadata accordingly in the original file; use --verbose to print additional details**
|
||||
|
||||
`osxphotos timewarp --date-delta "-1 week" --time-delta "+3 hours" --timezone -0700 --push-exif --verbose`
|
||||
|
||||
For this to work, you'll need to install the third-party exiftool (https://exiftool.org/) utility. If you use homebrew (https://brew.sh/) you can do this with `brew install exiftool`.
|
||||
|
||||
**Set the timezone to UTC +03:00 for each photo but keep the time the same (that is, don't adjust time for the new timezone)**
|
||||
|
||||
`osxphotos timewarp --timezone 0300 --match-time`
|
||||
|
||||
*Note on timezones and times*: In Photos, when you change the timezone, Photos assumes the time itself was correct for the previous timezone and adjusts the time accordingly to the new timezone. E.g. if the photo's time is `13:00` and the timezone is `GMT -07:00` and you adjust the timezone one hour east to `GMT -06:00`, Photos will change the time of the photo to `14:00`. osxphotos timewarp follows this behavior. Using `--match-time` allows you to adjust the timezone but keep the same time without adjustment. For example, if your camera clock was correct but lacked timezone information and you took photos in one timezone but imported them to photos in another, Photos will add the timezone of the computer at time of import. You can use osxphotos timewarp to adjust the timezone but keep the time using `--match-time`.
|
||||
|
||||
**Compare the date/time/timezone of selected photos with the date/time/timezone in the photos' original EXIF metadata**
|
||||
|
||||
`osxphotos timewarp --compare-exif`
|
||||
|
||||
**Read the date/time/timezone from the photos' original EXIF metadata to update the photos' date/time/timezone;
|
||||
if the EXIF data is missing, use the file modification date/time; show verbose output**
|
||||
|
||||
`osxphotos timewarp --pull-exif --use-file-time --verbose`
|
||||
|
||||
"""
|
||||
),
|
||||
width=formatter.width,
|
||||
markdown=True,
|
||||
)
|
||||
)
|
||||
help_text += formatter.getvalue()
|
||||
return help_text
|
||||
|
||||
|
||||
@click.command(cls=TimeWarpCommand, name="timewarp")
|
||||
@click.option(
|
||||
"--date",
|
||||
"-d",
|
||||
metavar="DATE",
|
||||
type=DateTimeISO8601(),
|
||||
help="Set date for selected photos. Format is 'YYYY-MM-DD'.",
|
||||
)
|
||||
@click.option(
|
||||
"--date-delta",
|
||||
"-D",
|
||||
metavar="DELTA",
|
||||
type=DateOffset(),
|
||||
help="Adjust date for selected photos by DELTA. "
|
||||
"Format is one of: '±D days', '±W weeks', '±D' where D is days",
|
||||
)
|
||||
@click.option(
|
||||
"--time",
|
||||
"-t",
|
||||
metavar="TIME",
|
||||
type=TimeString(),
|
||||
help="Set time for selected photos. Format is one of 'HH:MM:SS', 'HH:MM:SS.fff', 'HH:MM'.",
|
||||
)
|
||||
@click.option(
|
||||
"--time-delta",
|
||||
"-T",
|
||||
metavar="DELTA",
|
||||
type=TimeOffset(),
|
||||
help="Adjust time for selected photos by DELTA time. "
|
||||
"Format is one of '±HH:MM:SS', '±H hours' (or hr), '±M minutes' (or min), '±S seconds' (or sec), '±S' (where S is seconds)",
|
||||
)
|
||||
@click.option(
|
||||
"--timezone",
|
||||
"-z",
|
||||
metavar="TIMEZONE",
|
||||
type=UTCOffset(),
|
||||
help="Set timezone for selected photos as offset from UTC. "
|
||||
"Format is one of '±HH:MM', '±H:MM', or '±HHMM'. "
|
||||
"The actual time of the photo is not adjusted which means, somewhat counterintuitively, "
|
||||
"that the time in the new timezone will be different. "
|
||||
"For example, if photo has time of 12:00 and timezone of GMT+01:00 and new timezone is specified as "
|
||||
"'--timezone +02:00' (one hour ahead of current GMT+01:00 timezone), the photo's new time will be 13:00 GMT+02:00, "
|
||||
"which is equivalent to the old time of 12:00+01:00. "
|
||||
"This is the same behavior exhibited by Photos when manually adjusting timezone in the Get Info window. "
|
||||
"See also --match-time. ",
|
||||
)
|
||||
@click.option(
|
||||
"--inspect",
|
||||
"-i",
|
||||
is_flag=True,
|
||||
help="Print out the date/time/timezone for each selected photo without changing any information.",
|
||||
)
|
||||
@click.option(
|
||||
"--compare-exif",
|
||||
"-c",
|
||||
is_flag=True,
|
||||
help="Compare the EXIF date/time/timezone for each selected photo to the same data in Photos. "
|
||||
"Requires the third-party exiftool utility be installed (see https://exiftool.org/). "
|
||||
"See also --add-to-album.",
|
||||
)
|
||||
@click.option(
|
||||
"--push-exif",
|
||||
"-p",
|
||||
is_flag=True,
|
||||
help="Push date/time and timezone for selected photos from Photos to the "
|
||||
"EXIF metadata in the original file in the Photos library. "
|
||||
"Requires the third-party exiftool utility be installed (see https://exiftool.org/). "
|
||||
"Using this option modifies the *original* file of the image in your Photos library. "
|
||||
"--push-exif will be executed after any other updates are performed on the photo. "
|
||||
"See also --pull-exif.",
|
||||
)
|
||||
@click.option(
|
||||
"--pull-exif",
|
||||
"-P",
|
||||
is_flag=True,
|
||||
help="Pull date/time and timezone for selected photos from EXIF metadata in the original file "
|
||||
"into Photos and update the associated data in Photos to match the EXIF data. "
|
||||
"--pull-exif will be executed before any other updates are performed on the photo. "
|
||||
"It is possible for images to have missing EXIF data, for example the date/time could be set but there might be "
|
||||
"no timezone set in the EXIF metadata. "
|
||||
"Missing data will be handled thusly: if date/time/timezone are all present in the EXIF data, "
|
||||
"the photo's date/time/timezone will be updated. If timezone is missing but date/time is present, "
|
||||
"only the photo's date/time will be updated. If date/time is missing but the timezone is present, only the "
|
||||
"photo's timezone will be updated unless --use-file-time is set in which case, "
|
||||
"the photo's file modification date/time will be used in place of EXIF date/time. "
|
||||
"If the date is present but the time is missing, the time will be set to 00:00:00. "
|
||||
"Requires the third-party exiftool utility be installed (see https://exiftool.org/). "
|
||||
"See also --push-exif.",
|
||||
)
|
||||
@click.option(
|
||||
"--function",
|
||||
"-F",
|
||||
metavar="filename.py::function",
|
||||
nargs=1,
|
||||
type=FunctionCall(),
|
||||
multiple=False,
|
||||
help="Run python function to determine the date/time/timezone to apply to a photo. "
|
||||
"Use this in format: --function filename.py::function where filename.py is a python "
|
||||
"file you've created and function is the name of the function in the python file you want to call. The function will be "
|
||||
"passed information about the photo being processed and is expected to return "
|
||||
"a naive datetime.datetime object with time in local time and UTC timezone offset in seconds. "
|
||||
"See example function at https://github.com/RhetTbull/osxphotos/blob/master/examples/timewarp_function_example.py",
|
||||
)
|
||||
@click.option(
|
||||
"--match-time",
|
||||
"-m",
|
||||
is_flag=True,
|
||||
help="When used with --timezone, adjusts the photo time so that the timestamp in the new timezone matches "
|
||||
"the timestamp in the old timezone. "
|
||||
"For example, if photo has time of 12:00 and timezone of GMT+01:00 and new timezone is specified as "
|
||||
"'--timezone +02:00' (one hour ahead of current GMT+01:00 timezone), the photo's new time will be 12:00 GMT+02:00. "
|
||||
"That is, the timezone will have changed but the timestamp of the photo will match the previous timestamp. "
|
||||
"Use --match-time when the camera's time was correct for the time the photo was taken but the "
|
||||
"timezone was missing or wrong and you want to adjust the timezone while preserving the photo's time. "
|
||||
"See also --timezone.",
|
||||
)
|
||||
@click.option(
|
||||
"--use-file-time",
|
||||
"-f",
|
||||
is_flag=True,
|
||||
help="When used with --pull-exif, the file modification date/time will be used if date/time "
|
||||
"is missing from the EXIF data. ",
|
||||
)
|
||||
@click.option(
|
||||
"--add-to-album",
|
||||
"-a",
|
||||
metavar="ALBUM",
|
||||
help="When used with --compare-exif, adds any photos with date/time/timezone differences "
|
||||
"between Photos/EXIF to album ALBUM. If ALBUM does not exist, it will be created.",
|
||||
)
|
||||
@click.option("--verbose", "-V", "verbose", is_flag=True, help="Show verbose output.")
|
||||
@click.option(
|
||||
"--library",
|
||||
"-L",
|
||||
metavar="PHOTOS_LIBRARY_PATH",
|
||||
type=click.Path(),
|
||||
help=r"Path to Photos library (e.g. '~/Pictures/Photos\ Library.photoslibrary'). "
|
||||
f"This is not likely needed as {APP_NAME} will usually be able to locate the path to the open Photos library. "
|
||||
"Use --library only if you get an error that the Photos library cannot be located.",
|
||||
)
|
||||
@click.option(
|
||||
"--exiftool-path",
|
||||
"-e",
|
||||
type=click.Path(exists=True),
|
||||
help="Optional path to exiftool executable (will look in $PATH if not specified) for those options which require exiftool.",
|
||||
)
|
||||
@click.option(
|
||||
"--output-file",
|
||||
"-o",
|
||||
type=click.File(mode="w", lazy=False),
|
||||
help="Output file. If not specified, output is written to stdout.",
|
||||
)
|
||||
@click.option(
|
||||
"--terminal-width",
|
||||
"-w",
|
||||
type=int,
|
||||
help="Terminal width in characters.",
|
||||
hidden=True,
|
||||
)
|
||||
@click.option("--timestamp", is_flag=True, help="Add time stamp to verbose output")
|
||||
@THEME_OPTION
|
||||
@click.option(
|
||||
"--plain",
|
||||
is_flag=True,
|
||||
help="Plain text mode. Do not use rich output.",
|
||||
)
|
||||
@click.option(
|
||||
"--force",
|
||||
is_flag=True,
|
||||
help="Bypass confirmation prompt. Use with caution.",
|
||||
)
|
||||
def timewarp(
|
||||
date,
|
||||
date_delta,
|
||||
time,
|
||||
time_delta,
|
||||
timezone,
|
||||
inspect,
|
||||
compare_exif,
|
||||
push_exif,
|
||||
pull_exif,
|
||||
function,
|
||||
match_time,
|
||||
use_file_time,
|
||||
add_to_album,
|
||||
exiftool_path,
|
||||
verbose,
|
||||
library,
|
||||
theme,
|
||||
plain,
|
||||
output_file,
|
||||
terminal_width,
|
||||
timestamp,
|
||||
force,
|
||||
):
|
||||
"""Adjust date/time/timezone of photos in Apple Photos.
|
||||
|
||||
Changes will be applied to all photos currently selected in Photos.
|
||||
timewarp cannot operate on photos selected in a Smart Album;
|
||||
select photos in a regular album or in the 'All Photos' view.
|
||||
See Timewarp Overview below for additional information.
|
||||
"""
|
||||
|
||||
# check constraints
|
||||
if not any(
|
||||
[
|
||||
date,
|
||||
date_delta,
|
||||
time,
|
||||
time_delta,
|
||||
timezone,
|
||||
inspect,
|
||||
compare_exif,
|
||||
push_exif,
|
||||
pull_exif,
|
||||
function,
|
||||
]
|
||||
):
|
||||
raise click.UsageError(
|
||||
"At least one of --date, --date-delta, --time, --time-delta, "
|
||||
"--timezone, --inspect, --compare-exif, --push-exif, --pull-exif, --function "
|
||||
"must be specified."
|
||||
)
|
||||
|
||||
if date and date_delta:
|
||||
raise click.UsageError("--date and --date-delta are mutually exclusive.")
|
||||
|
||||
if time and time_delta:
|
||||
raise click.UsageError("--time and --time-delta are mutually exclusive.")
|
||||
|
||||
if match_time and not timezone:
|
||||
raise click.UsageError("--match-time must be used with --timezone.")
|
||||
|
||||
if add_to_album and not compare_exif:
|
||||
raise click.UsageError("--add-to-album must be used with --compare-exif.")
|
||||
|
||||
# configure colored rich output
|
||||
# TODO: this is all a little hacky, find a better way to do this
|
||||
color_theme = get_theme(theme)
|
||||
verbose_ = verbose_print(
|
||||
verbose,
|
||||
timestamp,
|
||||
rich=True,
|
||||
theme=color_theme,
|
||||
highlight=False,
|
||||
file=output_file,
|
||||
)
|
||||
# set console for rich_echo to be same as for verbose_
|
||||
terminal_width = terminal_width or (1000 if output_file else None)
|
||||
if output_file:
|
||||
set_rich_console(Console(file=output_file, width=terminal_width))
|
||||
elif terminal_width:
|
||||
set_rich_console(
|
||||
Console(
|
||||
file=sys.stdout,
|
||||
theme=color_theme,
|
||||
force_terminal=True,
|
||||
width=terminal_width,
|
||||
)
|
||||
)
|
||||
else:
|
||||
set_rich_console(get_verbose_console(theme=color_theme))
|
||||
set_rich_theme(color_theme)
|
||||
|
||||
if any([compare_exif, push_exif, pull_exif]):
|
||||
exiftool_path = exiftool_path or get_exiftool_path()
|
||||
verbose_(f"exiftool path: [filename]{exiftool_path}[/filename]")
|
||||
|
||||
try:
|
||||
photos = PhotosLibrary().selection
|
||||
if not photos:
|
||||
rich_echo_error("[warning]No photos selected[/]")
|
||||
sys.exit(0)
|
||||
except Exception as e:
|
||||
# AppleScript error -1728 occurs if user attempts to get selected photos in a Smart Album
|
||||
if "(-1728)" in str(e):
|
||||
rich_echo_error(
|
||||
"[error]Could not get selected photos. Ensure photos is open and photos are selected. "
|
||||
"If you have selected photos and you see this message, it may be because the selected photos are in a Photos Smart Album. "
|
||||
f"{APP_NAME} cannot access photos in a Smart Album. Select the photos in a regular album or in 'All Photos' view. "
|
||||
"Another option is to create a new album using 'File | New Album With Selection' then select the photos in the new album.[/]",
|
||||
)
|
||||
else:
|
||||
rich_echo_error(
|
||||
f"[error]Could not get selected photos. Ensure Photos is open and photos to process are selected. {e}[/]",
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
# confirm with user before proceeding
|
||||
if (
|
||||
any(
|
||||
[
|
||||
date,
|
||||
date_delta,
|
||||
time,
|
||||
time_delta,
|
||||
timezone,
|
||||
push_exif,
|
||||
pull_exif,
|
||||
function,
|
||||
]
|
||||
)
|
||||
and not force
|
||||
):
|
||||
click.confirm(
|
||||
rich_text(
|
||||
f":warning-emoji: About to process [num]{len(photos)}[/] {pluralize(len(photos), 'photo', 'photos')} with timewarp. "
|
||||
"This will directly modify your Photos library database using undocumented features. "
|
||||
"While this functionality has been well tested, it is possible this may "
|
||||
"corrupt, damage, or destroy your Photos library. [bold]Use at your own caution. No warranty is implied or provided.[/] "
|
||||
"It is strongly recommended you make a backup of your Photos library before using the timewarp command "
|
||||
"(for example, using Time Machine).\n\n"
|
||||
"Proceed with timewarp?"
|
||||
),
|
||||
abort=True,
|
||||
)
|
||||
|
||||
update_photo_date_time_ = partial(
|
||||
update_photo_date_time,
|
||||
date=date,
|
||||
time=time,
|
||||
date_delta=date_delta,
|
||||
time_delta=time_delta,
|
||||
verbose_print=verbose_,
|
||||
)
|
||||
|
||||
update_photo_time_for_new_timezone_ = partial(
|
||||
update_photo_time_for_new_timezone,
|
||||
library_path=library,
|
||||
verbose_print=verbose_,
|
||||
)
|
||||
|
||||
if function:
|
||||
update_photo_from_function_ = partial(
|
||||
update_photo_from_function,
|
||||
library_path=library,
|
||||
function=function[0],
|
||||
verbose_print=verbose_,
|
||||
)
|
||||
else:
|
||||
update_photo_from_function_ = noop
|
||||
|
||||
if inspect:
|
||||
tzinfo = PhotoTimeZone(library_path=library)
|
||||
if photos:
|
||||
rich_echo(
|
||||
"[filename]filename[/filename], [uuid]uuid[/uuid], [time]photo time (local)[/time], [time]photo time[/time], [tz]timezone offset[/tz], [tz]timezone name[/tz]"
|
||||
)
|
||||
for photo in photos:
|
||||
tz_seconds, tz_str, tz_name = tzinfo.get_timezone(photo)
|
||||
photo_date_local = datetime_naive_to_local(photo.date)
|
||||
photo_date_tz = datetime_to_new_tz(photo_date_local, tz_seconds)
|
||||
rich_echo(
|
||||
f"[filename]{photo.filename}[/filename], [uuid]{photo.uuid}[/uuid], [time]{photo_date_local.strftime(DATETIME_FORMAT)}[/time], [time]{photo_date_tz.strftime(DATETIME_FORMAT)}[/time], [tz]{tz_str}[/tz], [tz]{tz_name}[/tz]"
|
||||
)
|
||||
sys.exit(0)
|
||||
|
||||
if compare_exif:
|
||||
album = PhotosAlbumPhotoScript(add_to_album) if add_to_album else None
|
||||
different_photos = 0
|
||||
if photos:
|
||||
photocomp = PhotoCompare(
|
||||
library_path=library,
|
||||
verbose=verbose_,
|
||||
exiftool_path=exiftool_path,
|
||||
)
|
||||
if not album:
|
||||
rich_echo(
|
||||
"filename, uuid, photo time (Photos), photo time (EXIF), timezone offset (Photos), timezone offset (EXIF)"
|
||||
)
|
||||
for photo in photos:
|
||||
diff_results = (
|
||||
photocomp.compare_exif_no_markup(photo)
|
||||
if plain
|
||||
else photocomp.compare_exif_with_markup(photo)
|
||||
)
|
||||
|
||||
if not plain:
|
||||
filename = (
|
||||
f"[change]{photo.filename}[/change]"
|
||||
if diff_results.diff
|
||||
else f"[no_change]{photo.filename}[/no_change]"
|
||||
)
|
||||
else:
|
||||
filename = photo.filename
|
||||
uuid = f"[uuid]{photo.uuid}[/uuid]"
|
||||
if album:
|
||||
if diff_results.diff:
|
||||
different_photos += 1
|
||||
verbose_(
|
||||
f"Photo {filename} ({uuid}) has different date/time/timezone, adding to album '{album.name}'"
|
||||
)
|
||||
album.add(photo)
|
||||
else:
|
||||
verbose_(f"Photo {filename} ({uuid}) has same date/time/timezone")
|
||||
else:
|
||||
rich_echo(
|
||||
f"{filename}, {uuid}, "
|
||||
f"{diff_results.photos_date} {diff_results.photos_time}, {diff_results.exif_date} {diff_results.exif_time}, "
|
||||
f"{diff_results.photos_tz}, {diff_results.exif_tz}"
|
||||
)
|
||||
if album:
|
||||
rich_echo(
|
||||
f"Compared {len(photos)} photos, found {different_photos} "
|
||||
f"that {pluralize(different_photos, 'is', 'are')} different and "
|
||||
f"added {pluralize(different_photos, 'it', 'them')} to album '{album.name}'."
|
||||
)
|
||||
sys.exit(0)
|
||||
|
||||
if timezone:
|
||||
tz_updater = PhotoTimeZoneUpdater(
|
||||
timezone, verbose=verbose_, library_path=library
|
||||
)
|
||||
|
||||
if any([push_exif, pull_exif, function]):
|
||||
# ExifDateTimeUpdater used to get photo path for --function
|
||||
exif_updater = ExifDateTimeUpdater(
|
||||
library_path=library,
|
||||
verbose=verbose_,
|
||||
exiftool_path=exiftool_path,
|
||||
plain=plain,
|
||||
)
|
||||
|
||||
num_photos = len(photos)
|
||||
with rich_progress(console=get_verbose_console(), mock=verbose) as progress:
|
||||
task = progress.add_task(
|
||||
f"Processing [num]{num_photos}[/] {pluralize(len(photos), 'photo', 'photos')}",
|
||||
total=num_photos,
|
||||
)
|
||||
for p in photos:
|
||||
if pull_exif:
|
||||
exif_updater.update_photos_from_exif(
|
||||
p, use_file_modify_date=use_file_time
|
||||
)
|
||||
if any([date, time, date_delta, time_delta]):
|
||||
update_photo_date_time_(p)
|
||||
if match_time:
|
||||
# need to adjust time before the timezone is updated
|
||||
# or the old timezone will be overwritten in the database
|
||||
update_photo_time_for_new_timezone_(photo=p, new_timezone=timezone)
|
||||
if timezone:
|
||||
tz_updater.update_photo(p)
|
||||
if function:
|
||||
verbose_(f"Calling function [bold]{function[1]}")
|
||||
photo_path = exif_updater.get_photo_path(p)
|
||||
update_photo_from_function_(photo=p, path=photo_path)
|
||||
if push_exif:
|
||||
# this should be the last step in the if chain to ensure all Photos data is updated
|
||||
# before exiftool is run
|
||||
exif_warn, exif_error = exif_updater.update_exif_from_photos(p)
|
||||
if exif_warn:
|
||||
rich_echo_error(
|
||||
f"[warning]Warning running exiftool: {exif_warn}[/]"
|
||||
)
|
||||
if exif_error:
|
||||
rich_echo_error(f"[error]Error running exiftool: {exif_error}[/]")
|
||||
|
||||
progress.advance(task)
|
||||
|
||||
rich_echo("Done.")
|
||||
@@ -43,15 +43,18 @@ def noop(*args, **kwargs):
|
||||
pass
|
||||
|
||||
|
||||
def get_verbose_console() -> Console:
|
||||
"""Get console object
|
||||
def get_verbose_console(theme: t.Optional[Theme] = None) -> Console:
|
||||
"""Get console object or create one if not already created
|
||||
|
||||
Args:
|
||||
theme: optional rich.theme.Theme object to use for formatting
|
||||
|
||||
Returns:
|
||||
Console object
|
||||
"""
|
||||
global _console
|
||||
if _console.console is None:
|
||||
_console.console = Console(force_terminal=True)
|
||||
_console.console = Console(force_terminal=True, theme=theme)
|
||||
return _console.console
|
||||
|
||||
|
||||
@@ -61,6 +64,7 @@ def verbose_print(
|
||||
rich: bool = False,
|
||||
highlight: bool = False,
|
||||
theme: t.Optional[Theme] = None,
|
||||
file: t.Optional[t.IO] = None,
|
||||
**kwargs: t.Any,
|
||||
) -> t.Callable:
|
||||
"""Create verbose function to print output
|
||||
@@ -71,6 +75,7 @@ def verbose_print(
|
||||
rich: use rich.print instead of click.echo
|
||||
highlight: if True, use automatic rich.print highlighting
|
||||
theme: optional rich.theme.Theme object to use for formatting
|
||||
file: optional file handle to write to instead of stdout
|
||||
kwargs: any extra arguments to pass to click.echo or rich.print depending on whether rich==True
|
||||
|
||||
Returns:
|
||||
@@ -80,7 +85,10 @@ def verbose_print(
|
||||
return noop
|
||||
|
||||
global _console
|
||||
_console.console = Console(theme=theme, width=10_000)
|
||||
if file:
|
||||
_console.console = Console(theme=theme, file=file)
|
||||
else:
|
||||
_console.console = Console(theme=theme, width=10_000)
|
||||
|
||||
# closure to capture timestamp
|
||||
def verbose_(*args):
|
||||
|
||||
38
osxphotos/cli/version.py
Normal file
38
osxphotos/cli/version.py
Normal file
@@ -0,0 +1,38 @@
|
||||
"""about command for osxphotos CLI"""
|
||||
|
||||
import click
|
||||
import os
|
||||
from osxphotos._constants import OSXPHOTOS_URL
|
||||
from osxphotos._version import __version__
|
||||
from .common import get_latest_version
|
||||
import packaging
|
||||
|
||||
|
||||
@click.command(name="version")
|
||||
@click.pass_obj
|
||||
@click.pass_context
|
||||
@click.option(
|
||||
"--run",
|
||||
metavar="COMMAND",
|
||||
required=False,
|
||||
type=str,
|
||||
help="Run COMMAND if there is a new version of osxphotos available.",
|
||||
)
|
||||
def version(ctx, cli_obj, run):
|
||||
"""Check for new version of osxphotos."""
|
||||
latest_version, err = get_latest_version()
|
||||
if latest_version and packaging.version.parse(
|
||||
latest_version
|
||||
) > packaging.version.parse(__version__):
|
||||
click.echo(
|
||||
f"A new version of osxphotos is available: {latest_version} (you have {__version__})\n"
|
||||
"Run `pipx upgrade osxphotos` to upgrade (assuming you installed osxphotos with pipx).\n"
|
||||
f"See {OSXPHOTOS_URL} for more information."
|
||||
)
|
||||
if run:
|
||||
click.echo(f"Running command: '{run}'")
|
||||
os.system(run)
|
||||
elif not latest_version:
|
||||
click.echo(f"Unable to check for new version of osxphotos: {err}")
|
||||
else:
|
||||
click.echo(f"You have the latest version of osxphotos: {__version__}")
|
||||
167
osxphotos/compare_exif.py
Normal file
167
osxphotos/compare_exif.py
Normal file
@@ -0,0 +1,167 @@
|
||||
""" PhotoCompare class to compare date/time/timezone in Photos to the exif data """
|
||||
|
||||
from collections import namedtuple
|
||||
from typing import Callable, List, Optional, Tuple
|
||||
|
||||
from osxphotos import PhotosDB
|
||||
from osxphotos.exiftool import ExifTool
|
||||
from photoscript import Photo
|
||||
|
||||
from .datetime_utils import datetime_naive_to_local, datetime_to_new_tz
|
||||
from .exif_datetime_updater import get_exif_date_time_offset
|
||||
from .phototz import PhotoTimeZone
|
||||
from .utils import noop
|
||||
|
||||
ExifDiff = namedtuple(
|
||||
"ExifDiff",
|
||||
[
|
||||
"diff",
|
||||
"photos_date",
|
||||
"photos_time",
|
||||
"photos_tz",
|
||||
"exif_date",
|
||||
"exif_time",
|
||||
"exif_tz",
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
def change(msg: str) -> str:
|
||||
"""Add change tag to string"""
|
||||
return f"[change]{msg}[/change]"
|
||||
|
||||
|
||||
def no_change(msg: str) -> str:
|
||||
"""Add no change tag to string"""
|
||||
return f"[no_change]{msg}[/no_change]"
|
||||
|
||||
|
||||
class PhotoCompare:
|
||||
"""Class to compare date/time/timezone in Photos to the exif data"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
library_path: Optional[str] = None,
|
||||
verbose: Optional[Callable] = None,
|
||||
exiftool_path: Optional[str] = None,
|
||||
):
|
||||
self.library_path = library_path
|
||||
self.db = PhotosDB(self.library_path)
|
||||
self.verbose = verbose or noop
|
||||
self.exiftool_path = exiftool_path
|
||||
self.phototz = PhotoTimeZone(self.library_path)
|
||||
|
||||
def compare_exif(self, photo: Photo) -> List[str]:
|
||||
"""Compare date/time/timezone in Photos to the exif data
|
||||
|
||||
Args:
|
||||
photo (Photo): Photo object to compare
|
||||
|
||||
Returns:
|
||||
List of strings:
|
||||
"""
|
||||
photos_offset_seconds, photos_tz_str, _ = self.phototz.get_timezone(photo)
|
||||
photos_date = datetime_naive_to_local(photo.date)
|
||||
photos_date = datetime_to_new_tz(photos_date, photos_offset_seconds)
|
||||
photos_date_str = photos_date.strftime("%Y-%m-%d %H:%M:%S")
|
||||
|
||||
photo_ = self.db.get_photo(photo.uuid)
|
||||
if photo_path := photo_.path:
|
||||
exif = ExifTool(filepath=photo_path, exiftool=self.exiftool_path)
|
||||
exif_dict = exif.asdict()
|
||||
exif_dt_offset = get_exif_date_time_offset(exif_dict)
|
||||
exif_offset = exif_dt_offset.offset_str
|
||||
exif_date = (
|
||||
exif_dt_offset.datetime.strftime("%Y-%m-%d %H:%M:%S")
|
||||
if exif_dt_offset.datetime
|
||||
else ""
|
||||
)
|
||||
else:
|
||||
exif_date = ""
|
||||
exif_offset = ""
|
||||
|
||||
return [photos_date_str, photos_tz_str, exif_date, exif_offset]
|
||||
|
||||
def compare_exif_with_markup(self, photo: Photo) -> ExifDiff:
|
||||
"""Compare date/time/timezone in Photos to the exif data and return an ExifDiff named tuple;
|
||||
adds rich markup to strings to show differences
|
||||
|
||||
Args:
|
||||
photo (Photo): Photo object to compare
|
||||
"""
|
||||
photos_date, photos_tz, exif_date, exif_tz = self.compare_exif(photo)
|
||||
diff = False
|
||||
photos_date, photos_time = photos_date.split(" ", 1)
|
||||
try:
|
||||
exif_date, exif_time = exif_date.split(" ", 1)
|
||||
except ValueError:
|
||||
exif_date = exif_date
|
||||
exif_time = ""
|
||||
|
||||
if photos_date != exif_date:
|
||||
photos_date = change(photos_date)
|
||||
exif_date = change(exif_date)
|
||||
diff = True
|
||||
else:
|
||||
photos_date = no_change(photos_date)
|
||||
exif_date = no_change(exif_date)
|
||||
|
||||
if photos_time != exif_time:
|
||||
photos_time = change(photos_time)
|
||||
exif_time = change(exif_time)
|
||||
diff = True
|
||||
else:
|
||||
photos_time = no_change(photos_time)
|
||||
exif_time = no_change(exif_time)
|
||||
|
||||
if photos_tz != exif_tz:
|
||||
photos_tz = change(photos_tz)
|
||||
exif_tz = change(exif_tz)
|
||||
diff = True
|
||||
else:
|
||||
photos_tz = no_change(photos_tz)
|
||||
exif_tz = no_change(exif_tz)
|
||||
|
||||
return ExifDiff(
|
||||
diff,
|
||||
photos_date,
|
||||
photos_time,
|
||||
photos_tz,
|
||||
exif_date,
|
||||
exif_time,
|
||||
exif_tz,
|
||||
)
|
||||
|
||||
def compare_exif_no_markup(self, photo: Photo) -> ExifDiff:
|
||||
"""Compare date/time/timezone in Photos to the exif data and return an ExifDiff named tuple;
|
||||
|
||||
Args:
|
||||
photo (Photo): Photo object to compare
|
||||
"""
|
||||
photos_date, photos_tz, exif_date, exif_tz = self.compare_exif(photo)
|
||||
diff = False
|
||||
photos_date, photos_time = photos_date.split(" ", 1)
|
||||
try:
|
||||
exif_date, exif_time = exif_date.split(" ", 1)
|
||||
except ValueError:
|
||||
exif_date = exif_date
|
||||
exif_time = ""
|
||||
|
||||
if photos_date != exif_date:
|
||||
diff = True
|
||||
|
||||
if photos_time != exif_time:
|
||||
diff = True
|
||||
|
||||
if photos_tz != exif_tz:
|
||||
diff = True
|
||||
|
||||
return ExifDiff(
|
||||
diff,
|
||||
photos_date,
|
||||
photos_time,
|
||||
photos_tz,
|
||||
exif_date,
|
||||
exif_time,
|
||||
exif_tz,
|
||||
)
|
||||
@@ -1,19 +1,28 @@
|
||||
""" datetime.datetime helper functions for converting to/from UTC """
|
||||
""" datetime.datetime helper functions for converting to/from UTC and other datetime manipulations"""
|
||||
|
||||
# source: https://github.com/RhetTbull/datetime-utils
|
||||
|
||||
__version__ = "2022.04.30"
|
||||
|
||||
import datetime
|
||||
|
||||
# TODO: probably shouldn't use replace here, see this:
|
||||
# https://stackoverflow.com/questions/13994594/how-to-add-timezone-into-a-naive-datetime-instance-in-python/13994611#13994611
|
||||
|
||||
__all__ = [
|
||||
"get_local_tz",
|
||||
"datetime_has_tz",
|
||||
"datetime_tz_to_utc",
|
||||
"datetime_remove_tz",
|
||||
"datetime_naive_to_utc",
|
||||
"datetime_naive_to_local",
|
||||
"datetime_naive_to_utc",
|
||||
"datetime_remove_tz",
|
||||
"datetime_to_new_tz",
|
||||
"datetime_tz_to_utc",
|
||||
"datetime_utc_to_local",
|
||||
"get_local_tz",
|
||||
"utc_offset_seconds",
|
||||
]
|
||||
|
||||
|
||||
def get_local_tz(dt):
|
||||
# TODO: look at https://github.com/regebro/tzlocal for more robust implementation
|
||||
def get_local_tz(dt: datetime.datetime) -> datetime.tzinfo:
|
||||
"""Return local timezone as datetime.timezone tzinfo for dt
|
||||
|
||||
Args:
|
||||
@@ -31,7 +40,7 @@ def get_local_tz(dt):
|
||||
raise ValueError("dt must be naive datetime.datetime object")
|
||||
|
||||
|
||||
def datetime_has_tz(dt):
|
||||
def datetime_has_tz(dt: datetime.datetime) -> bool:
|
||||
"""Return True if datetime dt has tzinfo else False
|
||||
|
||||
Args:
|
||||
@@ -50,7 +59,7 @@ def datetime_has_tz(dt):
|
||||
return dt.tzinfo is not None and dt.tzinfo.utcoffset(dt) is not None
|
||||
|
||||
|
||||
def datetime_tz_to_utc(dt):
|
||||
def datetime_tz_to_utc(dt: datetime.datetime) -> datetime.datetime:
|
||||
"""Convert datetime.datetime object with timezone to UTC timezone
|
||||
|
||||
Args:
|
||||
@@ -70,10 +79,10 @@ def datetime_tz_to_utc(dt):
|
||||
if dt.tzinfo is not None and dt.tzinfo.utcoffset(dt) is not None:
|
||||
return dt.replace(tzinfo=dt.tzinfo).astimezone(tz=datetime.timezone.utc)
|
||||
else:
|
||||
raise ValueError(f"dt does not have timezone info")
|
||||
raise ValueError("dt does not have timezone info")
|
||||
|
||||
|
||||
def datetime_remove_tz(dt):
|
||||
def datetime_remove_tz(dt: datetime.datetime) -> datetime.datetime:
|
||||
"""Remove timezone from a datetime.datetime object
|
||||
|
||||
Args:
|
||||
@@ -92,7 +101,7 @@ def datetime_remove_tz(dt):
|
||||
return dt.replace(tzinfo=None)
|
||||
|
||||
|
||||
def datetime_naive_to_utc(dt):
|
||||
def datetime_naive_to_utc(dt: datetime.datetime) -> datetime.datetime:
|
||||
"""Convert naive (timezone unaware) datetime.datetime
|
||||
to aware timezone in UTC timezone
|
||||
|
||||
@@ -120,7 +129,7 @@ def datetime_naive_to_utc(dt):
|
||||
return dt.replace(tzinfo=datetime.timezone.utc)
|
||||
|
||||
|
||||
def datetime_naive_to_local(dt):
|
||||
def datetime_naive_to_local(dt: datetime.datetime) -> datetime.datetime:
|
||||
"""Convert naive (timezone unaware) datetime.datetime
|
||||
to aware timezone in local timezone
|
||||
|
||||
@@ -142,13 +151,13 @@ def datetime_naive_to_local(dt):
|
||||
# has timezone info
|
||||
raise ValueError(
|
||||
"dt must be naive/timezone unaware: "
|
||||
f"{dt} has tzinfo {dt.tzinfo} and offset {dt.tizinfo.utcoffset(dt)}"
|
||||
f"{dt} has tzinfo {dt.tzinfo} and offset {dt.tzinfo.utcoffset(dt)}"
|
||||
)
|
||||
|
||||
return dt.replace(tzinfo=get_local_tz(dt))
|
||||
|
||||
|
||||
def datetime_utc_to_local(dt):
|
||||
def datetime_utc_to_local(dt: datetime.datetime) -> datetime.datetime:
|
||||
"""Convert datetime.datetime object in UTC timezone to local timezone
|
||||
|
||||
Args:
|
||||
@@ -169,3 +178,33 @@ def datetime_utc_to_local(dt):
|
||||
raise ValueError(f"{dt} must be in UTC timezone: timezone = {dt.tzinfo}")
|
||||
|
||||
return dt.replace(tzinfo=datetime.timezone.utc).astimezone(tz=None)
|
||||
|
||||
|
||||
def datetime_to_new_tz(dt: datetime.datetime, offset) -> datetime.datetime:
|
||||
"""Convert datetime.datetime object from current timezone to new timezone with offset of seconds from UTC"""
|
||||
if not datetime_has_tz(dt):
|
||||
raise ValueError("dt must be timezone aware")
|
||||
|
||||
time_delta = datetime.timedelta(seconds=offset)
|
||||
tz = datetime.timezone(time_delta)
|
||||
return dt.astimezone(tz=tz)
|
||||
|
||||
|
||||
def utc_offset_seconds(dt: datetime.datetime) -> int:
|
||||
"""Return offset in seconds from UTC for timezone aware datetime.datetime object
|
||||
|
||||
Args:
|
||||
dt: datetime.datetime object
|
||||
|
||||
Returns:
|
||||
offset in seconds from UTC
|
||||
|
||||
Raises:
|
||||
ValueError if dt does not have timezone information
|
||||
"""
|
||||
|
||||
if dt.tzinfo is not None and dt.tzinfo.utcoffset(dt) is not None:
|
||||
return dt.tzinfo.utcoffset(dt).total_seconds()
|
||||
else:
|
||||
raise ValueError("dt does not have timezone info")
|
||||
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
# 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: 93e80185682565b83f06940002a2e690
|
||||
tags: 645f666f9bcd5a90fca523b33c5a78b7
|
||||
@@ -1,257 +0,0 @@
|
||||
<!doctype html>
|
||||
<html class="no-js">
|
||||
<head><meta charset="utf-8"/>
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1"/>
|
||||
<meta name="color-scheme" content="light dark"><link rel="index" title="Index" href="../genindex.html" /><link rel="search" title="Search" href="../search.html" />
|
||||
|
||||
<meta name="generator" content="sphinx-4.4.0, furo 2022.04.07"/>
|
||||
<title>Overview: module code - osxphotos 0.47.10 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" />
|
||||
|
||||
|
||||
|
||||
|
||||
<style>
|
||||
body {
|
||||
--color-code-background: #f8f8f8;
|
||||
--color-code-foreground: black;
|
||||
|
||||
}
|
||||
@media not print {
|
||||
body[data-theme="dark"] {
|
||||
--color-code-background: #202020;
|
||||
--color-code-foreground: #d0d0d0;
|
||||
|
||||
}
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body:not([data-theme="light"]) {
|
||||
--color-code-background: #202020;
|
||||
--color-code-foreground: #d0d0d0;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</style></head>
|
||||
<body>
|
||||
|
||||
<script>
|
||||
document.body.dataset.theme = localStorage.getItem("theme") || "auto";
|
||||
</script>
|
||||
|
||||
|
||||
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
|
||||
<symbol id="svg-toc" viewBox="0 0 24 24">
|
||||
<title>Contents</title>
|
||||
<svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 1024 1024">
|
||||
<path d="M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM115.4 518.9L271.7 642c5.8 4.6 14.4.5 14.4-6.9V388.9c0-7.4-8.5-11.5-14.4-6.9L115.4 505.1a8.74 8.74 0 0 0 0 13.8z"/>
|
||||
</svg>
|
||||
</symbol>
|
||||
<symbol id="svg-menu" viewBox="0 0 24 24">
|
||||
<title>Menu</title>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather-menu">
|
||||
<line x1="3" y1="12" x2="21" y2="12"></line>
|
||||
<line x1="3" y1="6" x2="21" y2="6"></line>
|
||||
<line x1="3" y1="18" x2="21" y2="18"></line>
|
||||
</svg>
|
||||
</symbol>
|
||||
<symbol id="svg-arrow-right" viewBox="0 0 24 24">
|
||||
<title>Expand</title>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather-chevron-right">
|
||||
<polyline points="9 18 15 12 9 6"></polyline>
|
||||
</svg>
|
||||
</symbol>
|
||||
<symbol id="svg-sun" viewBox="0 0 24 24">
|
||||
<title>Light mode</title>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="feather-sun">
|
||||
<circle cx="12" cy="12" r="5"></circle>
|
||||
<line x1="12" y1="1" x2="12" y2="3"></line>
|
||||
<line x1="12" y1="21" x2="12" y2="23"></line>
|
||||
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
|
||||
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
|
||||
<line x1="1" y1="12" x2="3" y2="12"></line>
|
||||
<line x1="21" y1="12" x2="23" y2="12"></line>
|
||||
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
|
||||
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
|
||||
</svg>
|
||||
</symbol>
|
||||
<symbol id="svg-moon" viewBox="0 0 24 24">
|
||||
<title>Dark mode</title>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="icon-tabler-moon">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M12 3c.132 0 .263 0 .393 0a7.5 7.5 0 0 0 7.92 12.446a9 9 0 1 1 -8.313 -12.454z" />
|
||||
</svg>
|
||||
</symbol>
|
||||
<symbol id="svg-sun-half" viewBox="0 0 24 24">
|
||||
<title>Auto light/dark mode</title>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="icon-tabler-shadow">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"/>
|
||||
<circle cx="12" cy="12" r="9" />
|
||||
<path d="M13 12h5" />
|
||||
<path d="M13 15h4" />
|
||||
<path d="M13 18h1" />
|
||||
<path d="M13 9h4" />
|
||||
<path d="M13 6h1" />
|
||||
</svg>
|
||||
</symbol>
|
||||
</svg>
|
||||
|
||||
<input type="checkbox" class="sidebar-toggle" name="__navigation" id="__navigation">
|
||||
<input type="checkbox" class="sidebar-toggle" name="__toc" id="__toc">
|
||||
<label class="overlay sidebar-overlay" for="__navigation">
|
||||
<div class="visually-hidden">Hide navigation sidebar</div>
|
||||
</label>
|
||||
<label class="overlay toc-overlay" for="__toc">
|
||||
<div class="visually-hidden">Hide table of contents sidebar</div>
|
||||
</label>
|
||||
|
||||
|
||||
|
||||
<div class="page">
|
||||
<header class="mobile-header">
|
||||
<div class="header-left">
|
||||
<label class="nav-overlay-icon" for="__navigation">
|
||||
<div class="visually-hidden">Toggle site navigation sidebar</div>
|
||||
<i class="icon"><svg><use href="#svg-menu"></use></svg></i>
|
||||
</label>
|
||||
</div>
|
||||
<div class="header-center">
|
||||
<a href="../index.html"><div class="brand">osxphotos 0.47.10 documentation</div></a>
|
||||
</div>
|
||||
<div class="header-right">
|
||||
<div class="theme-toggle-container theme-toggle-header">
|
||||
<button class="theme-toggle">
|
||||
<div class="visually-hidden">Toggle Light / Dark / Auto color theme</div>
|
||||
<svg class="theme-icon-when-auto"><use href="#svg-sun-half"></use></svg>
|
||||
<svg class="theme-icon-when-dark"><use href="#svg-moon"></use></svg>
|
||||
<svg class="theme-icon-when-light"><use href="#svg-sun"></use></svg>
|
||||
</button>
|
||||
</div>
|
||||
<label class="toc-overlay-icon toc-header-icon no-toc" for="__toc">
|
||||
<div class="visually-hidden">Toggle table of contents sidebar</div>
|
||||
<i class="icon"><svg><use href="#svg-toc"></use></svg></i>
|
||||
</label>
|
||||
</div>
|
||||
</header>
|
||||
<aside class="sidebar-drawer">
|
||||
<div class="sidebar-container">
|
||||
|
||||
<div class="sidebar-sticky"><a class="sidebar-brand" href="../index.html">
|
||||
|
||||
|
||||
<span class="sidebar-brand-text">osxphotos 0.47.10 documentation</span>
|
||||
|
||||
</a><form class="sidebar-search-container" method="get" action="../search.html" role="search">
|
||||
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
|
||||
<input type="hidden" name="check_keywords" value="yes">
|
||||
<input type="hidden" name="area" value="default">
|
||||
</form>
|
||||
<div id="searchbox"></div><div class="sidebar-scroll"><div class="sidebar-tree">
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../overview.html">osxphotos</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../tutorial.html">osxphotos Tutorial</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../cli.html">osxphotos Command Line Interface (CLI)</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../template_help.html">osxphotos Template System</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../package_overview.html">Example uses of the python package</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../reference.html">osxphotos python API</a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</aside>
|
||||
<div class="main">
|
||||
<div class="content">
|
||||
<div class="article-container">
|
||||
<a href="#" class="back-to-top muted-link">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8v12z"></path>
|
||||
</svg>
|
||||
<span>Back to top</span>
|
||||
</a>
|
||||
<div class="content-icon-container"><div class="theme-toggle-container theme-toggle-content">
|
||||
<button class="theme-toggle">
|
||||
<div class="visually-hidden">Toggle Light / Dark / Auto color theme</div>
|
||||
<svg class="theme-icon-when-auto"><use href="#svg-sun-half"></use></svg>
|
||||
<svg class="theme-icon-when-dark"><use href="#svg-moon"></use></svg>
|
||||
<svg class="theme-icon-when-light"><use href="#svg-sun"></use></svg>
|
||||
</button>
|
||||
</div>
|
||||
<label class="toc-overlay-icon toc-content-icon no-toc" for="__toc">
|
||||
<div class="visually-hidden">Toggle table of contents sidebar</div>
|
||||
<i class="icon"><svg><use href="#svg-toc"></use></svg></i>
|
||||
</label>
|
||||
</div>
|
||||
<article role="main">
|
||||
<h1>All modules for which code is available</h1>
|
||||
<ul><li><a href="osxphotos/_constants.html">osxphotos._constants</a></li>
|
||||
<li><a href="osxphotos/albuminfo.html">osxphotos.albuminfo</a></li>
|
||||
<li><a href="osxphotos/debug.html">osxphotos.debug</a></li>
|
||||
<li><a href="osxphotos/exifinfo.html">osxphotos.exifinfo</a></li>
|
||||
<li><a href="osxphotos/exiftool.html">osxphotos.exiftool</a></li>
|
||||
<li><a href="osxphotos/export_db.html">osxphotos.export_db</a></li>
|
||||
<li><a href="osxphotos/fileutil.html">osxphotos.fileutil</a></li>
|
||||
<li><a href="osxphotos/momentinfo.html">osxphotos.momentinfo</a></li>
|
||||
<li><a href="osxphotos/personinfo.html">osxphotos.personinfo</a></li>
|
||||
<li><a href="osxphotos/photoexporter.html">osxphotos.photoexporter</a></li>
|
||||
<li><a href="osxphotos/photoinfo.html">osxphotos.photoinfo</a></li>
|
||||
<li><a href="osxphotos/photosdb/_photosdb_process_comments.html">osxphotos.photosdb._photosdb_process_comments</a></li>
|
||||
<li><a href="osxphotos/photosdb/photosdb.html">osxphotos.photosdb.photosdb</a></li>
|
||||
<li><a href="osxphotos/phototemplate.html">osxphotos.phototemplate</a></li>
|
||||
<li><a href="osxphotos/placeinfo.html">osxphotos.placeinfo</a></li>
|
||||
<li><a href="osxphotos/queryoptions.html">osxphotos.queryoptions</a></li>
|
||||
<li><a href="osxphotos/scoreinfo.html">osxphotos.scoreinfo</a></li>
|
||||
<li><a href="osxphotos/searchinfo.html">osxphotos.searchinfo</a></li>
|
||||
</ul>
|
||||
</article>
|
||||
</div>
|
||||
<footer>
|
||||
|
||||
<div class="related-pages">
|
||||
|
||||
|
||||
</div>
|
||||
<div class="bottom-of-page">
|
||||
<div class="left-details">
|
||||
<div class="copyright">
|
||||
Copyright © 2021, Rhet Turnbull
|
||||
</div>
|
||||
Made with <a href="https://www.sphinx-doc.org/">Sphinx</a> and <a class="muted-link" href="https://pradyunsg.me">@pradyunsg</a>'s
|
||||
|
||||
<a href="https://github.com/pradyunsg/furo">Furo</a>
|
||||
|
||||
</div>
|
||||
<div class="right-details">
|
||||
<div class="icons">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</footer>
|
||||
</div>
|
||||
<aside class="toc-drawer no-toc">
|
||||
|
||||
|
||||
|
||||
</aside>
|
||||
</div>
|
||||
</div><script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js"></script>
|
||||
<script src="../_static/jquery.js"></script>
|
||||
<script src="../_static/underscore.js"></script>
|
||||
<script src="../_static/doctools.js"></script>
|
||||
<script src="../_static/scripts/furo.js"></script>
|
||||
<script src="../_static/clipboard.min.js"></script>
|
||||
<script src="../_static/copybutton.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,429 +0,0 @@
|
||||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>osxphotos._constants — osxphotos 0.47.9 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="../../_static/alabaster.css" />
|
||||
<script data-url_root="../../" id="documentation_options" src="../../_static/documentation_options.js"></script>
|
||||
<script src="../../_static/jquery.js"></script>
|
||||
<script src="../../_static/underscore.js"></script>
|
||||
<script src="../../_static/doctools.js"></script>
|
||||
<link rel="index" title="Index" href="../../genindex.html" />
|
||||
<link rel="search" title="Search" href="../../search.html" />
|
||||
|
||||
<link rel="stylesheet" href="../../_static/custom.css" type="text/css" />
|
||||
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
|
||||
|
||||
</head><body>
|
||||
|
||||
|
||||
<div class="document">
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
|
||||
|
||||
<div class="body" role="main">
|
||||
|
||||
<h1>Source code for osxphotos._constants</h1><div class="highlight"><pre>
|
||||
<span></span><span class="sd">"""</span>
|
||||
<span class="sd">Constants used by osxphotos </span>
|
||||
<span class="sd">"""</span>
|
||||
|
||||
<span class="kn">import</span> <span class="nn">os.path</span>
|
||||
<span class="kn">from</span> <span class="nn">datetime</span> <span class="kn">import</span> <span class="n">datetime</span>
|
||||
<span class="kn">from</span> <span class="nn">enum</span> <span class="kn">import</span> <span class="n">Enum</span>
|
||||
|
||||
<span class="n">APP_NAME</span> <span class="o">=</span> <span class="s2">"osxphotos"</span>
|
||||
|
||||
<span class="n">OSXPHOTOS_URL</span> <span class="o">=</span> <span class="s2">"https://github.com/RhetTbull/osxphotos"</span>
|
||||
|
||||
<span class="c1"># Time delta: add this to Photos times to get unix time</span>
|
||||
<span class="c1"># Apple Epoch is Jan 1, 2001</span>
|
||||
<span class="n">TIME_DELTA</span> <span class="o">=</span> <span class="p">(</span><span class="n">datetime</span><span class="p">(</span><span class="mi">2001</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="o">-</span> <span class="n">datetime</span><span class="p">(</span><span class="mi">1970</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">))</span><span class="o">.</span><span class="n">total_seconds</span><span class="p">()</span>
|
||||
|
||||
<span class="c1"># Unicode format to use for comparing strings</span>
|
||||
<span class="n">UNICODE_FORMAT</span> <span class="o">=</span> <span class="s2">"NFC"</span>
|
||||
|
||||
<span class="c1"># which Photos library database versions have been tested</span>
|
||||
<span class="c1"># Photos 2.0 (10.12.6) == 2622</span>
|
||||
<span class="c1"># Photos 3.0 (10.13.6) == 3301</span>
|
||||
<span class="c1"># Photos 4.0 (10.14.5) == 4016</span>
|
||||
<span class="c1"># Photos 4.0 (10.14.6) == 4025</span>
|
||||
<span class="c1"># Photos 5.0 (10.15.0) == 6000 or 5001</span>
|
||||
<span class="n">_TESTED_DB_VERSIONS</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"6000"</span><span class="p">,</span> <span class="s2">"5001"</span><span class="p">,</span> <span class="s2">"4025"</span><span class="p">,</span> <span class="s2">"4016"</span><span class="p">,</span> <span class="s2">"3301"</span><span class="p">,</span> <span class="s2">"2622"</span><span class="p">]</span>
|
||||
|
||||
<span class="c1"># database model versions (applies to Photos 5, Photos 6)</span>
|
||||
<span class="c1"># these come from PLModelVersion key in binary plist in Z_METADATA.Z_PLIST</span>
|
||||
<span class="c1"># Photos 5 (10.15.1) == 13537</span>
|
||||
<span class="c1"># Photos 5 (10.15.4, 10.15.5, 10.15.6) == 13703</span>
|
||||
<span class="c1"># Photos 6 (10.16.0 Beta) == 14104</span>
|
||||
<span class="n">_TEST_MODEL_VERSIONS</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"13537"</span><span class="p">,</span> <span class="s2">"13703"</span><span class="p">,</span> <span class="s2">"14104"</span><span class="p">]</span>
|
||||
|
||||
<span class="n">_PHOTOS_2_VERSION</span> <span class="o">=</span> <span class="s2">"2622"</span>
|
||||
|
||||
<span class="c1"># only version 3 - 4 have RKVersion.selfPortrait</span>
|
||||
<span class="n">_PHOTOS_3_VERSION</span> <span class="o">=</span> <span class="s2">"3301"</span>
|
||||
|
||||
<span class="c1"># versions 5.0 and later have a different database structure</span>
|
||||
<span class="n">_PHOTOS_4_VERSION</span> <span class="o">=</span> <span class="s2">"4025"</span> <span class="c1"># latest Mojove version on 10.14.6</span>
|
||||
<span class="n">_PHOTOS_5_VERSION</span> <span class="o">=</span> <span class="s2">"5000"</span> <span class="c1"># I've seen both 5001 and 6000. 6000 is most common on Catalina and up but there are some version 5001 database in the wild</span>
|
||||
|
||||
<span class="c1"># Ranges for model version by Photos version</span>
|
||||
<span class="n">_PHOTOS_5_MODEL_VERSION</span> <span class="o">=</span> <span class="p">[</span><span class="mi">13000</span><span class="p">,</span> <span class="mi">13999</span><span class="p">]</span>
|
||||
<span class="n">_PHOTOS_6_MODEL_VERSION</span> <span class="o">=</span> <span class="p">[</span><span class="mi">14000</span><span class="p">,</span> <span class="mi">14999</span><span class="p">]</span>
|
||||
<span class="n">_PHOTOS_7_MODEL_VERSION</span> <span class="o">=</span> <span class="p">[</span>
|
||||
<span class="mi">15000</span><span class="p">,</span>
|
||||
<span class="mi">15999</span><span class="p">,</span>
|
||||
<span class="p">]</span> <span class="c1"># Monterey developer preview is 15134, 12.1 is 15331</span>
|
||||
|
||||
<span class="c1"># some table names differ between Photos 5 and Photos 6</span>
|
||||
<span class="n">_DB_TABLE_NAMES</span> <span class="o">=</span> <span class="p">{</span>
|
||||
<span class="mi">5</span><span class="p">:</span> <span class="p">{</span>
|
||||
<span class="s2">"ASSET"</span><span class="p">:</span> <span class="s2">"ZGENERICASSET"</span><span class="p">,</span>
|
||||
<span class="s2">"KEYWORD_JOIN"</span><span class="p">:</span> <span class="s2">"Z_1KEYWORDS.Z_37KEYWORDS"</span><span class="p">,</span>
|
||||
<span class="s2">"ALBUM_JOIN"</span><span class="p">:</span> <span class="s2">"Z_26ASSETS.Z_34ASSETS"</span><span class="p">,</span>
|
||||
<span class="s2">"ALBUM_SORT_ORDER"</span><span class="p">:</span> <span class="s2">"Z_26ASSETS.Z_FOK_34ASSETS"</span><span class="p">,</span>
|
||||
<span class="s2">"IMPORT_FOK"</span><span class="p">:</span> <span class="s2">"ZGENERICASSET.Z_FOK_IMPORTSESSION"</span><span class="p">,</span>
|
||||
<span class="s2">"DEPTH_STATE"</span><span class="p">:</span> <span class="s2">"ZGENERICASSET.ZDEPTHSTATES"</span><span class="p">,</span>
|
||||
<span class="s2">"UTI_ORIGINAL"</span><span class="p">:</span> <span class="s2">"ZINTERNALRESOURCE.ZUNIFORMTYPEIDENTIFIER"</span><span class="p">,</span>
|
||||
<span class="s2">"ASSET_ALBUM_JOIN"</span><span class="p">:</span> <span class="s2">"Z_26ASSETS.Z_26ALBUMS"</span><span class="p">,</span>
|
||||
<span class="s2">"ASSET_ALBUM_TABLE"</span><span class="p">:</span> <span class="s2">"Z_26ASSETS"</span><span class="p">,</span>
|
||||
<span class="s2">"HDR_TYPE"</span><span class="p">:</span> <span class="s2">"ZCUSTOMRENDEREDVALUE"</span><span class="p">,</span>
|
||||
<span class="p">},</span>
|
||||
<span class="mi">6</span><span class="p">:</span> <span class="p">{</span>
|
||||
<span class="s2">"ASSET"</span><span class="p">:</span> <span class="s2">"ZASSET"</span><span class="p">,</span>
|
||||
<span class="s2">"KEYWORD_JOIN"</span><span class="p">:</span> <span class="s2">"Z_1KEYWORDS.Z_36KEYWORDS"</span><span class="p">,</span>
|
||||
<span class="s2">"ALBUM_JOIN"</span><span class="p">:</span> <span class="s2">"Z_26ASSETS.Z_3ASSETS"</span><span class="p">,</span>
|
||||
<span class="s2">"ALBUM_SORT_ORDER"</span><span class="p">:</span> <span class="s2">"Z_26ASSETS.Z_FOK_3ASSETS"</span><span class="p">,</span>
|
||||
<span class="s2">"IMPORT_FOK"</span><span class="p">:</span> <span class="s2">"null"</span><span class="p">,</span>
|
||||
<span class="s2">"DEPTH_STATE"</span><span class="p">:</span> <span class="s2">"ZASSET.ZDEPTHTYPE"</span><span class="p">,</span>
|
||||
<span class="s2">"UTI_ORIGINAL"</span><span class="p">:</span> <span class="s2">"ZINTERNALRESOURCE.ZUNIFORMTYPEIDENTIFIER"</span><span class="p">,</span>
|
||||
<span class="s2">"ASSET_ALBUM_JOIN"</span><span class="p">:</span> <span class="s2">"Z_26ASSETS.Z_26ALBUMS"</span><span class="p">,</span>
|
||||
<span class="s2">"ASSET_ALBUM_TABLE"</span><span class="p">:</span> <span class="s2">"Z_26ASSETS"</span><span class="p">,</span>
|
||||
<span class="s2">"HDR_TYPE"</span><span class="p">:</span> <span class="s2">"ZCUSTOMRENDEREDVALUE"</span><span class="p">,</span>
|
||||
<span class="p">},</span>
|
||||
<span class="mi">7</span><span class="p">:</span> <span class="p">{</span>
|
||||
<span class="s2">"ASSET"</span><span class="p">:</span> <span class="s2">"ZASSET"</span><span class="p">,</span>
|
||||
<span class="s2">"KEYWORD_JOIN"</span><span class="p">:</span> <span class="s2">"Z_1KEYWORDS.Z_38KEYWORDS"</span><span class="p">,</span>
|
||||
<span class="s2">"ALBUM_JOIN"</span><span class="p">:</span> <span class="s2">"Z_27ASSETS.Z_3ASSETS"</span><span class="p">,</span>
|
||||
<span class="s2">"ALBUM_SORT_ORDER"</span><span class="p">:</span> <span class="s2">"Z_27ASSETS.Z_FOK_3ASSETS"</span><span class="p">,</span>
|
||||
<span class="s2">"IMPORT_FOK"</span><span class="p">:</span> <span class="s2">"null"</span><span class="p">,</span>
|
||||
<span class="s2">"DEPTH_STATE"</span><span class="p">:</span> <span class="s2">"ZASSET.ZDEPTHTYPE"</span><span class="p">,</span>
|
||||
<span class="s2">"UTI_ORIGINAL"</span><span class="p">:</span> <span class="s2">"ZINTERNALRESOURCE.ZCOMPACTUTI"</span><span class="p">,</span>
|
||||
<span class="s2">"ASSET_ALBUM_JOIN"</span><span class="p">:</span> <span class="s2">"Z_27ASSETS.Z_27ALBUMS"</span><span class="p">,</span>
|
||||
<span class="s2">"ASSET_ALBUM_TABLE"</span><span class="p">:</span> <span class="s2">"Z_27ASSETS"</span><span class="p">,</span>
|
||||
<span class="s2">"HDR_TYPE"</span><span class="p">:</span> <span class="s2">"ZHDRTYPE"</span><span class="p">,</span>
|
||||
<span class="p">},</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="c1"># which version operating systems have been tested</span>
|
||||
<span class="n">_TESTED_OS_VERSIONS</span> <span class="o">=</span> <span class="p">[</span>
|
||||
<span class="p">(</span><span class="s2">"10"</span><span class="p">,</span> <span class="s2">"12"</span><span class="p">),</span>
|
||||
<span class="p">(</span><span class="s2">"10"</span><span class="p">,</span> <span class="s2">"13"</span><span class="p">),</span>
|
||||
<span class="p">(</span><span class="s2">"10"</span><span class="p">,</span> <span class="s2">"14"</span><span class="p">),</span>
|
||||
<span class="p">(</span><span class="s2">"10"</span><span class="p">,</span> <span class="s2">"15"</span><span class="p">),</span>
|
||||
<span class="p">(</span><span class="s2">"10"</span><span class="p">,</span> <span class="s2">"16"</span><span class="p">),</span>
|
||||
<span class="p">(</span><span class="s2">"11"</span><span class="p">,</span> <span class="s2">"0"</span><span class="p">),</span>
|
||||
<span class="p">(</span><span class="s2">"11"</span><span class="p">,</span> <span class="s2">"1"</span><span class="p">),</span>
|
||||
<span class="p">(</span><span class="s2">"11"</span><span class="p">,</span> <span class="s2">"2"</span><span class="p">),</span>
|
||||
<span class="p">(</span><span class="s2">"11"</span><span class="p">,</span> <span class="s2">"3"</span><span class="p">),</span>
|
||||
<span class="p">(</span><span class="s2">"11"</span><span class="p">,</span> <span class="s2">"4"</span><span class="p">),</span>
|
||||
<span class="p">(</span><span class="s2">"11"</span><span class="p">,</span> <span class="s2">"5"</span><span class="p">),</span>
|
||||
<span class="p">(</span><span class="s2">"11"</span><span class="p">,</span> <span class="s2">"6"</span><span class="p">),</span>
|
||||
<span class="p">(</span><span class="s2">"12"</span><span class="p">,</span> <span class="s2">"0"</span><span class="p">),</span>
|
||||
<span class="p">(</span><span class="s2">"12"</span><span class="p">,</span> <span class="s2">"1"</span><span class="p">),</span>
|
||||
<span class="p">(</span><span class="s2">"12"</span><span class="p">,</span> <span class="s2">"2"</span><span class="p">),</span>
|
||||
<span class="p">(</span><span class="s2">"12"</span><span class="p">,</span> <span class="s2">"3"</span><span class="p">),</span>
|
||||
<span class="p">]</span>
|
||||
|
||||
<span class="c1"># Photos 5 has persons who are empty string if unidentified face</span>
|
||||
<span class="n">_UNKNOWN_PERSON</span> <span class="o">=</span> <span class="s2">"_UNKNOWN_"</span>
|
||||
|
||||
<span class="c1"># photos with no reverse geolocation info (place)</span>
|
||||
<span class="n">_UNKNOWN_PLACE</span> <span class="o">=</span> <span class="s2">"_UNKNOWN_"</span>
|
||||
|
||||
<span class="n">_EXIF_TOOL_URL</span> <span class="o">=</span> <span class="s2">"https://exiftool.org/"</span>
|
||||
|
||||
<span class="c1"># Where are shared iCloud photos located?</span>
|
||||
<span class="n">_PHOTOS_5_SHARED_PHOTO_PATH</span> <span class="o">=</span> <span class="s2">"resources/cloudsharing/data"</span>
|
||||
|
||||
<span class="c1"># What type of file? Based on ZGENERICASSET.ZKIND in Photos 5 database</span>
|
||||
<span class="n">_PHOTO_TYPE</span> <span class="o">=</span> <span class="mi">0</span>
|
||||
<span class="n">_MOVIE_TYPE</span> <span class="o">=</span> <span class="mi">1</span>
|
||||
|
||||
<span class="c1"># Name of XMP template file</span>
|
||||
<span class="n">_TEMPLATE_DIR</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">dirname</span><span class="p">(</span><span class="vm">__file__</span><span class="p">),</span> <span class="s2">"templates"</span><span class="p">)</span>
|
||||
<span class="n">_XMP_TEMPLATE_NAME</span> <span class="o">=</span> <span class="s2">"xmp_sidecar.mako"</span>
|
||||
<span class="n">_XMP_TEMPLATE_NAME_BETA</span> <span class="o">=</span> <span class="s2">"xmp_sidecar_beta.mako"</span>
|
||||
|
||||
<span class="c1"># Constants used for processing folders and albums</span>
|
||||
<span class="n">_PHOTOS_5_ALBUM_KIND</span> <span class="o">=</span> <span class="mi">2</span> <span class="c1"># normal user album</span>
|
||||
<span class="n">_PHOTOS_5_SHARED_ALBUM_KIND</span> <span class="o">=</span> <span class="mi">1505</span> <span class="c1"># shared album</span>
|
||||
<span class="n">_PHOTOS_5_PROJECT_ALBUM_KIND</span> <span class="o">=</span> <span class="mi">1508</span> <span class="c1"># My Projects (e.g. Calendar, Card, Slideshow)</span>
|
||||
<span class="n">_PHOTOS_5_FOLDER_KIND</span> <span class="o">=</span> <span class="mi">4000</span> <span class="c1"># user folder</span>
|
||||
<span class="n">_PHOTOS_5_ROOT_FOLDER_KIND</span> <span class="o">=</span> <span class="mi">3999</span> <span class="c1"># root folder</span>
|
||||
<span class="n">_PHOTOS_5_IMPORT_SESSION_ALBUM_KIND</span> <span class="o">=</span> <span class="mi">1506</span> <span class="c1"># import session</span>
|
||||
|
||||
<span class="n">_PHOTOS_4_ALBUM_KIND</span> <span class="o">=</span> <span class="mi">3</span> <span class="c1"># RKAlbum.albumSubclass</span>
|
||||
<span class="n">_PHOTOS_4_ALBUM_TYPE_ALBUM</span> <span class="o">=</span> <span class="mi">1</span> <span class="c1"># RKAlbum.albumType</span>
|
||||
<span class="n">_PHOTOS_4_ALBUM_TYPE_PROJECT</span> <span class="o">=</span> <span class="mi">9</span> <span class="c1"># RKAlbum.albumType</span>
|
||||
<span class="n">_PHOTOS_4_ALBUM_TYPE_SLIDESHOW</span> <span class="o">=</span> <span class="mi">8</span> <span class="c1"># RKAlbum.albumType</span>
|
||||
<span class="n">_PHOTOS_4_TOP_LEVEL_ALBUMS</span> <span class="o">=</span> <span class="p">[</span>
|
||||
<span class="s2">"TopLevelAlbums"</span><span class="p">,</span>
|
||||
<span class="s2">"TopLevelKeepsakes"</span><span class="p">,</span>
|
||||
<span class="s2">"TopLevelSlideshows"</span><span class="p">,</span>
|
||||
<span class="p">]</span>
|
||||
<span class="n">_PHOTOS_4_ROOT_FOLDER</span> <span class="o">=</span> <span class="s2">"LibraryFolder"</span>
|
||||
|
||||
<span class="c1"># EXIF related constants</span>
|
||||
<span class="c1"># max keyword length for IPTC:Keyword, reference</span>
|
||||
<span class="c1"># https://www.iptc.org/std/photometadata/documentation/userguide/</span>
|
||||
<span class="n">_MAX_IPTC_KEYWORD_LEN</span> <span class="o">=</span> <span class="mi">64</span>
|
||||
|
||||
<span class="c1"># Sentinel value for detecting if a template in keyword_template doesn't match</span>
|
||||
<span class="c1"># If anyone has a keyword matching this, then too bad...</span>
|
||||
<span class="n">_OSXPHOTOS_NONE_SENTINEL</span> <span class="o">=</span> <span class="s2">"OSXPhotosXYZZY42_Sentinel$"</span>
|
||||
|
||||
<span class="c1"># SearchInfo categories for Photos 5, corresponds to categories in database/search/psi.sqlite</span>
|
||||
<span class="n">SEARCH_CATEGORY_LABEL</span> <span class="o">=</span> <span class="mi">2024</span>
|
||||
<span class="n">SEARCH_CATEGORY_PLACE_NAME</span> <span class="o">=</span> <span class="mi">1</span>
|
||||
<span class="n">SEARCH_CATEGORY_STREET</span> <span class="o">=</span> <span class="mi">2</span>
|
||||
<span class="n">SEARCH_CATEGORY_NEIGHBORHOOD</span> <span class="o">=</span> <span class="mi">3</span>
|
||||
<span class="n">SEARCH_CATEGORY_LOCALITY_4</span> <span class="o">=</span> <span class="mi">4</span>
|
||||
<span class="n">SEARCH_CATEGORY_SUB_LOCALITY_5</span> <span class="o">=</span> <span class="mi">5</span>
|
||||
<span class="n">SEARCH_CATEGORY_SUB_LOCALITY_6</span> <span class="o">=</span> <span class="mi">6</span>
|
||||
<span class="n">SEARCH_CATEGORY_CITY</span> <span class="o">=</span> <span class="mi">7</span>
|
||||
<span class="n">SEARCH_CATEGORY_LOCALITY_8</span> <span class="o">=</span> <span class="mi">8</span>
|
||||
<span class="n">SEARCH_CATEGORY_NAMED_AREA</span> <span class="o">=</span> <span class="mi">9</span>
|
||||
<span class="n">SEARCH_CATEGORY_ALL_LOCALITY</span> <span class="o">=</span> <span class="p">[</span>
|
||||
<span class="n">SEARCH_CATEGORY_LOCALITY_4</span><span class="p">,</span>
|
||||
<span class="n">SEARCH_CATEGORY_SUB_LOCALITY_5</span><span class="p">,</span>
|
||||
<span class="n">SEARCH_CATEGORY_SUB_LOCALITY_6</span><span class="p">,</span>
|
||||
<span class="n">SEARCH_CATEGORY_LOCALITY_8</span><span class="p">,</span>
|
||||
<span class="n">SEARCH_CATEGORY_NAMED_AREA</span><span class="p">,</span>
|
||||
<span class="p">]</span>
|
||||
<span class="n">SEARCH_CATEGORY_STATE</span> <span class="o">=</span> <span class="mi">10</span>
|
||||
<span class="n">SEARCH_CATEGORY_STATE_ABBREVIATION</span> <span class="o">=</span> <span class="mi">11</span>
|
||||
<span class="n">SEARCH_CATEGORY_COUNTRY</span> <span class="o">=</span> <span class="mi">12</span>
|
||||
<span class="n">SEARCH_CATEGORY_BODY_OF_WATER</span> <span class="o">=</span> <span class="mi">14</span>
|
||||
<span class="n">SEARCH_CATEGORY_MONTH</span> <span class="o">=</span> <span class="mi">1014</span>
|
||||
<span class="n">SEARCH_CATEGORY_YEAR</span> <span class="o">=</span> <span class="mi">1015</span>
|
||||
<span class="n">SEARCH_CATEGORY_KEYWORDS</span> <span class="o">=</span> <span class="mi">2016</span>
|
||||
<span class="n">SEARCH_CATEGORY_TITLE</span> <span class="o">=</span> <span class="mi">2017</span>
|
||||
<span class="n">SEARCH_CATEGORY_DESCRIPTION</span> <span class="o">=</span> <span class="mi">2018</span>
|
||||
<span class="n">SEARCH_CATEGORY_HOME</span> <span class="o">=</span> <span class="mi">2020</span>
|
||||
<span class="n">SEARCH_CATEGORY_PERSON</span> <span class="o">=</span> <span class="mi">2021</span>
|
||||
<span class="n">SEARCH_CATEGORY_ACTIVITY</span> <span class="o">=</span> <span class="mi">2027</span>
|
||||
<span class="n">SEARCH_CATEGORY_HOLIDAY</span> <span class="o">=</span> <span class="mi">2029</span>
|
||||
<span class="n">SEARCH_CATEGORY_SEASON</span> <span class="o">=</span> <span class="mi">2030</span>
|
||||
<span class="n">SEARCH_CATEGORY_WORK</span> <span class="o">=</span> <span class="mi">2036</span>
|
||||
<span class="n">SEARCH_CATEGORY_VENUE</span> <span class="o">=</span> <span class="mi">2038</span>
|
||||
<span class="n">SEARCH_CATEGORY_VENUE_TYPE</span> <span class="o">=</span> <span class="mi">2039</span>
|
||||
<span class="n">SEARCH_CATEGORY_PHOTO_TYPE_VIDEO</span> <span class="o">=</span> <span class="mi">2044</span>
|
||||
<span class="n">SEARCH_CATEGORY_PHOTO_TYPE_SLOMO</span> <span class="o">=</span> <span class="mi">2045</span>
|
||||
<span class="n">SEARCH_CATEGORY_PHOTO_TYPE_LIVE</span> <span class="o">=</span> <span class="mi">2046</span>
|
||||
<span class="n">SEARCH_CATEGORY_PHOTO_TYPE_SCREENSHOT</span> <span class="o">=</span> <span class="mi">2047</span>
|
||||
<span class="n">SEARCH_CATEGORY_PHOTO_TYPE_PANORAMA</span> <span class="o">=</span> <span class="mi">2048</span>
|
||||
<span class="n">SEARCH_CATEGORY_PHOTO_TYPE_TIMELAPSE</span> <span class="o">=</span> <span class="mi">2049</span>
|
||||
<span class="n">SEARCH_CATEGORY_PHOTO_TYPE_BURSTS</span> <span class="o">=</span> <span class="mi">2052</span>
|
||||
<span class="n">SEARCH_CATEGORY_PHOTO_TYPE_PORTRAIT</span> <span class="o">=</span> <span class="mi">2053</span>
|
||||
<span class="n">SEARCH_CATEGORY_PHOTO_TYPE_SELFIES</span> <span class="o">=</span> <span class="mi">2054</span>
|
||||
<span class="n">SEARCH_CATEGORY_PHOTO_TYPE_FAVORITES</span> <span class="o">=</span> <span class="mi">2055</span>
|
||||
<span class="n">SEARCH_CATEGORY_MEDIA_TYPES</span> <span class="o">=</span> <span class="p">[</span>
|
||||
<span class="n">SEARCH_CATEGORY_PHOTO_TYPE_VIDEO</span><span class="p">,</span>
|
||||
<span class="n">SEARCH_CATEGORY_PHOTO_TYPE_SLOMO</span><span class="p">,</span>
|
||||
<span class="n">SEARCH_CATEGORY_PHOTO_TYPE_LIVE</span><span class="p">,</span>
|
||||
<span class="n">SEARCH_CATEGORY_PHOTO_TYPE_SCREENSHOT</span><span class="p">,</span>
|
||||
<span class="n">SEARCH_CATEGORY_PHOTO_TYPE_PANORAMA</span><span class="p">,</span>
|
||||
<span class="n">SEARCH_CATEGORY_PHOTO_TYPE_TIMELAPSE</span><span class="p">,</span>
|
||||
<span class="n">SEARCH_CATEGORY_PHOTO_TYPE_BURSTS</span><span class="p">,</span>
|
||||
<span class="n">SEARCH_CATEGORY_PHOTO_TYPE_PORTRAIT</span><span class="p">,</span>
|
||||
<span class="n">SEARCH_CATEGORY_PHOTO_TYPE_SELFIES</span><span class="p">,</span>
|
||||
<span class="n">SEARCH_CATEGORY_PHOTO_TYPE_FAVORITES</span><span class="p">,</span>
|
||||
<span class="p">]</span>
|
||||
<span class="n">SEARCH_CATEGORY_PHOTO_NAME</span> <span class="o">=</span> <span class="mi">2056</span>
|
||||
|
||||
|
||||
<span class="c1"># Max filename length on MacOS</span>
|
||||
<span class="n">MAX_FILENAME_LEN</span> <span class="o">=</span> <span class="mi">255</span>
|
||||
|
||||
<span class="c1"># Max directory name length on MacOS</span>
|
||||
<span class="n">MAX_DIRNAME_LEN</span> <span class="o">=</span> <span class="mi">255</span>
|
||||
|
||||
<span class="c1"># Default JPEG quality when converting to JPEG</span>
|
||||
<span class="n">DEFAULT_JPEG_QUALITY</span> <span class="o">=</span> <span class="mf">1.0</span>
|
||||
|
||||
<span class="c1"># Default suffix to add to edited images</span>
|
||||
<span class="n">DEFAULT_EDITED_SUFFIX</span> <span class="o">=</span> <span class="s2">"_edited"</span>
|
||||
|
||||
<span class="c1"># Default suffix to add to original images</span>
|
||||
<span class="n">DEFAULT_ORIGINAL_SUFFIX</span> <span class="o">=</span> <span class="s2">""</span>
|
||||
|
||||
<span class="c1"># Default suffix to add to preview images</span>
|
||||
<span class="n">DEFAULT_PREVIEW_SUFFIX</span> <span class="o">=</span> <span class="s2">"_preview"</span>
|
||||
|
||||
<span class="c1"># Bit masks for --sidecar</span>
|
||||
<span class="n">SIDECAR_JSON</span> <span class="o">=</span> <span class="mh">0x1</span>
|
||||
<span class="n">SIDECAR_EXIFTOOL</span> <span class="o">=</span> <span class="mh">0x2</span>
|
||||
<span class="n">SIDECAR_XMP</span> <span class="o">=</span> <span class="mh">0x4</span>
|
||||
|
||||
<span class="c1"># supported attributes for --xattr-template</span>
|
||||
<span class="n">EXTENDED_ATTRIBUTE_NAMES</span> <span class="o">=</span> <span class="p">[</span>
|
||||
<span class="s2">"authors"</span><span class="p">,</span>
|
||||
<span class="s2">"comment"</span><span class="p">,</span>
|
||||
<span class="s2">"copyright"</span><span class="p">,</span>
|
||||
<span class="s2">"creator"</span><span class="p">,</span>
|
||||
<span class="s2">"description"</span><span class="p">,</span>
|
||||
<span class="s2">"findercomment"</span><span class="p">,</span>
|
||||
<span class="s2">"headline"</span><span class="p">,</span>
|
||||
<span class="s2">"keywords"</span><span class="p">,</span>
|
||||
<span class="s2">"participants"</span><span class="p">,</span>
|
||||
<span class="s2">"projects"</span><span class="p">,</span>
|
||||
<span class="s2">"rating"</span><span class="p">,</span>
|
||||
<span class="s2">"subject"</span><span class="p">,</span>
|
||||
<span class="s2">"title"</span><span class="p">,</span>
|
||||
<span class="s2">"version"</span><span class="p">,</span>
|
||||
<span class="p">]</span>
|
||||
<span class="n">EXTENDED_ATTRIBUTE_NAMES_QUOTED</span> <span class="o">=</span> <span class="p">[</span><span class="sa">f</span><span class="s2">"'</span><span class="si">{</span><span class="n">x</span><span class="si">}</span><span class="s2">'"</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">EXTENDED_ATTRIBUTE_NAMES</span><span class="p">]</span>
|
||||
|
||||
|
||||
<span class="c1"># name of export DB</span>
|
||||
<span class="n">OSXPHOTOS_EXPORT_DB</span> <span class="o">=</span> <span class="s2">".osxphotos_export.db"</span>
|
||||
|
||||
<span class="c1"># bit flags for burst images ("burstPickType")</span>
|
||||
<span class="n">BURST_PICK_TYPE_NONE</span> <span class="o">=</span> <span class="mb">0b0</span> <span class="c1"># 0: sometimes used for single images with a burst UUID</span>
|
||||
<span class="n">BURST_NOT_SELECTED</span> <span class="o">=</span> <span class="mb">0b10</span> <span class="c1"># 2: burst image is not selected</span>
|
||||
<span class="n">BURST_DEFAULT_PICK</span> <span class="o">=</span> <span class="mb">0b100</span> <span class="c1"># 4: burst image is the one Photos picked to be key image before any selections made</span>
|
||||
<span class="n">BURST_SELECTED</span> <span class="o">=</span> <span class="mb">0b1000</span> <span class="c1"># 8: burst image is selected</span>
|
||||
<span class="n">BURST_KEY</span> <span class="o">=</span> <span class="mb">0b10000</span> <span class="c1"># 16: burst image is the key photo (top of burst stack)</span>
|
||||
<span class="n">BURST_UNKNOWN</span> <span class="o">=</span> <span class="mb">0b100000</span> <span class="c1"># 32: this is almost always set with BURST_DEFAULT_PICK and never if BURST_DEFAULT_PICK is not set. I think this has something to do with what algorithm Photos used to pick the default image</span>
|
||||
|
||||
<span class="n">LIVE_VIDEO_EXTENSIONS</span> <span class="o">=</span> <span class="p">[</span><span class="s2">".mov"</span><span class="p">]</span>
|
||||
|
||||
<span class="c1"># categories that --post-command can be used with; these map to ExportResults fields</span>
|
||||
<span class="n">POST_COMMAND_CATEGORIES</span> <span class="o">=</span> <span class="p">{</span>
|
||||
<span class="s2">"exported"</span><span class="p">:</span> <span class="s2">"All exported files"</span><span class="p">,</span>
|
||||
<span class="s2">"new"</span><span class="p">:</span> <span class="s2">"When used with '--update', all newly exported files"</span><span class="p">,</span>
|
||||
<span class="s2">"updated"</span><span class="p">:</span> <span class="s2">"When used with '--update', all files which were previously exported but updated this time"</span><span class="p">,</span>
|
||||
<span class="s2">"skipped"</span><span class="p">:</span> <span class="s2">"When used with '--update', all files which were skipped (because they were previously exported and didn't change)"</span><span class="p">,</span>
|
||||
<span class="s2">"missing"</span><span class="p">:</span> <span class="s2">"All files which were not exported because they were missing from the Photos library"</span><span class="p">,</span>
|
||||
<span class="s2">"exif_updated"</span><span class="p">:</span> <span class="s2">"When used with '--exiftool', all files on which exiftool updated the metadata"</span><span class="p">,</span>
|
||||
<span class="s2">"touched"</span><span class="p">:</span> <span class="s2">"When used with '--touch-file', all files where the date was touched"</span><span class="p">,</span>
|
||||
<span class="s2">"converted_to_jpeg"</span><span class="p">:</span> <span class="s2">"When used with '--convert-to-jpeg', all files which were converted to jpeg"</span><span class="p">,</span>
|
||||
<span class="s2">"sidecar_json_written"</span><span class="p">:</span> <span class="s2">"When used with '--sidecar json', all JSON sidecar files which were written"</span><span class="p">,</span>
|
||||
<span class="s2">"sidecar_json_skipped"</span><span class="p">:</span> <span class="s2">"When used with '--sidecar json' and '--update', all JSON sidecar files which were skipped"</span><span class="p">,</span>
|
||||
<span class="s2">"sidecar_exiftool_written"</span><span class="p">:</span> <span class="s2">"When used with '--sidecar exiftool', all exiftool sidecar files which were written"</span><span class="p">,</span>
|
||||
<span class="s2">"sidecar_exiftool_skipped"</span><span class="p">:</span> <span class="s2">"When used with '--sidecar exiftool' and '--update, all exiftool sidecar files which were skipped"</span><span class="p">,</span>
|
||||
<span class="s2">"sidecar_xmp_written"</span><span class="p">:</span> <span class="s2">"When used with '--sidecar xmp', all XMP sidecar files which were written"</span><span class="p">,</span>
|
||||
<span class="s2">"sidecar_xmp_skipped"</span><span class="p">:</span> <span class="s2">"When used with '--sidecar xmp' and '--update', all XMP sidecar files which were skipped"</span><span class="p">,</span>
|
||||
<span class="s2">"error"</span><span class="p">:</span> <span class="s2">"All files which produced an error during export"</span><span class="p">,</span>
|
||||
<span class="c1"># "deleted_files": "When used with '--cleanup', all files deleted during the export",</span>
|
||||
<span class="c1"># "deleted_directories": "When used with '--cleanup', all directories deleted during the export",</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="AlbumSortOrder"><a class="viewcode-back" href="../../reference.html#osxphotos.AlbumSortOrder">[docs]</a><span class="k">class</span> <span class="nc">AlbumSortOrder</span><span class="p">(</span><span class="n">Enum</span><span class="p">):</span>
|
||||
<span class="sd">"""Album Sort Order"""</span>
|
||||
|
||||
<span class="n">UNKNOWN</span> <span class="o">=</span> <span class="mi">0</span>
|
||||
<span class="n">MANUAL</span> <span class="o">=</span> <span class="mi">1</span>
|
||||
<span class="n">NEWEST_FIRST</span> <span class="o">=</span> <span class="mi">2</span>
|
||||
<span class="n">OLDEST_FIRST</span> <span class="o">=</span> <span class="mi">3</span>
|
||||
<span class="n">TITLE</span> <span class="o">=</span> <span class="mi">5</span></div>
|
||||
|
||||
|
||||
<span class="n">TEXT_DETECTION_CONFIDENCE_THRESHOLD</span> <span class="o">=</span> <span class="mf">0.75</span>
|
||||
|
||||
<span class="c1"># stat sort order for cProfile: https://docs.python.org/3/library/profile.html#pstats.Stats.sort_stats</span>
|
||||
<span class="n">PROFILE_SORT_KEYS</span> <span class="o">=</span> <span class="p">[</span>
|
||||
<span class="s2">"calls"</span><span class="p">,</span>
|
||||
<span class="s2">"cumulative"</span><span class="p">,</span>
|
||||
<span class="s2">"cumtime"</span><span class="p">,</span>
|
||||
<span class="s2">"file"</span><span class="p">,</span>
|
||||
<span class="s2">"filename"</span><span class="p">,</span>
|
||||
<span class="s2">"module"</span><span class="p">,</span>
|
||||
<span class="s2">"ncalls"</span><span class="p">,</span>
|
||||
<span class="s2">"pcalls"</span><span class="p">,</span>
|
||||
<span class="s2">"line"</span><span class="p">,</span>
|
||||
<span class="s2">"name"</span><span class="p">,</span>
|
||||
<span class="s2">"nfl"</span><span class="p">,</span>
|
||||
<span class="s2">"stdname"</span><span class="p">,</span>
|
||||
<span class="s2">"time"</span><span class="p">,</span>
|
||||
<span class="s2">"tottime"</span><span class="p">,</span>
|
||||
<span class="p">]</span>
|
||||
</pre></div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||||
<div class="sphinxsidebarwrapper">
|
||||
<h1 class="logo"><a href="../../index.html">osxphotos</a></h1>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../overview.html">osxphotos</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../tutorial.html">Tutorial</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../cli.html">osxphotos command line interface (CLI)</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../reference.html">osxphotos package</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="relations">
|
||||
<h3>Related Topics</h3>
|
||||
<ul>
|
||||
<li><a href="../../index.html">Documentation overview</a><ul>
|
||||
<li><a href="../index.html">Module code</a><ul>
|
||||
</ul></li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="searchbox" style="display: none" role="search">
|
||||
<h3 id="searchlabel">Quick search</h3>
|
||||
<div class="searchformwrapper">
|
||||
<form class="search" action="../../search.html" method="get">
|
||||
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
|
||||
<input type="submit" value="Go" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<script>$('#searchbox').show(0);</script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
©2021, Rhet Turnbull.
|
||||
|
||||
|
|
||||
Powered by <a href="http://sphinx-doc.org/">Sphinx 4.4.0</a>
|
||||
& <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,518 +0,0 @@
|
||||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>osxphotos.albuminfo — osxphotos 0.47.9 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="../../_static/alabaster.css" />
|
||||
<script data-url_root="../../" id="documentation_options" src="../../_static/documentation_options.js"></script>
|
||||
<script src="../../_static/jquery.js"></script>
|
||||
<script src="../../_static/underscore.js"></script>
|
||||
<script src="../../_static/doctools.js"></script>
|
||||
<link rel="index" title="Index" href="../../genindex.html" />
|
||||
<link rel="search" title="Search" href="../../search.html" />
|
||||
|
||||
<link rel="stylesheet" href="../../_static/custom.css" type="text/css" />
|
||||
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
|
||||
|
||||
</head><body>
|
||||
|
||||
|
||||
<div class="document">
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
|
||||
|
||||
<div class="body" role="main">
|
||||
|
||||
<h1>Source code for osxphotos.albuminfo</h1><div class="highlight"><pre>
|
||||
<span></span><span class="sd">"""</span>
|
||||
<span class="sd">AlbumInfo and FolderInfo classes for dealing with albums and folders</span>
|
||||
|
||||
<span class="sd">AlbumInfo class</span>
|
||||
<span class="sd">Represents a single Album in the Photos library and provides access to the album's attributes</span>
|
||||
<span class="sd">PhotosDB.albums() returns a list of AlbumInfo objects</span>
|
||||
|
||||
<span class="sd">FolderInfo class</span>
|
||||
<span class="sd">Represents a single Folder in the Photos library and provides access to the folders attributes</span>
|
||||
<span class="sd">PhotosDB.folders() returns a list of FolderInfo objects</span>
|
||||
<span class="sd">"""</span>
|
||||
|
||||
<span class="kn">from</span> <span class="nn">datetime</span> <span class="kn">import</span> <span class="n">datetime</span><span class="p">,</span> <span class="n">timedelta</span><span class="p">,</span> <span class="n">timezone</span>
|
||||
|
||||
<span class="kn">from</span> <span class="nn">._constants</span> <span class="kn">import</span> <span class="p">(</span>
|
||||
<span class="n">_PHOTOS_4_ALBUM_KIND</span><span class="p">,</span>
|
||||
<span class="n">_PHOTOS_4_TOP_LEVEL_ALBUMS</span><span class="p">,</span>
|
||||
<span class="n">_PHOTOS_4_VERSION</span><span class="p">,</span>
|
||||
<span class="n">_PHOTOS_5_ALBUM_KIND</span><span class="p">,</span>
|
||||
<span class="n">_PHOTOS_5_FOLDER_KIND</span><span class="p">,</span>
|
||||
<span class="n">TIME_DELTA</span><span class="p">,</span>
|
||||
<span class="n">AlbumSortOrder</span><span class="p">,</span>
|
||||
<span class="p">)</span>
|
||||
<span class="kn">from</span> <span class="nn">.datetime_utils</span> <span class="kn">import</span> <span class="n">get_local_tz</span>
|
||||
<span class="kn">from</span> <span class="nn">.query_builder</span> <span class="kn">import</span> <span class="n">get_query</span>
|
||||
|
||||
<span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span>
|
||||
<span class="s2">"sort_list_by_keys"</span><span class="p">,</span>
|
||||
<span class="s2">"AlbumInfoBaseClass"</span><span class="p">,</span>
|
||||
<span class="s2">"AlbumInfo"</span><span class="p">,</span>
|
||||
<span class="s2">"ImportInfo"</span><span class="p">,</span>
|
||||
<span class="s2">"ProjectInfo"</span><span class="p">,</span>
|
||||
<span class="s2">"FolderInfo"</span><span class="p">,</span>
|
||||
<span class="p">]</span>
|
||||
|
||||
|
||||
<span class="k">def</span> <span class="nf">sort_list_by_keys</span><span class="p">(</span><span class="n">values</span><span class="p">,</span> <span class="n">sort_keys</span><span class="p">):</span>
|
||||
<span class="sd">"""Sorts list values by a second list sort_keys</span>
|
||||
<span class="sd"> e.g. given ["a","c","b"], [1, 3, 2], returns ["a", "b", "c"]</span>
|
||||
|
||||
<span class="sd"> Args:</span>
|
||||
<span class="sd"> values: a list of values to be sorted</span>
|
||||
<span class="sd"> sort_keys: a list of keys to sort values by</span>
|
||||
|
||||
<span class="sd"> Returns:</span>
|
||||
<span class="sd"> list of values, sorted by sort_keys</span>
|
||||
|
||||
<span class="sd"> Raises:</span>
|
||||
<span class="sd"> ValueError: raised if len(values) != len(sort_keys)</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">values</span><span class="p">)</span> <span class="o">!=</span> <span class="nb">len</span><span class="p">(</span><span class="n">sort_keys</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">"values and sort_keys must have same length"</span><span class="p">)</span>
|
||||
|
||||
<span class="k">return</span> <span class="nb">list</span><span class="p">(</span><span class="nb">zip</span><span class="p">(</span><span class="o">*</span><span class="nb">sorted</span><span class="p">(</span><span class="nb">zip</span><span class="p">(</span><span class="n">sort_keys</span><span class="p">,</span> <span class="n">values</span><span class="p">))))[</span><span class="mi">1</span><span class="p">]</span>
|
||||
|
||||
|
||||
<span class="k">class</span> <span class="nc">AlbumInfoBaseClass</span><span class="p">:</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Base class for AlbumInfo, ImportInfo</span>
|
||||
<span class="sd"> Info about a specific Album, contains all the details about the album</span>
|
||||
<span class="sd"> including folders, photos, etc.</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">db</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">uuid</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_uuid</span> <span class="o">=</span> <span class="n">uuid</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_db</span> <span class="o">=</span> <span class="n">db</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_title</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_dbalbum_details</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"title"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_creation_date_timestamp</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_dbalbum_details</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"creation_date"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_start_date_timestamp</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_dbalbum_details</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"start_date"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_end_date_timestamp</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_dbalbum_details</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"end_date"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_local_tz</span> <span class="o">=</span> <span class="n">get_local_tz</span><span class="p">(</span>
|
||||
<span class="n">datetime</span><span class="o">.</span><span class="n">fromtimestamp</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_creation_date_timestamp</span> <span class="o">+</span> <span class="n">TIME_DELTA</span><span class="p">)</span>
|
||||
<span class="p">)</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">uuid</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""return uuid of album"""</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_uuid</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">creation_date</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""return creation date of album"""</span>
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_creation_date</span>
|
||||
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_creation_date</span> <span class="o">=</span> <span class="p">(</span>
|
||||
<span class="n">datetime</span><span class="o">.</span><span class="n">fromtimestamp</span><span class="p">(</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_creation_date_timestamp</span> <span class="o">+</span> <span class="n">TIME_DELTA</span>
|
||||
<span class="p">)</span><span class="o">.</span><span class="n">astimezone</span><span class="p">(</span><span class="n">tz</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_local_tz</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_creation_date_timestamp</span>
|
||||
<span class="k">else</span> <span class="n">datetime</span><span class="p">(</span><span class="mi">1970</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span><span class="o">.</span><span class="n">astimezone</span><span class="p">(</span>
|
||||
<span class="n">tz</span><span class="o">=</span><span class="n">timezone</span><span class="p">(</span><span class="n">timedelta</span><span class="p">(</span><span class="mi">0</span><span class="p">))</span>
|
||||
<span class="p">)</span>
|
||||
<span class="p">)</span>
|
||||
<span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_creation_date</span> <span class="o">=</span> <span class="n">datetime</span><span class="p">(</span><span class="mi">1970</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span><span class="o">.</span><span class="n">astimezone</span><span class="p">(</span>
|
||||
<span class="n">tz</span><span class="o">=</span><span class="n">timezone</span><span class="p">(</span><span class="n">timedelta</span><span class="p">(</span><span class="mi">0</span><span class="p">))</span>
|
||||
<span class="p">)</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_creation_date</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">start_date</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""For Albums, return start date (earliest image) of album or None for albums with no images</span>
|
||||
<span class="sd"> For Import Sessions, return start date of import session (when import began)"""</span>
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_start_date</span>
|
||||
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_start_date</span> <span class="o">=</span> <span class="p">(</span>
|
||||
<span class="n">datetime</span><span class="o">.</span><span class="n">fromtimestamp</span><span class="p">(</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_start_date_timestamp</span> <span class="o">+</span> <span class="n">TIME_DELTA</span>
|
||||
<span class="p">)</span><span class="o">.</span><span class="n">astimezone</span><span class="p">(</span><span class="n">tz</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_local_tz</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_start_date_timestamp</span>
|
||||
<span class="k">else</span> <span class="kc">None</span>
|
||||
<span class="p">)</span>
|
||||
<span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_start_date</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_start_date</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">end_date</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""For Albums, return end date (most recent image) of album or None for albums with no images</span>
|
||||
<span class="sd"> For Import Sessions, return end date of import sessions (when import was completed)"""</span>
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_end_date</span>
|
||||
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_end_date</span> <span class="o">=</span> <span class="p">(</span>
|
||||
<span class="n">datetime</span><span class="o">.</span><span class="n">fromtimestamp</span><span class="p">(</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_end_date_timestamp</span> <span class="o">+</span> <span class="n">TIME_DELTA</span>
|
||||
<span class="p">)</span><span class="o">.</span><span class="n">astimezone</span><span class="p">(</span><span class="n">tz</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_local_tz</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_end_date_timestamp</span>
|
||||
<span class="k">else</span> <span class="kc">None</span>
|
||||
<span class="p">)</span>
|
||||
<span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_end_date</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_end_date</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">photos</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="p">[]</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">owner</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""Return name of photo owner for shared album (Photos 5+ only), or None if not shared"""</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_db_version</span> <span class="o"><=</span> <span class="n">_PHOTOS_4_VERSION</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="kc">None</span>
|
||||
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_owner</span>
|
||||
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="n">personid</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_dbalbum_details</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">uuid</span><span class="p">][</span>
|
||||
<span class="s2">"cloudownerhashedpersonid"</span>
|
||||
<span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_owner</span> <span class="o">=</span> <span class="p">(</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_db_hashed_person_id</span><span class="p">[</span><span class="n">personid</span><span class="p">][</span><span class="s2">"full_name"</span><span class="p">]</span>
|
||||
<span class="k">if</span> <span class="n">personid</span>
|
||||
<span class="k">else</span> <span class="kc">None</span>
|
||||
<span class="p">)</span>
|
||||
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_owner</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_owner</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__len__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""return number of photos contained in album"""</span>
|
||||
<span class="k">return</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">photos</span><span class="p">)</span>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="AlbumInfo"><a class="viewcode-back" href="../../reference.html#osxphotos.AlbumInfo">[docs]</a><span class="k">class</span> <span class="nc">AlbumInfo</span><span class="p">(</span><span class="n">AlbumInfoBaseClass</span><span class="p">):</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Info about a specific Album, contains all the details about the album</span>
|
||||
<span class="sd"> including folders, photos, etc.</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">title</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""return title / name of album"""</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_title</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">photos</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""return list of photos contained in album sorted in same sort order as Photos"""</span>
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_photos</span>
|
||||
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">uuid</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_dbalbums_album</span><span class="p">:</span>
|
||||
<span class="n">uuid</span><span class="p">,</span> <span class="n">sort_order</span> <span class="o">=</span> <span class="nb">zip</span><span class="p">(</span><span class="o">*</span><span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_dbalbums_album</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">uuid</span><span class="p">])</span>
|
||||
<span class="n">sorted_uuid</span> <span class="o">=</span> <span class="n">sort_list_by_keys</span><span class="p">(</span><span class="n">uuid</span><span class="p">,</span> <span class="n">sort_order</span><span class="p">)</span>
|
||||
<span class="n">photos</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">photos_by_uuid</span><span class="p">(</span><span class="n">sorted_uuid</span><span class="p">)</span>
|
||||
<span class="n">sort_order</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">sort_order</span>
|
||||
<span class="k">if</span> <span class="n">sort_order</span> <span class="o">==</span> <span class="n">AlbumSortOrder</span><span class="o">.</span><span class="n">NEWEST_FIRST</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_photos</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">photos</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">p</span><span class="p">:</span> <span class="n">p</span><span class="o">.</span><span class="n">date</span><span class="p">,</span> <span class="n">reverse</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
|
||||
<span class="k">elif</span> <span class="n">sort_order</span> <span class="o">==</span> <span class="n">AlbumSortOrder</span><span class="o">.</span><span class="n">OLDEST_FIRST</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_photos</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">photos</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">p</span><span class="p">:</span> <span class="n">p</span><span class="o">.</span><span class="n">date</span><span class="p">)</span>
|
||||
<span class="k">elif</span> <span class="n">sort_order</span> <span class="o">==</span> <span class="n">AlbumSortOrder</span><span class="o">.</span><span class="n">TITLE</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_photos</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">photos</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">p</span><span class="p">:</span> <span class="n">p</span><span class="o">.</span><span class="n">title</span> <span class="ow">or</span> <span class="s2">""</span><span class="p">)</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="c1"># assume AlbumSortOrder.MANUAL</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_photos</span> <span class="o">=</span> <span class="n">photos</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_photos</span> <span class="o">=</span> <span class="p">[]</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_photos</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">folder_names</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""return hierarchical list of folders the album is contained in</span>
|
||||
<span class="sd"> the folder list is in form:</span>
|
||||
<span class="sd"> ["Top level folder", "sub folder 1", "sub folder 2", ...]</span>
|
||||
<span class="sd"> returns empty list if album is not in any folders"""</span>
|
||||
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_folder_names</span>
|
||||
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_folder_names</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_album_folder_hierarchy_list</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_uuid</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_folder_names</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">folder_list</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""return hierarchical list of folders the album is contained in</span>
|
||||
<span class="sd"> as list of FolderInfo objects in form</span>
|
||||
<span class="sd"> ["Top level folder", "sub folder 1", "sub folder 2", ...]</span>
|
||||
<span class="sd"> returns empty list if album is not in any folders"""</span>
|
||||
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_folders</span>
|
||||
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_folders</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_album_folder_hierarchy_folderinfo</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_uuid</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_folders</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">parent</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""returns FolderInfo object for parent folder or None if no parent (e.g. top-level album)"""</span>
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_parent</span>
|
||||
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_db_version</span> <span class="o"><=</span> <span class="n">_PHOTOS_4_VERSION</span><span class="p">:</span>
|
||||
<span class="n">parent_uuid</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_dbalbum_details</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">_uuid</span><span class="p">][</span><span class="s2">"folderUuid"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_parent</span> <span class="o">=</span> <span class="p">(</span>
|
||||
<span class="n">FolderInfo</span><span class="p">(</span><span class="n">db</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="p">,</span> <span class="n">uuid</span><span class="o">=</span><span class="n">parent_uuid</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="n">parent_uuid</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">_PHOTOS_4_TOP_LEVEL_ALBUMS</span>
|
||||
<span class="k">else</span> <span class="kc">None</span>
|
||||
<span class="p">)</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="n">parent_pk</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_dbalbum_details</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">_uuid</span><span class="p">][</span><span class="s2">"parentfolder"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_parent</span> <span class="o">=</span> <span class="p">(</span>
|
||||
<span class="n">FolderInfo</span><span class="p">(</span><span class="n">db</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="p">,</span> <span class="n">uuid</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_dbalbums_pk</span><span class="p">[</span><span class="n">parent_pk</span><span class="p">])</span>
|
||||
<span class="k">if</span> <span class="n">parent_pk</span> <span class="o">!=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_folder_root_pk</span>
|
||||
<span class="k">else</span> <span class="kc">None</span>
|
||||
<span class="p">)</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_parent</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">sort_order</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""return sort order of album"""</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_db_version</span> <span class="o"><=</span> <span class="n">_PHOTOS_4_VERSION</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="n">AlbumSortOrder</span><span class="o">.</span><span class="n">MANUAL</span>
|
||||
|
||||
<span class="n">details</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_dbalbum_details</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">_uuid</span><span class="p">]</span>
|
||||
<span class="k">if</span> <span class="n">details</span><span class="p">[</span><span class="s2">"customsortkey"</span><span class="p">]</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
|
||||
<span class="k">if</span> <span class="n">details</span><span class="p">[</span><span class="s2">"customsortascending"</span><span class="p">]</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="n">AlbumSortOrder</span><span class="o">.</span><span class="n">NEWEST_FIRST</span>
|
||||
<span class="k">elif</span> <span class="n">details</span><span class="p">[</span><span class="s2">"customsortascending"</span><span class="p">]</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="n">AlbumSortOrder</span><span class="o">.</span><span class="n">OLDEST_FIRST</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="n">AlbumSortOrder</span><span class="o">.</span><span class="n">UNKNOWN</span>
|
||||
<span class="k">elif</span> <span class="n">details</span><span class="p">[</span><span class="s2">"customsortkey"</span><span class="p">]</span> <span class="o">==</span> <span class="mi">5</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="n">AlbumSortOrder</span><span class="o">.</span><span class="n">TITLE</span>
|
||||
<span class="k">elif</span> <span class="n">details</span><span class="p">[</span><span class="s2">"customsortkey"</span><span class="p">]</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="n">AlbumSortOrder</span><span class="o">.</span><span class="n">MANUAL</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="n">AlbumSortOrder</span><span class="o">.</span><span class="n">UNKNOWN</span>
|
||||
|
||||
<div class="viewcode-block" id="AlbumInfo.photo_index"><a class="viewcode-back" href="../../reference.html#osxphotos.AlbumInfo.photo_index">[docs]</a> <span class="k">def</span> <span class="nf">photo_index</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="sd">"""return index of photo in album (based on album sort order)"""</span>
|
||||
<span class="k">for</span> <span class="n">index</span><span class="p">,</span> <span class="n">p</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">photos</span><span class="p">):</span>
|
||||
<span class="k">if</span> <span class="n">p</span><span class="o">.</span><span class="n">uuid</span> <span class="o">==</span> <span class="n">photo</span><span class="o">.</span><span class="n">uuid</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="n">index</span>
|
||||
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
|
||||
<span class="sa">f</span><span class="s2">"Photo with uuid </span><span class="si">{</span><span class="n">photo</span><span class="o">.</span><span class="n">uuid</span><span class="si">}</span><span class="s2"> does not appear to be in this album"</span>
|
||||
<span class="p">)</span></div></div>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="ImportInfo"><a class="viewcode-back" href="../../reference.html#osxphotos.ImportInfo">[docs]</a><span class="k">class</span> <span class="nc">ImportInfo</span><span class="p">(</span><span class="n">AlbumInfoBaseClass</span><span class="p">):</span>
|
||||
<span class="sd">"""Information about import sessions"""</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">photos</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""return list of photos contained in import session"""</span>
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_photos</span>
|
||||
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
|
||||
<span class="n">uuid_list</span><span class="p">,</span> <span class="n">sort_order</span> <span class="o">=</span> <span class="nb">zip</span><span class="p">(</span>
|
||||
<span class="o">*</span><span class="p">[</span>
|
||||
<span class="p">(</span><span class="n">uuid</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"fok_import_session"</span><span class="p">])</span>
|
||||
<span class="k">for</span> <span class="n">uuid</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_dbphotos</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_dbphotos</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"import_uuid"</span><span class="p">]</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">uuid</span>
|
||||
<span class="p">]</span>
|
||||
<span class="p">)</span>
|
||||
<span class="n">sorted_uuid</span> <span class="o">=</span> <span class="n">sort_list_by_keys</span><span class="p">(</span><span class="n">uuid_list</span><span class="p">,</span> <span class="n">sort_order</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_photos</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">photos_by_uuid</span><span class="p">(</span><span class="n">sorted_uuid</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_photos</span></div>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="ProjectInfo"><a class="viewcode-back" href="../../reference.html#osxphotos.ProjectInfo">[docs]</a><span class="k">class</span> <span class="nc">ProjectInfo</span><span class="p">(</span><span class="n">AlbumInfo</span><span class="p">):</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> ProjectInfo with info about projects</span>
|
||||
<span class="sd"> Projects are cards, calendars, slideshows, etc.</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="o">...</span></div>
|
||||
|
||||
|
||||
<span class="k">class</span> <span class="nc">FolderInfo</span><span class="p">:</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> Info about a specific folder, contains all the details about the folder</span>
|
||||
<span class="sd"> including folders, albums, etc</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">db</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">uuid</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_uuid</span> <span class="o">=</span> <span class="n">uuid</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_db</span> <span class="o">=</span> <span class="n">db</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_db_version</span> <span class="o"><=</span> <span class="n">_PHOTOS_4_VERSION</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_pk</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_title</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_dbfolder_details</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"name"</span><span class="p">]</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_pk</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_dbalbum_details</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"pk"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_title</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_dbalbum_details</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"title"</span><span class="p">]</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">title</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""return title / name of folder"""</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_title</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">uuid</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""return uuid of folder"""</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_uuid</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">album_info</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""return list of albums (as AlbumInfo objects) contained in the folder"""</span>
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_albums</span>
|
||||
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_db_version</span> <span class="o"><=</span> <span class="n">_PHOTOS_4_VERSION</span><span class="p">:</span>
|
||||
<span class="n">albums</span> <span class="o">=</span> <span class="p">[</span>
|
||||
<span class="n">AlbumInfo</span><span class="p">(</span><span class="n">db</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="p">,</span> <span class="n">uuid</span><span class="o">=</span><span class="n">album</span><span class="p">)</span>
|
||||
<span class="k">for</span> <span class="n">album</span><span class="p">,</span> <span class="n">detail</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_dbalbum_details</span><span class="o">.</span><span class="n">items</span><span class="p">()</span>
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="n">detail</span><span class="p">[</span><span class="s2">"intrash"</span><span class="p">]</span>
|
||||
<span class="ow">and</span> <span class="n">detail</span><span class="p">[</span><span class="s2">"albumSubclass"</span><span class="p">]</span> <span class="o">==</span> <span class="n">_PHOTOS_4_ALBUM_KIND</span>
|
||||
<span class="ow">and</span> <span class="n">detail</span><span class="p">[</span><span class="s2">"folderUuid"</span><span class="p">]</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">_uuid</span>
|
||||
<span class="p">]</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="n">albums</span> <span class="o">=</span> <span class="p">[</span>
|
||||
<span class="n">AlbumInfo</span><span class="p">(</span><span class="n">db</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="p">,</span> <span class="n">uuid</span><span class="o">=</span><span class="n">album</span><span class="p">)</span>
|
||||
<span class="k">for</span> <span class="n">album</span><span class="p">,</span> <span class="n">detail</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_dbalbum_details</span><span class="o">.</span><span class="n">items</span><span class="p">()</span>
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="n">detail</span><span class="p">[</span><span class="s2">"intrash"</span><span class="p">]</span>
|
||||
<span class="ow">and</span> <span class="n">detail</span><span class="p">[</span><span class="s2">"kind"</span><span class="p">]</span> <span class="o">==</span> <span class="n">_PHOTOS_5_ALBUM_KIND</span>
|
||||
<span class="ow">and</span> <span class="n">detail</span><span class="p">[</span><span class="s2">"parentfolder"</span><span class="p">]</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">_pk</span>
|
||||
<span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_albums</span> <span class="o">=</span> <span class="n">albums</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_albums</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">parent</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""returns FolderInfo object for parent or None if no parent (e.g. top-level folder)"""</span>
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_parent</span>
|
||||
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_db_version</span> <span class="o"><=</span> <span class="n">_PHOTOS_4_VERSION</span><span class="p">:</span>
|
||||
<span class="n">parent_uuid</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_dbfolder_details</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">_uuid</span><span class="p">][</span><span class="s2">"parentFolderUuid"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_parent</span> <span class="o">=</span> <span class="p">(</span>
|
||||
<span class="n">FolderInfo</span><span class="p">(</span><span class="n">db</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="p">,</span> <span class="n">uuid</span><span class="o">=</span><span class="n">parent_uuid</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="n">parent_uuid</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">_PHOTOS_4_TOP_LEVEL_ALBUMS</span>
|
||||
<span class="k">else</span> <span class="kc">None</span>
|
||||
<span class="p">)</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="n">parent_pk</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_dbalbum_details</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">_uuid</span><span class="p">][</span><span class="s2">"parentfolder"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_parent</span> <span class="o">=</span> <span class="p">(</span>
|
||||
<span class="n">FolderInfo</span><span class="p">(</span><span class="n">db</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="p">,</span> <span class="n">uuid</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_dbalbums_pk</span><span class="p">[</span><span class="n">parent_pk</span><span class="p">])</span>
|
||||
<span class="k">if</span> <span class="n">parent_pk</span> <span class="o">!=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_folder_root_pk</span>
|
||||
<span class="k">else</span> <span class="kc">None</span>
|
||||
<span class="p">)</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_parent</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">subfolders</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""return list of folders (as FolderInfo objects) contained in the folder"""</span>
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_folders</span>
|
||||
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_db_version</span> <span class="o"><=</span> <span class="n">_PHOTOS_4_VERSION</span><span class="p">:</span>
|
||||
<span class="n">folders</span> <span class="o">=</span> <span class="p">[</span>
|
||||
<span class="n">FolderInfo</span><span class="p">(</span><span class="n">db</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="p">,</span> <span class="n">uuid</span><span class="o">=</span><span class="n">folder</span><span class="p">)</span>
|
||||
<span class="k">for</span> <span class="n">folder</span><span class="p">,</span> <span class="n">detail</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_dbfolder_details</span><span class="o">.</span><span class="n">items</span><span class="p">()</span>
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="n">detail</span><span class="p">[</span><span class="s2">"intrash"</span><span class="p">]</span>
|
||||
<span class="ow">and</span> <span class="ow">not</span> <span class="n">detail</span><span class="p">[</span><span class="s2">"isMagic"</span><span class="p">]</span>
|
||||
<span class="ow">and</span> <span class="n">detail</span><span class="p">[</span><span class="s2">"parentFolderUuid"</span><span class="p">]</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">_uuid</span>
|
||||
<span class="p">]</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="n">folders</span> <span class="o">=</span> <span class="p">[</span>
|
||||
<span class="n">FolderInfo</span><span class="p">(</span><span class="n">db</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="p">,</span> <span class="n">uuid</span><span class="o">=</span><span class="n">album</span><span class="p">)</span>
|
||||
<span class="k">for</span> <span class="n">album</span><span class="p">,</span> <span class="n">detail</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_dbalbum_details</span><span class="o">.</span><span class="n">items</span><span class="p">()</span>
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="n">detail</span><span class="p">[</span><span class="s2">"intrash"</span><span class="p">]</span>
|
||||
<span class="ow">and</span> <span class="n">detail</span><span class="p">[</span><span class="s2">"kind"</span><span class="p">]</span> <span class="o">==</span> <span class="n">_PHOTOS_5_FOLDER_KIND</span>
|
||||
<span class="ow">and</span> <span class="n">detail</span><span class="p">[</span><span class="s2">"parentfolder"</span><span class="p">]</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">_pk</span>
|
||||
<span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_folders</span> <span class="o">=</span> <span class="n">folders</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_folders</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__len__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""returns count of folders + albums contained in the folder"""</span>
|
||||
<span class="k">return</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">subfolders</span><span class="p">)</span> <span class="o">+</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">album_info</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||||
<div class="sphinxsidebarwrapper">
|
||||
<h1 class="logo"><a href="../../index.html">osxphotos</a></h1>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../overview.html">osxphotos</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../tutorial.html">Tutorial</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../cli.html">osxphotos command line interface (CLI)</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../reference.html">osxphotos package</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="relations">
|
||||
<h3>Related Topics</h3>
|
||||
<ul>
|
||||
<li><a href="../../index.html">Documentation overview</a><ul>
|
||||
<li><a href="../index.html">Module code</a><ul>
|
||||
</ul></li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="searchbox" style="display: none" role="search">
|
||||
<h3 id="searchlabel">Quick search</h3>
|
||||
<div class="searchformwrapper">
|
||||
<form class="search" action="../../search.html" method="get">
|
||||
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
|
||||
<input type="submit" value="Go" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<script>$('#searchbox').show(0);</script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
©2021, Rhet Turnbull.
|
||||
|
||||
|
|
||||
Powered by <a href="http://sphinx-doc.org/">Sphinx 4.4.0</a>
|
||||
& <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,206 +0,0 @@
|
||||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>osxphotos.debug — osxphotos 0.47.9 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="../../_static/alabaster.css" />
|
||||
<script data-url_root="../../" id="documentation_options" src="../../_static/documentation_options.js"></script>
|
||||
<script src="../../_static/jquery.js"></script>
|
||||
<script src="../../_static/underscore.js"></script>
|
||||
<script src="../../_static/doctools.js"></script>
|
||||
<link rel="index" title="Index" href="../../genindex.html" />
|
||||
<link rel="search" title="Search" href="../../search.html" />
|
||||
|
||||
<link rel="stylesheet" href="../../_static/custom.css" type="text/css" />
|
||||
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
|
||||
|
||||
</head><body>
|
||||
|
||||
|
||||
<div class="document">
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
|
||||
|
||||
<div class="body" role="main">
|
||||
|
||||
<h1>Source code for osxphotos.debug</h1><div class="highlight"><pre>
|
||||
<span></span><span class="sd">"""Utilities for debugging"""</span>
|
||||
|
||||
<span class="kn">import</span> <span class="nn">logging</span>
|
||||
<span class="kn">import</span> <span class="nn">sys</span>
|
||||
<span class="kn">import</span> <span class="nn">time</span>
|
||||
<span class="kn">from</span> <span class="nn">datetime</span> <span class="kn">import</span> <span class="n">datetime</span>
|
||||
<span class="kn">from</span> <span class="nn">typing</span> <span class="kn">import</span> <span class="n">Dict</span><span class="p">,</span> <span class="n">List</span>
|
||||
|
||||
<span class="kn">import</span> <span class="nn">wrapt</span>
|
||||
<span class="kn">from</span> <span class="nn">rich</span> <span class="kn">import</span> <span class="nb">print</span>
|
||||
|
||||
<span class="c1"># global variable to control debug output</span>
|
||||
<span class="c1"># set via --debug</span>
|
||||
<span class="n">DEBUG</span> <span class="o">=</span> <span class="kc">False</span>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="set_debug"><a class="viewcode-back" href="../../reference.html#osxphotos.set_debug">[docs]</a><span class="k">def</span> <span class="nf">set_debug</span><span class="p">(</span><span class="n">debug</span><span class="p">:</span> <span class="nb">bool</span><span class="p">):</span>
|
||||
<span class="sd">"""set debug flag"""</span>
|
||||
<span class="k">global</span> <span class="n">DEBUG</span>
|
||||
<span class="n">DEBUG</span> <span class="o">=</span> <span class="n">debug</span>
|
||||
<span class="n">logging</span><span class="o">.</span><span class="n">disable</span><span class="p">(</span><span class="n">logging</span><span class="o">.</span><span class="n">NOTSET</span> <span class="k">if</span> <span class="n">debug</span> <span class="k">else</span> <span class="n">logging</span><span class="o">.</span><span class="n">DEBUG</span><span class="p">)</span></div>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="is_debug"><a class="viewcode-back" href="../../reference.html#osxphotos.is_debug">[docs]</a><span class="k">def</span> <span class="nf">is_debug</span><span class="p">():</span>
|
||||
<span class="sd">"""return debug flag"""</span>
|
||||
<span class="k">return</span> <span class="n">DEBUG</span></div>
|
||||
|
||||
|
||||
<span class="k">def</span> <span class="nf">debug_watch</span><span class="p">(</span><span class="n">wrapped</span><span class="p">,</span> <span class="n">instance</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">):</span>
|
||||
<span class="sd">"""For use with wrapt.wrap_function_wrapper to watch calls to a function"""</span>
|
||||
<span class="n">caller</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">_getframe</span><span class="p">()</span><span class="o">.</span><span class="n">f_back</span><span class="o">.</span><span class="n">f_code</span><span class="o">.</span><span class="n">co_name</span>
|
||||
<span class="n">name</span> <span class="o">=</span> <span class="n">wrapped</span><span class="o">.</span><span class="vm">__name__</span>
|
||||
<span class="n">timestamp</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">isoformat</span><span class="p">()</span>
|
||||
<span class="nb">print</span><span class="p">(</span>
|
||||
<span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">timestamp</span><span class="si">}</span><span class="s2"> </span><span class="si">{</span><span class="n">name</span><span class="si">}</span><span class="s2"> called from </span><span class="si">{</span><span class="n">caller</span><span class="si">}</span><span class="s2"> with args: </span><span class="si">{</span><span class="n">args</span><span class="si">}</span><span class="s2"> and kwargs: </span><span class="si">{</span><span class="n">kwargs</span><span class="si">}</span><span class="s2">"</span>
|
||||
<span class="p">)</span>
|
||||
<span class="n">start_t</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">perf_counter</span><span class="p">()</span>
|
||||
<span class="n">rv</span> <span class="o">=</span> <span class="n">wrapped</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
|
||||
<span class="n">stop_t</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">perf_counter</span><span class="p">()</span>
|
||||
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">timestamp</span><span class="si">}</span><span class="s2"> </span><span class="si">{</span><span class="n">name</span><span class="si">}</span><span class="s2"> returned: </span><span class="si">{</span><span class="n">rv</span><span class="si">}</span><span class="s2">, elapsed time: </span><span class="si">{</span><span class="n">stop_t</span> <span class="o">-</span> <span class="n">start_t</span><span class="si">}</span><span class="s2"> sec"</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="n">rv</span>
|
||||
|
||||
|
||||
<span class="k">def</span> <span class="nf">debug_breakpoint</span><span class="p">(</span><span class="n">wrapped</span><span class="p">,</span> <span class="n">instance</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">):</span>
|
||||
<span class="sd">"""For use with wrapt.wrap_function_wrapper to set breakpoint on a function"""</span>
|
||||
<span class="nb">breakpoint</span><span class="p">()</span>
|
||||
<span class="k">return</span> <span class="n">wrapped</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
|
||||
|
||||
|
||||
<span class="k">def</span> <span class="nf">wrap_function</span><span class="p">(</span><span class="n">function_path</span><span class="p">,</span> <span class="n">wrapper</span><span class="p">):</span>
|
||||
<span class="sd">"""Wrap a function with wrapper function"""</span>
|
||||
<span class="n">module</span><span class="p">,</span> <span class="n">name</span> <span class="o">=</span> <span class="n">function_path</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">"."</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="n">wrapt</span><span class="o">.</span><span class="n">wrap_function_wrapper</span><span class="p">(</span><span class="n">module</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">wrapper</span><span class="p">)</span>
|
||||
<span class="k">except</span> <span class="ne">AttributeError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
|
||||
<span class="k">raise</span> <span class="ne">AttributeError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">module</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="n">name</span><span class="si">}</span><span class="s2"> does not exist"</span><span class="p">)</span> <span class="kn">from</span> <span class="nn">e</span>
|
||||
|
||||
|
||||
<span class="k">def</span> <span class="nf">get_debug_options</span><span class="p">(</span><span class="n">arg_names</span><span class="p">:</span> <span class="n">List</span><span class="p">,</span> <span class="n">argv</span><span class="p">:</span> <span class="n">List</span><span class="p">)</span> <span class="o">-></span> <span class="n">Dict</span><span class="p">:</span>
|
||||
<span class="sd">"""Get the options for the debug options;</span>
|
||||
<span class="sd"> Some of the debug options like --watch and --breakpoint need to be processed before any other packages are loaded</span>
|
||||
<span class="sd"> so they can't be handled in the normal click argument processing, thus this function is called</span>
|
||||
<span class="sd"> from osxphotos/cli/__init__.py</span>
|
||||
|
||||
<span class="sd"> Assumes multi-valued options are OK and that all options take form of --option VALUE or --option=VALUE</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="c1"># argv[0] is the program name</span>
|
||||
<span class="c1"># argv[1] is the command</span>
|
||||
<span class="c1"># argv[2:] are the arguments</span>
|
||||
<span class="n">args</span> <span class="o">=</span> <span class="p">{}</span>
|
||||
<span class="k">for</span> <span class="n">arg_name</span> <span class="ow">in</span> <span class="n">arg_names</span><span class="p">:</span>
|
||||
<span class="k">for</span> <span class="n">idx</span><span class="p">,</span> <span class="n">arg</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">:]):</span>
|
||||
<span class="k">if</span> <span class="n">arg</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">arg_name</span><span class="si">}</span><span class="s2">="</span><span class="p">):</span>
|
||||
<span class="n">arg_value</span> <span class="o">=</span> <span class="n">arg</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">"="</span><span class="p">)[</span><span class="mi">1</span><span class="p">]</span>
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="n">args</span><span class="p">[</span><span class="n">arg</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">arg_value</span><span class="p">)</span>
|
||||
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
|
||||
<span class="n">args</span><span class="p">[</span><span class="n">arg</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="n">arg_value</span><span class="p">]</span>
|
||||
<span class="k">elif</span> <span class="n">arg</span> <span class="o">==</span> <span class="n">arg_name</span><span class="p">:</span>
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="n">args</span><span class="p">[</span><span class="n">arg</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">argv</span><span class="p">[</span><span class="n">idx</span> <span class="o">+</span> <span class="mi">2</span><span class="p">])</span>
|
||||
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="n">args</span><span class="p">[</span><span class="n">arg</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="n">argv</span><span class="p">[</span><span class="n">idx</span> <span class="o">+</span> <span class="mi">2</span><span class="p">]]</span>
|
||||
<span class="k">except</span> <span class="ne">IndexError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
|
||||
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Missing value for </span><span class="si">{</span><span class="n">arg</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span> <span class="kn">from</span> <span class="nn">e</span>
|
||||
<span class="k">except</span> <span class="ne">IndexError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
|
||||
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Missing value for </span><span class="si">{</span><span class="n">arg</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span> <span class="kn">from</span> <span class="nn">e</span>
|
||||
<span class="k">return</span> <span class="n">args</span>
|
||||
|
||||
|
||||
<span class="k">def</span> <span class="nf">get_debug_flags</span><span class="p">(</span><span class="n">arg_names</span><span class="p">:</span> <span class="n">List</span><span class="p">,</span> <span class="n">argv</span><span class="p">:</span> <span class="n">List</span><span class="p">)</span> <span class="o">-></span> <span class="n">Dict</span><span class="p">:</span>
|
||||
<span class="sd">"""Get the flags for the debug options;</span>
|
||||
<span class="sd"> Processes flags like --debug that resolve to True or False</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="c1"># argv[0] is the program name</span>
|
||||
<span class="c1"># argv[1] is the command</span>
|
||||
<span class="c1"># argv[2:] are the arguments</span>
|
||||
<span class="n">args</span> <span class="o">=</span> <span class="p">{</span><span class="n">arg_name</span><span class="p">:</span> <span class="kc">False</span> <span class="k">for</span> <span class="n">arg_name</span> <span class="ow">in</span> <span class="n">arg_names</span><span class="p">}</span>
|
||||
<span class="k">for</span> <span class="n">arg_name</span> <span class="ow">in</span> <span class="n">arg_names</span><span class="p">:</span>
|
||||
<span class="k">if</span> <span class="n">arg_name</span> <span class="ow">in</span> <span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">:]:</span>
|
||||
<span class="n">args</span><span class="p">[</span><span class="n">arg_name</span><span class="p">]</span> <span class="o">=</span> <span class="kc">True</span>
|
||||
<span class="k">return</span> <span class="n">args</span>
|
||||
</pre></div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||||
<div class="sphinxsidebarwrapper">
|
||||
<h1 class="logo"><a href="../../index.html">osxphotos</a></h1>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../overview.html">osxphotos</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../tutorial.html">Tutorial</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../cli.html">osxphotos command line interface (CLI)</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../reference.html">osxphotos package</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="relations">
|
||||
<h3>Related Topics</h3>
|
||||
<ul>
|
||||
<li><a href="../../index.html">Documentation overview</a><ul>
|
||||
<li><a href="../index.html">Module code</a><ul>
|
||||
</ul></li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="searchbox" style="display: none" role="search">
|
||||
<h3 id="searchlabel">Quick search</h3>
|
||||
<div class="searchformwrapper">
|
||||
<form class="search" action="../../search.html" method="get">
|
||||
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
|
||||
<input type="submit" value="Go" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<script>$('#searchbox').show(0);</script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
©2021, Rhet Turnbull.
|
||||
|
||||
|
|
||||
Powered by <a href="http://sphinx-doc.org/">Sphinx 4.4.0</a>
|
||||
& <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,133 +0,0 @@
|
||||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>osxphotos.exifinfo — osxphotos 0.47.9 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="../../_static/alabaster.css" />
|
||||
<script data-url_root="../../" id="documentation_options" src="../../_static/documentation_options.js"></script>
|
||||
<script src="../../_static/jquery.js"></script>
|
||||
<script src="../../_static/underscore.js"></script>
|
||||
<script src="../../_static/doctools.js"></script>
|
||||
<link rel="index" title="Index" href="../../genindex.html" />
|
||||
<link rel="search" title="Search" href="../../search.html" />
|
||||
|
||||
<link rel="stylesheet" href="../../_static/custom.css" type="text/css" />
|
||||
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
|
||||
|
||||
</head><body>
|
||||
|
||||
|
||||
<div class="document">
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
|
||||
|
||||
<div class="body" role="main">
|
||||
|
||||
<h1>Source code for osxphotos.exifinfo</h1><div class="highlight"><pre>
|
||||
<span></span><span class="sd">""" ExifInfo class to expose EXIF info from the library """</span>
|
||||
|
||||
<span class="kn">from</span> <span class="nn">dataclasses</span> <span class="kn">import</span> <span class="n">dataclass</span>
|
||||
|
||||
<span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"ExifInfo"</span><span class="p">]</span>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="ExifInfo"><a class="viewcode-back" href="../../reference.html#osxphotos.ExifInfo">[docs]</a><span class="nd">@dataclass</span><span class="p">(</span><span class="n">frozen</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
|
||||
<span class="k">class</span> <span class="nc">ExifInfo</span><span class="p">:</span>
|
||||
<span class="sd">"""EXIF info associated with a photo from the Photos library"""</span>
|
||||
|
||||
<span class="n">flash_fired</span><span class="p">:</span> <span class="nb">bool</span>
|
||||
<span class="n">iso</span><span class="p">:</span> <span class="nb">int</span>
|
||||
<span class="n">metering_mode</span><span class="p">:</span> <span class="nb">int</span>
|
||||
<span class="n">sample_rate</span><span class="p">:</span> <span class="nb">int</span>
|
||||
<span class="n">track_format</span><span class="p">:</span> <span class="nb">int</span>
|
||||
<span class="n">white_balance</span><span class="p">:</span> <span class="nb">int</span>
|
||||
<span class="n">aperture</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">bit_rate</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">duration</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">exposure_bias</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">focal_length</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">fps</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">latitude</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">longitude</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">shutter_speed</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">camera_make</span><span class="p">:</span> <span class="nb">str</span>
|
||||
<span class="n">camera_model</span><span class="p">:</span> <span class="nb">str</span>
|
||||
<span class="n">codec</span><span class="p">:</span> <span class="nb">str</span>
|
||||
<span class="n">lens_model</span><span class="p">:</span> <span class="nb">str</span></div>
|
||||
</pre></div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||||
<div class="sphinxsidebarwrapper">
|
||||
<h1 class="logo"><a href="../../index.html">osxphotos</a></h1>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../overview.html">osxphotos</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../tutorial.html">Tutorial</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../cli.html">osxphotos command line interface (CLI)</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../reference.html">osxphotos package</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="relations">
|
||||
<h3>Related Topics</h3>
|
||||
<ul>
|
||||
<li><a href="../../index.html">Documentation overview</a><ul>
|
||||
<li><a href="../index.html">Module code</a><ul>
|
||||
</ul></li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="searchbox" style="display: none" role="search">
|
||||
<h3 id="searchlabel">Quick search</h3>
|
||||
<div class="searchformwrapper">
|
||||
<form class="search" action="../../search.html" method="get">
|
||||
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
|
||||
<input type="submit" value="Go" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<script>$('#searchbox').show(0);</script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
©2021, Rhet Turnbull.
|
||||
|
||||
|
|
||||
Powered by <a href="http://sphinx-doc.org/">Sphinx 4.4.0</a>
|
||||
& <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,616 +0,0 @@
|
||||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>osxphotos.exiftool — osxphotos 0.47.9 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="../../_static/alabaster.css" />
|
||||
<script data-url_root="../../" id="documentation_options" src="../../_static/documentation_options.js"></script>
|
||||
<script src="../../_static/jquery.js"></script>
|
||||
<script src="../../_static/underscore.js"></script>
|
||||
<script src="../../_static/doctools.js"></script>
|
||||
<link rel="index" title="Index" href="../../genindex.html" />
|
||||
<link rel="search" title="Search" href="../../search.html" />
|
||||
|
||||
<link rel="stylesheet" href="../../_static/custom.css" type="text/css" />
|
||||
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
|
||||
|
||||
</head><body>
|
||||
|
||||
|
||||
<div class="document">
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
|
||||
|
||||
<div class="body" role="main">
|
||||
|
||||
<h1>Source code for osxphotos.exiftool</h1><div class="highlight"><pre>
|
||||
<span></span><span class="sd">""" Yet another simple exiftool wrapper </span>
|
||||
<span class="sd"> I rolled my own for following reasons: </span>
|
||||
<span class="sd"> 1. I wanted something under MIT license (best alternative was licensed under GPL/BSD)</span>
|
||||
<span class="sd"> 2. I wanted singleton behavior so only a single exiftool process was ever running</span>
|
||||
<span class="sd"> 3. When used as a context manager, I wanted the operations to batch until exiting the context (improved performance)</span>
|
||||
<span class="sd"> If these aren't important to you, I highly recommend you use Sven Marnach's excellent </span>
|
||||
<span class="sd"> pyexiftool: https://github.com/smarnach/pyexiftool which provides more functionality """</span>
|
||||
|
||||
<span class="kn">import</span> <span class="nn">atexit</span>
|
||||
<span class="kn">import</span> <span class="nn">html</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">shutil</span>
|
||||
<span class="kn">import</span> <span class="nn">subprocess</span>
|
||||
<span class="kn">from</span> <span class="nn">abc</span> <span class="kn">import</span> <span class="n">ABC</span><span class="p">,</span> <span class="n">abstractmethod</span>
|
||||
<span class="kn">from</span> <span class="nn">functools</span> <span class="kn">import</span> <span class="n">lru_cache</span> <span class="c1"># pylint: disable=syntax-error</span>
|
||||
|
||||
<span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span>
|
||||
<span class="s2">"escape_str"</span><span class="p">,</span>
|
||||
<span class="s2">"exiftool_can_write"</span><span class="p">,</span>
|
||||
<span class="s2">"ExifTool"</span><span class="p">,</span>
|
||||
<span class="s2">"ExifToolCaching"</span><span class="p">,</span>
|
||||
<span class="s2">"get_exiftool_path"</span><span class="p">,</span>
|
||||
<span class="s2">"terminate_exiftool"</span><span class="p">,</span>
|
||||
<span class="s2">"unescape_str"</span><span class="p">,</span>
|
||||
<span class="p">]</span>
|
||||
|
||||
<span class="c1"># exiftool -stay_open commands outputs this EOF marker after command is run</span>
|
||||
<span class="n">EXIFTOOL_STAYOPEN_EOF</span> <span class="o">=</span> <span class="s2">"</span><span class="si">{ready}</span><span class="s2">"</span>
|
||||
<span class="n">EXIFTOOL_STAYOPEN_EOF_LEN</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">EXIFTOOL_STAYOPEN_EOF</span><span class="p">)</span>
|
||||
|
||||
<span class="c1"># list of exiftool processes to cleanup when exiting or when terminate is called</span>
|
||||
<span class="n">EXIFTOOL_PROCESSES</span> <span class="o">=</span> <span class="p">[]</span>
|
||||
|
||||
<span class="c1"># exiftool supported file types, created by utils/exiftool_supported_types.py</span>
|
||||
<span class="n">EXIFTOOL_FILETYPES_JSON</span> <span class="o">=</span> <span class="s2">"exiftool_filetypes.json"</span>
|
||||
<span class="k">with</span> <span class="p">(</span><span class="n">pathlib</span><span class="o">.</span><span class="n">Path</span><span class="p">(</span><span class="vm">__file__</span><span class="p">)</span><span class="o">.</span><span class="n">parent</span> <span class="o">/</span> <span class="n">EXIFTOOL_FILETYPES_JSON</span><span class="p">)</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="s2">"r"</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
|
||||
<span class="n">EXIFTOOL_SUPPORTED_FILETYPES</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">load</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
|
||||
|
||||
|
||||
<span class="k">def</span> <span class="nf">exiftool_can_write</span><span class="p">(</span><span class="n">suffix</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-></span> <span class="nb">bool</span><span class="p">:</span>
|
||||
<span class="sd">"""Return True if exiftool supports writing to a file with the given suffix, otherwise False"""</span>
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="n">suffix</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="kc">False</span>
|
||||
<span class="n">suffix</span> <span class="o">=</span> <span class="n">suffix</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
|
||||
<span class="k">if</span> <span class="n">suffix</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="s2">"."</span><span class="p">:</span>
|
||||
<span class="n">suffix</span> <span class="o">=</span> <span class="n">suffix</span><span class="p">[</span><span class="mi">1</span><span class="p">:]</span>
|
||||
<span class="k">return</span> <span class="p">(</span>
|
||||
<span class="n">suffix</span> <span class="ow">in</span> <span class="n">EXIFTOOL_SUPPORTED_FILETYPES</span>
|
||||
<span class="ow">and</span> <span class="n">EXIFTOOL_SUPPORTED_FILETYPES</span><span class="p">[</span><span class="n">suffix</span><span class="p">][</span><span class="s2">"write"</span><span class="p">]</span>
|
||||
<span class="p">)</span>
|
||||
|
||||
|
||||
<span class="k">def</span> <span class="nf">escape_str</span><span class="p">(</span><span class="n">s</span><span class="p">):</span>
|
||||
<span class="sd">"""escape string for use with exiftool -E"""</span>
|
||||
<span class="k">if</span> <span class="nb">type</span><span class="p">(</span><span class="n">s</span><span class="p">)</span> <span class="o">!=</span> <span class="nb">str</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="n">s</span>
|
||||
<span class="n">s</span> <span class="o">=</span> <span class="n">html</span><span class="o">.</span><span class="n">escape</span><span class="p">(</span><span class="n">s</span><span class="p">)</span>
|
||||
<span class="n">s</span> <span class="o">=</span> <span class="n">s</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s2">"</span><span class="se">\n</span><span class="s2">"</span><span class="p">,</span> <span class="s2">"&#xa;"</span><span class="p">)</span>
|
||||
<span class="n">s</span> <span class="o">=</span> <span class="n">s</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s2">"</span><span class="se">\t</span><span class="s2">"</span><span class="p">,</span> <span class="s2">"&#x9;"</span><span class="p">)</span>
|
||||
<span class="n">s</span> <span class="o">=</span> <span class="n">s</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s2">"</span><span class="se">\r</span><span class="s2">"</span><span class="p">,</span> <span class="s2">"&#xd;"</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="n">s</span>
|
||||
|
||||
|
||||
<span class="k">def</span> <span class="nf">unescape_str</span><span class="p">(</span><span class="n">s</span><span class="p">):</span>
|
||||
<span class="sd">"""unescape an HTML string returned by exiftool -E"""</span>
|
||||
<span class="k">if</span> <span class="nb">type</span><span class="p">(</span><span class="n">s</span><span class="p">)</span> <span class="o">!=</span> <span class="nb">str</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="n">s</span>
|
||||
<span class="c1"># avoid " in values which result in json.loads() throwing an exception, #636</span>
|
||||
<span class="n">s</span> <span class="o">=</span> <span class="n">s</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s2">"&quot;"</span><span class="p">,</span> <span class="s1">'</span><span class="se">\\</span><span class="s1">"'</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="n">html</span><span class="o">.</span><span class="n">unescape</span><span class="p">(</span><span class="n">s</span><span class="p">)</span>
|
||||
|
||||
|
||||
<span class="nd">@atexit</span><span class="o">.</span><span class="n">register</span>
|
||||
<span class="k">def</span> <span class="nf">terminate_exiftool</span><span class="p">():</span>
|
||||
<span class="sd">"""Terminate any running ExifTool subprocesses; call this to cleanup when done using ExifTool"""</span>
|
||||
<span class="k">for</span> <span class="n">proc</span> <span class="ow">in</span> <span class="n">EXIFTOOL_PROCESSES</span><span class="p">:</span>
|
||||
<span class="n">proc</span><span class="o">.</span><span class="n">_stop_proc</span><span class="p">()</span>
|
||||
|
||||
|
||||
<span class="nd">@lru_cache</span><span class="p">(</span><span class="n">maxsize</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
|
||||
<span class="k">def</span> <span class="nf">get_exiftool_path</span><span class="p">():</span>
|
||||
<span class="sd">"""return path of exiftool, cache result"""</span>
|
||||
<span class="n">exiftool_path</span> <span class="o">=</span> <span class="n">shutil</span><span class="o">.</span><span class="n">which</span><span class="p">(</span><span class="s2">"exiftool"</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="n">exiftool_path</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="n">exiftool_path</span><span class="o">.</span><span class="n">rstrip</span><span class="p">()</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="k">raise</span> <span class="ne">FileNotFoundError</span><span class="p">(</span>
|
||||
<span class="s2">"Could not find exiftool. Please download and install from "</span>
|
||||
<span class="s2">"https://exiftool.org/"</span>
|
||||
<span class="p">)</span>
|
||||
|
||||
|
||||
<span class="k">class</span> <span class="nc">_ExifToolProc</span><span class="p">:</span>
|
||||
<span class="sd">"""Runs exiftool in a subprocess via Popen</span>
|
||||
<span class="sd"> Creates a singleton object"""</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__new__</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
|
||||
<span class="sd">"""create new object or return instance of already created singleton"""</span>
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="nb">hasattr</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="s2">"instance"</span><span class="p">)</span> <span class="ow">or</span> <span class="ow">not</span> <span class="bp">cls</span><span class="o">.</span><span class="n">instance</span><span class="p">:</span>
|
||||
<span class="bp">cls</span><span class="o">.</span><span class="n">instance</span> <span class="o">=</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__new__</span><span class="p">(</span><span class="bp">cls</span><span class="p">)</span>
|
||||
|
||||
<span class="k">return</span> <span class="bp">cls</span><span class="o">.</span><span class="n">instance</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">exiftool</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
||||
<span class="sd">"""construct _ExifToolProc singleton object or return instance of already created object</span>
|
||||
<span class="sd"> exiftool: optional path to exiftool binary (if not provided, will search path to find it)</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s2">"_process_running"</span><span class="p">)</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">_process_running</span><span class="p">:</span>
|
||||
<span class="c1"># already running</span>
|
||||
<span class="k">if</span> <span class="n">exiftool</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">exiftool</span> <span class="o">!=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_exiftool</span><span class="p">:</span>
|
||||
<span class="n">logging</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span>
|
||||
<span class="sa">f</span><span class="s2">"exiftool subprocess already running, "</span>
|
||||
<span class="sa">f</span><span class="s2">"ignoring exiftool=</span><span class="si">{</span><span class="n">exiftool</span><span class="si">}</span><span class="s2">"</span>
|
||||
<span class="p">)</span>
|
||||
<span class="k">return</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_process_running</span> <span class="o">=</span> <span class="kc">False</span>
|
||||
<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="ow">or</span> <span class="n">get_exiftool_path</span><span class="p">()</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_start_proc</span><span class="p">()</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">process</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""return the exiftool subprocess"""</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_process_running</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_process</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_start_proc</span><span class="p">()</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_process</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">pid</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""return process id (PID) of the exiftool process"""</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_process</span><span class="o">.</span><span class="n">pid</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">exiftool</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""return path to exiftool process"""</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_exiftool</span>
|
||||
|
||||
<span class="k">def</span> <span class="nf">_start_proc</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""start exiftool in batch mode"""</span>
|
||||
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_process_running</span><span class="p">:</span>
|
||||
<span class="n">logging</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="s2">"exiftool already running: </span><span class="si">{self._process}</span><span class="s2">"</span><span class="p">)</span>
|
||||
<span class="k">return</span>
|
||||
|
||||
<span class="c1"># open exiftool process</span>
|
||||
<span class="c1"># make sure /usr/bin at start of path so exiftool can find xattr (see #636)</span>
|
||||
<span class="n">env</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="o">.</span><span class="n">copy</span><span class="p">()</span>
|
||||
<span class="n">env</span><span class="p">[</span><span class="s2">"PATH"</span><span class="p">]</span> <span class="o">=</span> <span class="sa">f</span><span class="s1">'/usr/bin/:</span><span class="si">{</span><span class="n">env</span><span class="p">[</span><span class="s2">"PATH"</span><span class="p">]</span><span class="si">}</span><span class="s1">'</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_process</span> <span class="o">=</span> <span class="n">subprocess</span><span class="o">.</span><span class="n">Popen</span><span class="p">(</span>
|
||||
<span class="p">[</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_exiftool</span><span class="p">,</span>
|
||||
<span class="s2">"-stay_open"</span><span class="p">,</span> <span class="c1"># keep process open in batch mode</span>
|
||||
<span class="s2">"True"</span><span class="p">,</span> <span class="c1"># -stay_open=True, keep process open in batch mode</span>
|
||||
<span class="s2">"-@"</span><span class="p">,</span> <span class="c1"># read command-line arguments from file</span>
|
||||
<span class="s2">"-"</span><span class="p">,</span> <span class="c1"># read from stdin</span>
|
||||
<span class="s2">"-common_args"</span><span class="p">,</span> <span class="c1"># specifies args common to all commands subsequently run</span>
|
||||
<span class="s2">"-n"</span><span class="p">,</span> <span class="c1"># no print conversion (e.g. print tag values in machine readable format)</span>
|
||||
<span class="s2">"-P"</span><span class="p">,</span> <span class="c1"># Preserve file modification date/time</span>
|
||||
<span class="s2">"-G"</span><span class="p">,</span> <span class="c1"># print group name for each tag</span>
|
||||
<span class="s2">"-E"</span><span class="p">,</span> <span class="c1"># escape tag values for HTML (allows use of HTML &#xa; for newlines)</span>
|
||||
<span class="p">],</span>
|
||||
<span class="n">stdin</span><span class="o">=</span><span class="n">subprocess</span><span class="o">.</span><span class="n">PIPE</span><span class="p">,</span>
|
||||
<span class="n">stdout</span><span class="o">=</span><span class="n">subprocess</span><span class="o">.</span><span class="n">PIPE</span><span class="p">,</span>
|
||||
<span class="n">stderr</span><span class="o">=</span><span class="n">subprocess</span><span class="o">.</span><span class="n">STDOUT</span><span class="p">,</span>
|
||||
<span class="n">env</span><span class="o">=</span><span class="n">env</span><span class="p">,</span>
|
||||
<span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_process_running</span> <span class="o">=</span> <span class="kc">True</span>
|
||||
|
||||
<span class="n">EXIFTOOL_PROCESSES</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
|
||||
|
||||
<span class="k">def</span> <span class="nf">_stop_proc</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""stop the exiftool process if it's running, otherwise, do nothing"""</span>
|
||||
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_process_running</span><span class="p">:</span>
|
||||
<span class="k">return</span>
|
||||
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_process</span><span class="o">.</span><span class="n">stdin</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="sa">b</span><span class="s2">"-stay_open</span><span class="se">\n</span><span class="s2">"</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_process</span><span class="o">.</span><span class="n">stdin</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="sa">b</span><span class="s2">"False</span><span class="se">\n</span><span class="s2">"</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_process</span><span class="o">.</span><span class="n">stdin</span><span class="o">.</span><span class="n">flush</span><span class="p">()</span>
|
||||
<span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
|
||||
<span class="k">pass</span>
|
||||
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_process</span><span class="o">.</span><span class="n">communicate</span><span class="p">(</span><span class="n">timeout</span><span class="o">=</span><span class="mi">5</span><span class="p">)</span>
|
||||
<span class="k">except</span> <span class="n">subprocess</span><span class="o">.</span><span class="n">TimeoutExpired</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_process</span><span class="o">.</span><span class="n">kill</span><span class="p">()</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_process</span><span class="o">.</span><span class="n">communicate</span><span class="p">()</span>
|
||||
|
||||
<span class="k">del</span> <span class="bp">self</span><span class="o">.</span><span class="n">_process</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_process_running</span> <span class="o">=</span> <span class="kc">False</span>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="ExifTool"><a class="viewcode-back" href="../../reference.html#osxphotos.ExifTool">[docs]</a><span class="k">class</span> <span class="nc">ExifTool</span><span class="p">:</span>
|
||||
<span class="sd">"""Basic exiftool interface for reading and writing EXIF tags"""</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">filepath</span><span class="p">,</span> <span class="n">exiftool</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">overwrite</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">flags</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
||||
<span class="sd">"""Create ExifTool object</span>
|
||||
|
||||
<span class="sd"> Args:</span>
|
||||
<span class="sd"> file: path to image file</span>
|
||||
<span class="sd"> exiftool: path to exiftool, if not specified will look in path</span>
|
||||
<span class="sd"> overwrite: if True, will overwrite image file without creating backup, default=False</span>
|
||||
<span class="sd"> flags: optional list of exiftool flags to prepend to exiftool command when writing metadata (e.g. -m or -F)</span>
|
||||
|
||||
<span class="sd"> Returns:</span>
|
||||
<span class="sd"> ExifTool instance</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">file</span> <span class="o">=</span> <span class="n">filepath</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">overwrite</span> <span class="o">=</span> <span class="n">overwrite</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">flags</span> <span class="o">=</span> <span class="n">flags</span> <span class="ow">or</span> <span class="p">[]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="p">{}</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">warning</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">error</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="c1"># if running as a context manager, self._context_mgr will be True</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_context_mgr</span> <span class="o">=</span> <span class="kc">False</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_exiftoolproc</span> <span class="o">=</span> <span class="n">_ExifToolProc</span><span class="p">(</span><span class="n">exiftool</span><span class="o">=</span><span class="n">exiftool</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_read_exif</span><span class="p">()</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">_process</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_exiftoolproc</span><span class="o">.</span><span class="n">process</span>
|
||||
|
||||
<div class="viewcode-block" id="ExifTool.setvalue"><a class="viewcode-back" href="../../reference.html#osxphotos.ExifTool.setvalue">[docs]</a> <span class="k">def</span> <span class="nf">setvalue</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">tag</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
|
||||
<span class="sd">"""Set tag to value(s); if value is None, will delete tag</span>
|
||||
|
||||
<span class="sd"> Args:</span>
|
||||
<span class="sd"> tag: str; name of tag to set</span>
|
||||
<span class="sd"> value: str; value to set tag to</span>
|
||||
|
||||
<span class="sd"> Returns:</span>
|
||||
<span class="sd"> True if success otherwise False</span>
|
||||
|
||||
<span class="sd"> If error generated by exiftool, returns False and sets self.error to error string</span>
|
||||
<span class="sd"> If warning generated by exiftool, returns True (unless there was also an error) and sets self.warning to warning string</span>
|
||||
<span class="sd"> If called in context manager, returns True (execution is delayed until exiting context manager)</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="k">if</span> <span class="n">value</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
||||
<span class="n">value</span> <span class="o">=</span> <span class="s2">""</span>
|
||||
<span class="n">value</span> <span class="o">=</span> <span class="n">escape_str</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
|
||||
<span class="n">command</span> <span class="o">=</span> <span class="p">[</span><span class="sa">f</span><span class="s2">"-</span><span class="si">{</span><span class="n">tag</span><span class="si">}</span><span class="s2">=</span><span class="si">{</span><span class="n">value</span><span class="si">}</span><span class="s2">"</span><span class="p">]</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">overwrite</span> <span class="ow">and</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_context_mgr</span><span class="p">:</span>
|
||||
<span class="n">command</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">"-overwrite_original"</span><span class="p">)</span>
|
||||
|
||||
<span class="c1"># avoid "Warning: Some character(s) could not be encoded in Latin" warning</span>
|
||||
<span class="n">command</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">"-iptc:codedcharacterset=utf8"</span><span class="p">)</span>
|
||||
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_context_mgr</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_commands</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">command</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="kc">True</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="n">_</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">error</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">run_commands</span><span class="p">(</span><span class="o">*</span><span class="n">command</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="n">error</span> <span class="o">==</span> <span class="s2">""</span></div>
|
||||
|
||||
<div class="viewcode-block" id="ExifTool.addvalues"><a class="viewcode-back" href="../../reference.html#osxphotos.ExifTool.addvalues">[docs]</a> <span class="k">def</span> <span class="nf">addvalues</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">tag</span><span class="p">,</span> <span class="o">*</span><span class="n">values</span><span class="p">):</span>
|
||||
<span class="sd">"""Add one or more value(s) to tag</span>
|
||||
<span class="sd"> If more than one value is passed, each value will be added to the tag</span>
|
||||
|
||||
<span class="sd"> Args:</span>
|
||||
<span class="sd"> tag: str; tag to set</span>
|
||||
<span class="sd"> *values: str; one or more values to set</span>
|
||||
|
||||
<span class="sd"> Returns:</span>
|
||||
<span class="sd"> True if success otherwise False</span>
|
||||
|
||||
<span class="sd"> If error generated by exiftool, returns False and sets self.error to error string</span>
|
||||
<span class="sd"> If warning generated by exiftool, returns True (unless there was also an error) and sets self.warning to warning string</span>
|
||||
<span class="sd"> If called in context manager, returns True (execution is delayed until exiting context manager)</span>
|
||||
|
||||
<span class="sd"> Notes: exiftool may add duplicate values for some tags so the caller must ensure</span>
|
||||
<span class="sd"> the values being added are not already in the EXIF data</span>
|
||||
<span class="sd"> For some tags, such as IPTC:Keywords, this will add a new value to the list of keywords,</span>
|
||||
<span class="sd"> but for others, such as EXIF:ISO, this will literally add a value to the existing value.</span>
|
||||
<span class="sd"> It's up to the caller to know what exiftool will do for each tag</span>
|
||||
<span class="sd"> If setvalue called before addvalues, exiftool does not appear to add duplicates,</span>
|
||||
<span class="sd"> but if addvalues called without first calling setvalue, exiftool will add duplicate values</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="n">values</span><span class="p">:</span>
|
||||
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">"Must pass at least one value"</span><span class="p">)</span>
|
||||
|
||||
<span class="n">command</span> <span class="o">=</span> <span class="p">[]</span>
|
||||
<span class="k">for</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">values</span><span class="p">:</span>
|
||||
<span class="k">if</span> <span class="n">value</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
||||
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">"Can't add None value to tag"</span><span class="p">)</span>
|
||||
<span class="n">value</span> <span class="o">=</span> <span class="n">escape_str</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
|
||||
<span class="n">command</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="sa">f</span><span class="s2">"-</span><span class="si">{</span><span class="n">tag</span><span class="si">}</span><span class="s2">+=</span><span class="si">{</span><span class="n">value</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
|
||||
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">overwrite</span> <span class="ow">and</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_context_mgr</span><span class="p">:</span>
|
||||
<span class="n">command</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">"-overwrite_original"</span><span class="p">)</span>
|
||||
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_context_mgr</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_commands</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">command</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="kc">True</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="n">_</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">error</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">run_commands</span><span class="p">(</span><span class="o">*</span><span class="n">command</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="n">error</span> <span class="o">==</span> <span class="s2">""</span></div>
|
||||
|
||||
<div class="viewcode-block" id="ExifTool.run_commands"><a class="viewcode-back" href="../../reference.html#osxphotos.ExifTool.run_commands">[docs]</a> <span class="k">def</span> <span class="nf">run_commands</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">commands</span><span class="p">,</span> <span class="n">no_file</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
|
||||
<span class="sd">"""Run commands in the exiftool process and return result.</span>
|
||||
|
||||
<span class="sd"> Args:</span>
|
||||
<span class="sd"> *commands: exiftool commands to run</span>
|
||||
<span class="sd"> no_file: (bool) do not pass the filename to exiftool (default=False)</span>
|
||||
<span class="sd"> by default, all commands will be run against self.file</span>
|
||||
<span class="sd"> use no_file=True to run a command without passing the filename</span>
|
||||
<span class="sd"> Returns:</span>
|
||||
<span class="sd"> (output, warning, errror)</span>
|
||||
<span class="sd"> output: bytes is containing output of exiftool commands</span>
|
||||
<span class="sd"> warning: if exiftool generated warnings, string containing warning otherwise empty string</span>
|
||||
<span class="sd"> error: if exiftool generated errors, string containing otherwise empty string</span>
|
||||
|
||||
<span class="sd"> Note: Also sets self.warning and self.error if warning or error generated.</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="p">(</span><span class="nb">hasattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s2">"_process"</span><span class="p">)</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">_process</span><span class="p">):</span>
|
||||
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">"exiftool process is not running"</span><span class="p">)</span>
|
||||
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="n">commands</span><span class="p">:</span>
|
||||
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s2">"must provide one or more command to run"</span><span class="p">)</span>
|
||||
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_context_mgr</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">overwrite</span><span class="p">:</span>
|
||||
<span class="n">commands</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">commands</span><span class="p">)</span>
|
||||
<span class="n">commands</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">"-overwrite_original"</span><span class="p">)</span>
|
||||
|
||||
<span class="n">filename</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">fsencode</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">file</span><span class="p">)</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">no_file</span> <span class="k">else</span> <span class="sa">b</span><span class="s2">""</span>
|
||||
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">flags</span><span class="p">:</span>
|
||||
<span class="c1"># need to split flags, e.g. so "--ext AVI" becomes ["--ext", "AVI"]</span>
|
||||
<span class="n">flags</span> <span class="o">=</span> <span class="p">[]</span>
|
||||
<span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">flags</span><span class="p">:</span>
|
||||
<span class="n">flags</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">f</span><span class="o">.</span><span class="n">split</span><span class="p">())</span>
|
||||
<span class="n">command_str</span> <span class="o">=</span> <span class="sa">b</span><span class="s2">"</span><span class="se">\n</span><span class="s2">"</span><span class="o">.</span><span class="n">join</span><span class="p">([</span><span class="n">f</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s2">"utf-8"</span><span class="p">)</span> <span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">flags</span><span class="p">])</span>
|
||||
<span class="n">command_str</span> <span class="o">+=</span> <span class="sa">b</span><span class="s2">"</span><span class="se">\n</span><span class="s2">"</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="n">command_str</span> <span class="o">=</span> <span class="sa">b</span><span class="s2">""</span>
|
||||
|
||||
<span class="n">command_str</span> <span class="o">+=</span> <span class="p">(</span>
|
||||
<span class="sa">b</span><span class="s2">"</span><span class="se">\n</span><span class="s2">"</span><span class="o">.</span><span class="n">join</span><span class="p">([</span><span class="n">c</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s2">"utf-8"</span><span class="p">)</span> <span class="k">for</span> <span class="n">c</span> <span class="ow">in</span> <span class="n">commands</span><span class="p">])</span>
|
||||
<span class="o">+</span> <span class="sa">b</span><span class="s2">"</span><span class="se">\n</span><span class="s2">"</span>
|
||||
<span class="o">+</span> <span class="n">filename</span>
|
||||
<span class="o">+</span> <span class="sa">b</span><span class="s2">"</span><span class="se">\n</span><span class="s2">"</span>
|
||||
<span class="o">+</span> <span class="sa">b</span><span class="s2">"-execute</span><span class="se">\n</span><span class="s2">"</span>
|
||||
<span class="p">)</span>
|
||||
|
||||
<span class="c1"># send the command</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_process</span><span class="o">.</span><span class="n">stdin</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">command_str</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_process</span><span class="o">.</span><span class="n">stdin</span><span class="o">.</span><span class="n">flush</span><span class="p">()</span>
|
||||
|
||||
<span class="c1"># read the output</span>
|
||||
<span class="n">output</span> <span class="o">=</span> <span class="sa">b</span><span class="s2">""</span>
|
||||
<span class="n">warning</span> <span class="o">=</span> <span class="sa">b</span><span class="s2">""</span>
|
||||
<span class="n">error</span> <span class="o">=</span> <span class="sa">b</span><span class="s2">""</span>
|
||||
<span class="k">while</span> <span class="n">EXIFTOOL_STAYOPEN_EOF</span> <span class="ow">not</span> <span class="ow">in</span> <span class="nb">str</span><span class="p">(</span><span class="n">output</span><span class="p">):</span>
|
||||
<span class="n">line</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_process</span><span class="o">.</span><span class="n">stdout</span><span class="o">.</span><span class="n">readline</span><span class="p">()</span>
|
||||
<span class="k">if</span> <span class="n">line</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="sa">b</span><span class="s2">"Warning"</span><span class="p">):</span>
|
||||
<span class="n">warning</span> <span class="o">+=</span> <span class="n">line</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
|
||||
<span class="k">elif</span> <span class="n">line</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="sa">b</span><span class="s2">"Error"</span><span class="p">):</span>
|
||||
<span class="n">error</span> <span class="o">+=</span> <span class="n">line</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="n">output</span> <span class="o">+=</span> <span class="n">line</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
|
||||
<span class="n">warning</span> <span class="o">=</span> <span class="s2">""</span> <span class="k">if</span> <span class="n">warning</span> <span class="o">==</span> <span class="sa">b</span><span class="s2">""</span> <span class="k">else</span> <span class="n">warning</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s2">"utf-8"</span><span class="p">)</span>
|
||||
<span class="n">error</span> <span class="o">=</span> <span class="s2">""</span> <span class="k">if</span> <span class="n">error</span> <span class="o">==</span> <span class="sa">b</span><span class="s2">""</span> <span class="k">else</span> <span class="n">error</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s2">"utf-8"</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">warning</span> <span class="o">=</span> <span class="n">warning</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">error</span> <span class="o">=</span> <span class="n">error</span>
|
||||
|
||||
<span class="k">return</span> <span class="n">output</span><span class="p">[:</span><span class="o">-</span><span class="n">EXIFTOOL_STAYOPEN_EOF_LEN</span><span class="p">],</span> <span class="n">warning</span><span class="p">,</span> <span class="n">error</span></div>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">pid</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""return process id (PID) of the exiftool process"""</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_process</span><span class="o">.</span><span class="n">pid</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">version</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""returns exiftool version"""</span>
|
||||
<span class="n">ver</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">run_commands</span><span class="p">(</span><span class="s2">"-ver"</span><span class="p">,</span> <span class="n">no_file</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="n">ver</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s2">"utf-8"</span><span class="p">)</span>
|
||||
|
||||
<div class="viewcode-block" id="ExifTool.asdict"><a class="viewcode-back" href="../../reference.html#osxphotos.ExifTool.asdict">[docs]</a> <span class="k">def</span> <span class="nf">asdict</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">tag_groups</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">normalized</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
|
||||
<span class="sd">"""return dictionary of all EXIF tags and values from exiftool</span>
|
||||
<span class="sd"> returns empty dict if no tags</span>
|
||||
|
||||
<span class="sd"> Args:</span>
|
||||
<span class="sd"> tag_groups: if True (default), dict keys have tag groups, e.g. "IPTC:Keywords"; if False, drops groups from keys, e.g. "Keywords"</span>
|
||||
<span class="sd"> normalized: if True, dict keys are all normalized to lower case (default is False)</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="n">json_str</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">run_commands</span><span class="p">(</span><span class="s2">"-json"</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="n">json_str</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="nb">dict</span><span class="p">()</span>
|
||||
<span class="n">json_str</span> <span class="o">=</span> <span class="n">unescape_str</span><span class="p">(</span><span class="n">json_str</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s2">"utf-8"</span><span class="p">))</span>
|
||||
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="n">exifdict</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">json_str</span><span class="p">)</span>
|
||||
<span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
|
||||
<span class="c1"># will fail with some commands, e.g --ext AVI which produces</span>
|
||||
<span class="c1"># 'No file with specified extension' instead of json</span>
|
||||
<span class="n">logging</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="sa">f</span><span class="s2">"error loading json returned by exiftool: </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s2"> </span><span class="si">{</span><span class="n">json_str</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="nb">dict</span><span class="p">()</span>
|
||||
<span class="n">exifdict</span> <span class="o">=</span> <span class="n">exifdict</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="n">tag_groups</span><span class="p">:</span>
|
||||
<span class="c1"># strip tag groups</span>
|
||||
<span class="n">exif_new</span> <span class="o">=</span> <span class="p">{}</span>
|
||||
<span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">exifdict</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
|
||||
<span class="n">k</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">sub</span><span class="p">(</span><span class="sa">r</span><span class="s2">".*:"</span><span class="p">,</span> <span class="s2">""</span><span class="p">,</span> <span class="n">k</span><span class="p">)</span>
|
||||
<span class="n">exif_new</span><span class="p">[</span><span class="n">k</span><span class="p">]</span> <span class="o">=</span> <span class="n">v</span>
|
||||
<span class="n">exifdict</span> <span class="o">=</span> <span class="n">exif_new</span>
|
||||
|
||||
<span class="k">if</span> <span class="n">normalized</span><span class="p">:</span>
|
||||
<span class="n">exifdict</span> <span class="o">=</span> <span class="p">{</span><span class="n">k</span><span class="o">.</span><span class="n">lower</span><span class="p">():</span> <span class="n">v</span> <span class="k">for</span> <span class="p">(</span><span class="n">k</span><span class="p">,</span> <span class="n">v</span><span class="p">)</span> <span class="ow">in</span> <span class="n">exifdict</span><span class="o">.</span><span class="n">items</span><span class="p">()}</span>
|
||||
|
||||
<span class="k">return</span> <span class="n">exifdict</span></div>
|
||||
|
||||
<div class="viewcode-block" id="ExifTool.json"><a class="viewcode-back" href="../../reference.html#osxphotos.ExifTool.json">[docs]</a> <span class="k">def</span> <span class="nf">json</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""returns JSON string containing all EXIF tags and values from exiftool"""</span>
|
||||
<span class="n">json</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">run_commands</span><span class="p">(</span><span class="s2">"-json"</span><span class="p">)</span>
|
||||
<span class="n">json</span> <span class="o">=</span> <span class="n">unescape_str</span><span class="p">(</span><span class="n">json</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s2">"utf-8"</span><span class="p">))</span>
|
||||
<span class="k">return</span> <span class="n">json</span></div>
|
||||
|
||||
<span class="k">def</span> <span class="nf">_read_exif</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""read exif data from file"""</span>
|
||||
<span class="n">data</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">asdict</span><span class="p">()</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="p">{</span><span class="n">k</span><span class="p">:</span> <span class="n">v</span> <span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">data</span><span class="o">.</span><span class="n">items</span><span class="p">()}</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="sa">f</span><span class="s2">"file: </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">file</span><span class="si">}</span><span class="se">\n</span><span class="s2">exiftool: </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">_exiftoolproc</span><span class="o">.</span><span class="n">_exiftool</span><span class="si">}</span><span class="s2">"</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__enter__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_context_mgr</span> <span class="o">=</span> <span class="kc">True</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_commands</span> <span class="o">=</span> <span class="p">[]</span>
|
||||
<span class="k">return</span> <span class="bp">self</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__exit__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">exc_type</span><span class="p">,</span> <span class="n">exc_value</span><span class="p">,</span> <span class="n">traceback</span><span class="p">):</span>
|
||||
<span class="k">if</span> <span class="n">exc_type</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="kc">False</span>
|
||||
<span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">_commands</span><span class="p">:</span>
|
||||
<span class="c1"># run_commands sets self.warning and self.error as needed</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">run_commands</span><span class="p">(</span><span class="o">*</span><span class="bp">self</span><span class="o">.</span><span class="n">_commands</span><span class="p">)</span></div>
|
||||
|
||||
|
||||
<span class="k">class</span> <span class="nc">ExifToolCaching</span><span class="p">(</span><span class="n">ExifTool</span><span class="p">):</span>
|
||||
<span class="sd">"""Basic exiftool interface for reading and writing EXIF tags, with caching.</span>
|
||||
<span class="sd"> Use this only when you know the file's EXIF data will not be changed by any external process.</span>
|
||||
|
||||
<span class="sd"> Creates a singleton cached ExifTool instance"""</span>
|
||||
|
||||
<span class="n">_singletons</span> <span class="o">=</span> <span class="p">{}</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__new__</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">filepath</span><span class="p">,</span> <span class="n">exiftool</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
||||
<span class="sd">"""create new object or return instance of already created singleton"""</span>
|
||||
<span class="k">if</span> <span class="n">filepath</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_singletons</span><span class="p">:</span>
|
||||
<span class="bp">cls</span><span class="o">.</span><span class="n">_singletons</span><span class="p">[</span><span class="n">filepath</span><span class="p">]</span> <span class="o">=</span> <span class="n">_ExifToolCaching</span><span class="p">(</span><span class="n">filepath</span><span class="p">,</span> <span class="n">exiftool</span><span class="o">=</span><span class="n">exiftool</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_singletons</span><span class="p">[</span><span class="n">filepath</span><span class="p">]</span>
|
||||
|
||||
|
||||
<span class="k">class</span> <span class="nc">_ExifToolCaching</span><span class="p">(</span><span class="n">ExifTool</span><span class="p">):</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">filepath</span><span class="p">,</span> <span class="n">exiftool</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
||||
<span class="sd">"""Create read-only ExifTool object that caches values</span>
|
||||
|
||||
<span class="sd"> Args:</span>
|
||||
<span class="sd"> file: path to image file</span>
|
||||
<span class="sd"> exiftool: path to exiftool, if not specified will look in path</span>
|
||||
|
||||
<span class="sd"> Returns:</span>
|
||||
<span class="sd"> ExifTool instance</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_json_cache</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_asdict_cache</span> <span class="o">=</span> <span class="p">{}</span>
|
||||
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="n">filepath</span><span class="p">,</span> <span class="n">exiftool</span><span class="o">=</span><span class="n">exiftool</span><span class="p">,</span> <span class="n">overwrite</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">flags</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span>
|
||||
|
||||
<span class="k">def</span> <span class="nf">run_commands</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">commands</span><span class="p">,</span> <span class="n">no_file</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
|
||||
<span class="k">if</span> <span class="n">commands</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">[</span><span class="s2">"-json"</span><span class="p">,</span> <span class="s2">"-ver"</span><span class="p">]:</span>
|
||||
<span class="k">raise</span> <span class="ne">NotImplementedError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="si">}</span><span class="s2"> is read-only"</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">run_commands</span><span class="p">(</span><span class="o">*</span><span class="n">commands</span><span class="p">,</span> <span class="n">no_file</span><span class="o">=</span><span class="n">no_file</span><span class="p">)</span>
|
||||
|
||||
<span class="k">def</span> <span class="nf">setvalue</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">tag</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
|
||||
<span class="k">raise</span> <span class="ne">NotImplementedError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="si">}</span><span class="s2"> is read-only"</span><span class="p">)</span>
|
||||
|
||||
<span class="k">def</span> <span class="nf">addvalues</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">tag</span><span class="p">,</span> <span class="o">*</span><span class="n">values</span><span class="p">):</span>
|
||||
<span class="k">raise</span> <span class="ne">NotImplementedError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="si">}</span><span class="s2"> is read-only"</span><span class="p">)</span>
|
||||
|
||||
<span class="k">def</span> <span class="nf">json</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_json_cache</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_json_cache</span> <span class="o">=</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">json</span><span class="p">()</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_json_cache</span>
|
||||
|
||||
<span class="k">def</span> <span class="nf">asdict</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">tag_groups</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">normalized</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
|
||||
<span class="sd">"""return dictionary of all EXIF tags and values from exiftool</span>
|
||||
<span class="sd"> returns empty dict if no tags</span>
|
||||
|
||||
<span class="sd"> Args:</span>
|
||||
<span class="sd"> tag_groups: if True (default), dict keys have tag groups, e.g. "IPTC:Keywords"; if False, drops groups from keys, e.g. "Keywords"</span>
|
||||
<span class="sd"> normalized: if True, dict keys are all normalized to lower case (default is False)</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_asdict_cache</span><span class="p">[</span><span class="n">tag_groups</span><span class="p">][</span><span class="n">normalized</span><span class="p">]</span>
|
||||
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
|
||||
<span class="k">if</span> <span class="n">tag_groups</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_asdict_cache</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_asdict_cache</span><span class="p">[</span><span class="n">tag_groups</span><span class="p">]</span> <span class="o">=</span> <span class="p">{}</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_asdict_cache</span><span class="p">[</span><span class="n">tag_groups</span><span class="p">][</span><span class="n">normalized</span><span class="p">]</span> <span class="o">=</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">asdict</span><span class="p">(</span>
|
||||
<span class="n">tag_groups</span><span class="o">=</span><span class="n">tag_groups</span><span class="p">,</span> <span class="n">normalized</span><span class="o">=</span><span class="n">normalized</span>
|
||||
<span class="p">)</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_asdict_cache</span><span class="p">[</span><span class="n">tag_groups</span><span class="p">][</span><span class="n">normalized</span><span class="p">]</span>
|
||||
|
||||
<span class="k">def</span> <span class="nf">flush_cache</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""Clear cached data so that calls to json or asdict return fresh data"""</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_json_cache</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_asdict_cache</span> <span class="o">=</span> <span class="p">{}</span>
|
||||
</pre></div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||||
<div class="sphinxsidebarwrapper">
|
||||
<h1 class="logo"><a href="../../index.html">osxphotos</a></h1>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../overview.html">osxphotos</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../tutorial.html">Tutorial</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../cli.html">osxphotos command line interface (CLI)</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../reference.html">osxphotos package</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="relations">
|
||||
<h3>Related Topics</h3>
|
||||
<ul>
|
||||
<li><a href="../../index.html">Documentation overview</a><ul>
|
||||
<li><a href="../index.html">Module code</a><ul>
|
||||
</ul></li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="searchbox" style="display: none" role="search">
|
||||
<h3 id="searchlabel">Quick search</h3>
|
||||
<div class="searchformwrapper">
|
||||
<form class="search" action="../../search.html" method="get">
|
||||
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
|
||||
<input type="submit" value="Go" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<script>$('#searchbox').show(0);</script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
©2021, Rhet Turnbull.
|
||||
|
||||
|
|
||||
Powered by <a href="http://sphinx-doc.org/">Sphinx 4.4.0</a>
|
||||
& <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,422 +0,0 @@
|
||||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>osxphotos.fileutil — osxphotos 0.47.9 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="../../_static/alabaster.css" />
|
||||
<script data-url_root="../../" id="documentation_options" src="../../_static/documentation_options.js"></script>
|
||||
<script src="../../_static/jquery.js"></script>
|
||||
<script src="../../_static/underscore.js"></script>
|
||||
<script src="../../_static/doctools.js"></script>
|
||||
<link rel="index" title="Index" href="../../genindex.html" />
|
||||
<link rel="search" title="Search" href="../../search.html" />
|
||||
|
||||
<link rel="stylesheet" href="../../_static/custom.css" type="text/css" />
|
||||
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
|
||||
|
||||
</head><body>
|
||||
|
||||
|
||||
<div class="document">
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
|
||||
|
||||
<div class="body" role="main">
|
||||
|
||||
<h1>Source code for osxphotos.fileutil</h1><div class="highlight"><pre>
|
||||
<span></span><span class="sd">""" FileUtil class with methods for copy, hardlink, unlink, etc. """</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">stat</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">abc</span> <span class="kn">import</span> <span class="n">ABC</span><span class="p">,</span> <span class="n">abstractmethod</span>
|
||||
<span class="kn">from</span> <span class="nn">tempfile</span> <span class="kn">import</span> <span class="n">TemporaryDirectory</span>
|
||||
|
||||
<span class="kn">import</span> <span class="nn">Foundation</span>
|
||||
|
||||
<span class="kn">from</span> <span class="nn">.imageconverter</span> <span class="kn">import</span> <span class="n">ImageConverter</span>
|
||||
|
||||
<span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"FileUtilABC"</span><span class="p">,</span> <span class="s2">"FileUtilMacOS"</span><span class="p">,</span> <span class="s2">"FileUtil"</span><span class="p">,</span> <span class="s2">"FileUtilNoOp"</span><span class="p">]</span>
|
||||
|
||||
|
||||
<span class="k">class</span> <span class="nc">FileUtilABC</span><span class="p">(</span><span class="n">ABC</span><span class="p">):</span>
|
||||
<span class="sd">"""Abstract base class for FileUtil"""</span>
|
||||
|
||||
<span class="nd">@classmethod</span>
|
||||
<span class="nd">@abstractmethod</span>
|
||||
<span class="k">def</span> <span class="nf">hardlink</span><span class="p">(</span><span class="bp">cls</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="k">pass</span>
|
||||
|
||||
<span class="nd">@classmethod</span>
|
||||
<span class="nd">@abstractmethod</span>
|
||||
<span class="k">def</span> <span class="nf">copy</span><span class="p">(</span><span class="bp">cls</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">norsrc</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
|
||||
<span class="k">pass</span>
|
||||
|
||||
<span class="nd">@classmethod</span>
|
||||
<span class="nd">@abstractmethod</span>
|
||||
<span class="k">def</span> <span class="nf">unlink</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">dest</span><span class="p">):</span>
|
||||
<span class="k">pass</span>
|
||||
|
||||
<span class="nd">@classmethod</span>
|
||||
<span class="nd">@abstractmethod</span>
|
||||
<span class="k">def</span> <span class="nf">rmdir</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">dest</span><span class="p">):</span>
|
||||
<span class="k">pass</span>
|
||||
|
||||
<span class="nd">@classmethod</span>
|
||||
<span class="nd">@abstractmethod</span>
|
||||
<span class="k">def</span> <span class="nf">utime</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">times</span><span class="p">):</span>
|
||||
<span class="k">pass</span>
|
||||
|
||||
<span class="nd">@classmethod</span>
|
||||
<span class="nd">@abstractmethod</span>
|
||||
<span class="k">def</span> <span class="nf">cmp</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">file1</span><span class="p">,</span> <span class="n">file2</span><span class="p">,</span> <span class="n">mtime1</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
||||
<span class="k">pass</span>
|
||||
|
||||
<span class="nd">@classmethod</span>
|
||||
<span class="nd">@abstractmethod</span>
|
||||
<span class="k">def</span> <span class="nf">cmp_file_sig</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">file1</span><span class="p">,</span> <span class="n">file2</span><span class="p">):</span>
|
||||
<span class="k">pass</span>
|
||||
|
||||
<span class="nd">@classmethod</span>
|
||||
<span class="nd">@abstractmethod</span>
|
||||
<span class="k">def</span> <span class="nf">file_sig</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">file1</span><span class="p">):</span>
|
||||
<span class="k">pass</span>
|
||||
|
||||
<span class="nd">@classmethod</span>
|
||||
<span class="nd">@abstractmethod</span>
|
||||
<span class="k">def</span> <span class="nf">convert_to_jpeg</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">src_file</span><span class="p">,</span> <span class="n">dest_file</span><span class="p">,</span> <span class="n">compression_quality</span><span class="o">=</span><span class="mf">1.0</span><span class="p">):</span>
|
||||
<span class="k">pass</span>
|
||||
|
||||
<span class="nd">@classmethod</span>
|
||||
<span class="nd">@abstractmethod</span>
|
||||
<span class="k">def</span> <span class="nf">rename</span><span class="p">(</span><span class="bp">cls</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="k">pass</span>
|
||||
|
||||
<span class="nd">@classmethod</span>
|
||||
<span class="nd">@abstractmethod</span>
|
||||
<span class="k">def</span> <span class="nf">tmpdir</span><span class="p">(</span>
|
||||
<span class="bp">cls</span><span class="p">,</span> <span class="n">prefix</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="nb">dir</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="o">-></span> <span class="n">tempfile</span><span class="o">.</span><span class="n">TemporaryDirectory</span><span class="p">:</span>
|
||||
<span class="k">pass</span>
|
||||
|
||||
|
||||
<span class="k">class</span> <span class="nc">FileUtilMacOS</span><span class="p">(</span><span class="n">FileUtilABC</span><span class="p">):</span>
|
||||
<span class="sd">"""Various file utilities"""</span>
|
||||
|
||||
<span class="nd">@classmethod</span>
|
||||
<span class="k">def</span> <span class="nf">hardlink</span><span class="p">(</span><span class="bp">cls</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="sd">"""Hardlinks a file from src path to dest path</span>
|
||||
<span class="sd"> src: source path as string</span>
|
||||
<span class="sd"> dest: destination path as string</span>
|
||||
<span class="sd"> Raises exception if linking fails or either path is None"""</span>
|
||||
|
||||
<span class="k">if</span> <span class="n">src</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">or</span> <span class="n">dest</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
||||
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">"src and dest must not be None"</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="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">isfile</span><span class="p">(</span><span class="n">src</span><span class="p">):</span>
|
||||
<span class="k">raise</span> <span class="ne">FileNotFoundError</span><span class="p">(</span><span class="s2">"src file does not appear to exist"</span><span class="p">,</span> <span class="n">src</span><span class="p">)</span>
|
||||
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="n">os</span><span class="o">.</span><span class="n">link</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="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
|
||||
<span class="k">raise</span> <span class="n">e</span> <span class="kn">from</span> <span class="nn">e</span>
|
||||
|
||||
<span class="nd">@classmethod</span>
|
||||
<span class="k">def</span> <span class="nf">copy</span><span class="p">(</span><span class="bp">cls</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="sd">"""Copies a file from src path to dest path</span>
|
||||
|
||||
<span class="sd"> Args:</span>
|
||||
<span class="sd"> src: source path as string; must be a valid file path</span>
|
||||
<span class="sd"> dest: destination path as string</span>
|
||||
<span class="sd"> dest may be either directory or file; in either case, src file must not exist in dest</span>
|
||||
<span class="sd"> Note: src and dest may be either a string or a pathlib.Path object</span>
|
||||
|
||||
<span class="sd"> Returns:</span>
|
||||
<span class="sd"> True if copy succeeded</span>
|
||||
|
||||
<span class="sd"> Raises:</span>
|
||||
<span class="sd"> OSError if copy fails</span>
|
||||
<span class="sd"> TypeError if either path is None</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">src</span><span class="p">,</span> <span class="n">pathlib</span><span class="o">.</span><span class="n">Path</span><span class="p">):</span>
|
||||
<span class="n">src</span> <span class="o">=</span> <span class="n">pathlib</span><span class="o">.</span><span class="n">Path</span><span class="p">(</span><span class="n">src</span><span class="p">)</span>
|
||||
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">dest</span><span class="p">,</span> <span class="n">pathlib</span><span class="o">.</span><span class="n">Path</span><span class="p">):</span>
|
||||
<span class="n">dest</span> <span class="o">=</span> <span class="n">pathlib</span><span class="o">.</span><span class="n">Path</span><span class="p">(</span><span class="n">dest</span><span class="p">)</span>
|
||||
|
||||
<span class="k">if</span> <span class="n">dest</span><span class="o">.</span><span class="n">is_dir</span><span class="p">():</span>
|
||||
<span class="n">dest</span> <span class="o">/=</span> <span class="n">src</span><span class="o">.</span><span class="n">name</span>
|
||||
|
||||
<span class="n">filemgr</span> <span class="o">=</span> <span class="n">Foundation</span><span class="o">.</span><span class="n">NSFileManager</span><span class="o">.</span><span class="n">defaultManager</span><span class="p">()</span>
|
||||
<span class="n">error</span> <span class="o">=</span> <span class="n">filemgr</span><span class="o">.</span><span class="n">copyItemAtPath_toPath_error_</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">src</span><span class="p">),</span> <span class="nb">str</span><span class="p">(</span><span class="n">dest</span><span class="p">),</span> <span class="kc">None</span><span class="p">)</span>
|
||||
<span class="c1"># error is a tuple of (bool, error_string)</span>
|
||||
<span class="c1"># error[0] is True if copy succeeded</span>
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="n">error</span><span class="p">[</span><span class="mi">0</span><span class="p">]:</span>
|
||||
<span class="k">raise</span> <span class="ne">OSError</span><span class="p">(</span><span class="n">error</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
|
||||
<span class="k">return</span> <span class="kc">True</span>
|
||||
|
||||
<span class="nd">@classmethod</span>
|
||||
<span class="k">def</span> <span class="nf">unlink</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">filepath</span><span class="p">):</span>
|
||||
<span class="sd">"""unlink filepath; if it's pathlib.Path, use Path.unlink, otherwise use os.unlink"""</span>
|
||||
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">filepath</span><span class="p">,</span> <span class="n">pathlib</span><span class="o">.</span><span class="n">Path</span><span class="p">):</span>
|
||||
<span class="n">filepath</span><span class="o">.</span><span class="n">unlink</span><span class="p">()</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="n">os</span><span class="o">.</span><span class="n">unlink</span><span class="p">(</span><span class="n">filepath</span><span class="p">)</span>
|
||||
|
||||
<span class="nd">@classmethod</span>
|
||||
<span class="k">def</span> <span class="nf">rmdir</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">dirpath</span><span class="p">):</span>
|
||||
<span class="sd">"""remove directory filepath; dirpath must be empty"""</span>
|
||||
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">dirpath</span><span class="p">,</span> <span class="n">pathlib</span><span class="o">.</span><span class="n">Path</span><span class="p">):</span>
|
||||
<span class="n">dirpath</span><span class="o">.</span><span class="n">rmdir</span><span class="p">()</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="n">os</span><span class="o">.</span><span class="n">rmdir</span><span class="p">(</span><span class="n">dirpath</span><span class="p">)</span>
|
||||
|
||||
<span class="nd">@classmethod</span>
|
||||
<span class="k">def</span> <span class="nf">utime</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">times</span><span class="p">):</span>
|
||||
<span class="sd">"""Set the access and modified time of path."""</span>
|
||||
<span class="n">os</span><span class="o">.</span><span class="n">utime</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="n">times</span><span class="o">=</span><span class="n">times</span><span class="p">)</span>
|
||||
|
||||
<span class="nd">@classmethod</span>
|
||||
<span class="k">def</span> <span class="nf">cmp</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">f1</span><span class="p">,</span> <span class="n">f2</span><span class="p">,</span> <span class="n">mtime1</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
||||
<span class="sd">"""Does shallow compare (file signatures) of f1 to file f2.</span>
|
||||
<span class="sd"> Arguments:</span>
|
||||
<span class="sd"> f1 -- File name</span>
|
||||
<span class="sd"> f2 -- File name</span>
|
||||
<span class="sd"> mtime1 -- optional, pass alternate file modification timestamp for f1; will be converted to int</span>
|
||||
|
||||
<span class="sd"> Return value:</span>
|
||||
<span class="sd"> True if the file signatures as returned by stat are the same, False otherwise.</span>
|
||||
<span class="sd"> Does not do a byte-by-byte comparison.</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="n">s1</span> <span class="o">=</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_sig</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">stat</span><span class="p">(</span><span class="n">f1</span><span class="p">))</span>
|
||||
<span class="k">if</span> <span class="n">mtime1</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
||||
<span class="n">s1</span> <span class="o">=</span> <span class="p">(</span><span class="n">s1</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">s1</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="nb">int</span><span class="p">(</span><span class="n">mtime1</span><span class="p">))</span>
|
||||
<span class="n">s2</span> <span class="o">=</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_sig</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">stat</span><span class="p">(</span><span class="n">f2</span><span class="p">))</span>
|
||||
<span class="k">if</span> <span class="n">s1</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">!=</span> <span class="n">stat</span><span class="o">.</span><span class="n">S_IFREG</span> <span class="ow">or</span> <span class="n">s2</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">!=</span> <span class="n">stat</span><span class="o">.</span><span class="n">S_IFREG</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="kc">False</span>
|
||||
<span class="k">return</span> <span class="n">s1</span> <span class="o">==</span> <span class="n">s2</span>
|
||||
|
||||
<span class="nd">@classmethod</span>
|
||||
<span class="k">def</span> <span class="nf">cmp_file_sig</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">f1</span><span class="p">,</span> <span class="n">s2</span><span class="p">):</span>
|
||||
<span class="sd">"""Compare file f1 to signature s2.</span>
|
||||
<span class="sd"> Arguments:</span>
|
||||
<span class="sd"> f1 -- File name</span>
|
||||
<span class="sd"> s2 -- stats as returned by _sig</span>
|
||||
|
||||
<span class="sd"> Return value:</span>
|
||||
<span class="sd"> True if the files are the same, False otherwise.</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="n">s2</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="kc">False</span>
|
||||
|
||||
<span class="n">s1</span> <span class="o">=</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_sig</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">stat</span><span class="p">(</span><span class="n">f1</span><span class="p">))</span>
|
||||
<span class="k">if</span> <span class="n">s1</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">!=</span> <span class="n">stat</span><span class="o">.</span><span class="n">S_IFREG</span> <span class="ow">or</span> <span class="n">s2</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">!=</span> <span class="n">stat</span><span class="o">.</span><span class="n">S_IFREG</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="kc">False</span>
|
||||
<span class="k">return</span> <span class="n">s1</span> <span class="o">==</span> <span class="n">s2</span>
|
||||
|
||||
<span class="nd">@classmethod</span>
|
||||
<span class="k">def</span> <span class="nf">file_sig</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">f1</span><span class="p">):</span>
|
||||
<span class="sd">"""return os.stat signature for file f1 as tuple of (mode, size, mtime)"""</span>
|
||||
<span class="k">return</span> <span class="bp">cls</span><span class="o">.</span><span class="n">_sig</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">stat</span><span class="p">(</span><span class="n">f1</span><span class="p">))</span>
|
||||
|
||||
<span class="nd">@classmethod</span>
|
||||
<span class="k">def</span> <span class="nf">convert_to_jpeg</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">src_file</span><span class="p">,</span> <span class="n">dest_file</span><span class="p">,</span> <span class="n">compression_quality</span><span class="o">=</span><span class="mf">1.0</span><span class="p">):</span>
|
||||
<span class="sd">"""converts image file src_file to jpeg format as dest_file</span>
|
||||
|
||||
<span class="sd"> Args:</span>
|
||||
<span class="sd"> src_file: image file to convert</span>
|
||||
<span class="sd"> dest_file: destination path to write converted file to</span>
|
||||
<span class="sd"> compression quality: JPEG compression quality in range 0.0 <= compression_quality <= 1.0; default 1.0 (best quality)</span>
|
||||
|
||||
<span class="sd"> Returns:</span>
|
||||
<span class="sd"> True if success, otherwise False</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="n">converter</span> <span class="o">=</span> <span class="n">ImageConverter</span><span class="p">()</span>
|
||||
<span class="k">return</span> <span class="n">converter</span><span class="o">.</span><span class="n">write_jpeg</span><span class="p">(</span>
|
||||
<span class="n">src_file</span><span class="p">,</span> <span class="n">dest_file</span><span class="p">,</span> <span class="n">compression_quality</span><span class="o">=</span><span class="n">compression_quality</span>
|
||||
<span class="p">)</span>
|
||||
|
||||
<span class="nd">@classmethod</span>
|
||||
<span class="k">def</span> <span class="nf">rename</span><span class="p">(</span><span class="bp">cls</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="sd">"""Copy src to dest</span>
|
||||
|
||||
<span class="sd"> Args:</span>
|
||||
<span class="sd"> src: path to source file</span>
|
||||
<span class="sd"> dest: path to destination file</span>
|
||||
|
||||
<span class="sd"> Returns:</span>
|
||||
<span class="sd"> Name of renamed file (dest)</span>
|
||||
|
||||
<span class="sd"> """</span>
|
||||
<span class="n">os</span><span class="o">.</span><span class="n">rename</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">src</span><span class="p">),</span> <span class="nb">str</span><span class="p">(</span><span class="n">dest</span><span class="p">))</span>
|
||||
<span class="k">return</span> <span class="n">dest</span>
|
||||
|
||||
<span class="nd">@classmethod</span>
|
||||
<span class="k">def</span> <span class="nf">tmpdir</span><span class="p">(</span>
|
||||
<span class="bp">cls</span><span class="p">,</span> <span class="n">prefix</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="nb">dir</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="o">-></span> <span class="n">tempfile</span><span class="o">.</span><span class="n">TemporaryDirectory</span><span class="p">:</span>
|
||||
<span class="sd">"""Securely creates a temporary directory using the same rules as mkdtemp().</span>
|
||||
<span class="sd"> The resulting object can be used as a context manager.</span>
|
||||
<span class="sd"> On completion of the context or destruction of the temporary directory object,</span>
|
||||
<span class="sd"> the newly created temporary directory and all its contents are removed from the filesystem.</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">return</span> <span class="n">TemporaryDirectory</span><span class="p">(</span><span class="n">prefix</span><span class="o">=</span><span class="n">prefix</span><span class="p">,</span> <span class="nb">dir</span><span class="o">=</span><span class="nb">dir</span><span class="p">)</span>
|
||||
|
||||
<span class="nd">@staticmethod</span>
|
||||
<span class="k">def</span> <span class="nf">_sig</span><span class="p">(</span><span class="n">st</span><span class="p">):</span>
|
||||
<span class="sd">"""return tuple of (mode, size, mtime) of file based on os.stat</span>
|
||||
<span class="sd"> Args:</span>
|
||||
<span class="sd"> st: os.stat signature</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="c1"># use int(st.st_mtime) because ditto does not copy fractional portion of mtime</span>
|
||||
<span class="k">return</span> <span class="p">(</span><span class="n">stat</span><span class="o">.</span><span class="n">S_IFMT</span><span class="p">(</span><span class="n">st</span><span class="o">.</span><span class="n">st_mode</span><span class="p">),</span> <span class="n">st</span><span class="o">.</span><span class="n">st_size</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">st</span><span class="o">.</span><span class="n">st_mtime</span><span class="p">))</span>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="FileUtil"><a class="viewcode-back" href="../../reference.html#osxphotos.FileUtil">[docs]</a><span class="k">class</span> <span class="nc">FileUtil</span><span class="p">(</span><span class="n">FileUtilMacOS</span><span class="p">):</span>
|
||||
<span class="sd">"""Various file utilities"""</span>
|
||||
|
||||
<span class="k">pass</span></div>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="FileUtilNoOp"><a class="viewcode-back" href="../../reference.html#osxphotos.FileUtilNoOp">[docs]</a><span class="k">class</span> <span class="nc">FileUtilNoOp</span><span class="p">(</span><span class="n">FileUtil</span><span class="p">):</span>
|
||||
<span class="sd">"""No-Op implementation of FileUtil for testing / dry-run mode</span>
|
||||
<span class="sd"> all methods with exception of tmpdir, cmp, cmp_file_sig and file_cmp are no-op</span>
|
||||
<span class="sd"> cmp and cmp_file_sig functions as FileUtil methods do</span>
|
||||
<span class="sd"> file_cmp returns mock data</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="nd">@staticmethod</span>
|
||||
<span class="k">def</span> <span class="nf">noop</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">):</span>
|
||||
<span class="k">pass</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__new__</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">verbose</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
||||
<span class="k">if</span> <span class="n">verbose</span><span class="p">:</span>
|
||||
<span class="k">if</span> <span class="n">callable</span><span class="p">(</span><span class="n">verbose</span><span class="p">):</span>
|
||||
<span class="bp">cls</span><span class="o">.</span><span class="n">verbose</span> <span class="o">=</span> <span class="n">verbose</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"verbose </span><span class="si">{</span><span class="n">verbose</span><span class="si">}</span><span class="s2"> not callable"</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="nb">super</span><span class="p">(</span><span class="n">FileUtilNoOp</span><span class="p">,</span> <span class="bp">cls</span><span class="p">)</span><span class="o">.</span><span class="fm">__new__</span><span class="p">(</span><span class="bp">cls</span><span class="p">)</span>
|
||||
|
||||
<div class="viewcode-block" id="FileUtilNoOp.hardlink"><a class="viewcode-back" href="../../reference.html#osxphotos.FileUtilNoOp.hardlink">[docs]</a> <span class="nd">@classmethod</span>
|
||||
<span class="k">def</span> <span class="nf">hardlink</span><span class="p">(</span><span class="bp">cls</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="k">pass</span></div>
|
||||
|
||||
<div class="viewcode-block" id="FileUtilNoOp.copy"><a class="viewcode-back" href="../../reference.html#osxphotos.FileUtilNoOp.copy">[docs]</a> <span class="nd">@classmethod</span>
|
||||
<span class="k">def</span> <span class="nf">copy</span><span class="p">(</span><span class="bp">cls</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">norsrc</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
|
||||
<span class="k">pass</span></div>
|
||||
|
||||
<div class="viewcode-block" id="FileUtilNoOp.unlink"><a class="viewcode-back" href="../../reference.html#osxphotos.FileUtilNoOp.unlink">[docs]</a> <span class="nd">@classmethod</span>
|
||||
<span class="k">def</span> <span class="nf">unlink</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">dest</span><span class="p">):</span>
|
||||
<span class="k">pass</span></div>
|
||||
|
||||
<div class="viewcode-block" id="FileUtilNoOp.rmdir"><a class="viewcode-back" href="../../reference.html#osxphotos.FileUtilNoOp.rmdir">[docs]</a> <span class="nd">@classmethod</span>
|
||||
<span class="k">def</span> <span class="nf">rmdir</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">dest</span><span class="p">):</span>
|
||||
<span class="k">pass</span></div>
|
||||
|
||||
<div class="viewcode-block" id="FileUtilNoOp.utime"><a class="viewcode-back" href="../../reference.html#osxphotos.FileUtilNoOp.utime">[docs]</a> <span class="nd">@classmethod</span>
|
||||
<span class="k">def</span> <span class="nf">utime</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">times</span><span class="p">):</span>
|
||||
<span class="k">pass</span></div>
|
||||
|
||||
<div class="viewcode-block" id="FileUtilNoOp.file_sig"><a class="viewcode-back" href="../../reference.html#osxphotos.FileUtilNoOp.file_sig">[docs]</a> <span class="nd">@classmethod</span>
|
||||
<span class="k">def</span> <span class="nf">file_sig</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">file1</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="p">(</span><span class="mi">42</span><span class="p">,</span> <span class="mi">42</span><span class="p">,</span> <span class="mi">42</span><span class="p">)</span></div>
|
||||
|
||||
<div class="viewcode-block" id="FileUtilNoOp.convert_to_jpeg"><a class="viewcode-back" href="../../reference.html#osxphotos.FileUtilNoOp.convert_to_jpeg">[docs]</a> <span class="nd">@classmethod</span>
|
||||
<span class="k">def</span> <span class="nf">convert_to_jpeg</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">src_file</span><span class="p">,</span> <span class="n">dest_file</span><span class="p">,</span> <span class="n">compression_quality</span><span class="o">=</span><span class="mf">1.0</span><span class="p">):</span>
|
||||
<span class="k">pass</span></div>
|
||||
|
||||
<div class="viewcode-block" id="FileUtilNoOp.rename"><a class="viewcode-back" href="../../reference.html#osxphotos.FileUtilNoOp.rename">[docs]</a> <span class="nd">@classmethod</span>
|
||||
<span class="k">def</span> <span class="nf">rename</span><span class="p">(</span><span class="bp">cls</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="k">pass</span></div>
|
||||
|
||||
<div class="viewcode-block" id="FileUtilNoOp.tmpdir"><a class="viewcode-back" href="../../reference.html#osxphotos.FileUtilNoOp.tmpdir">[docs]</a> <span class="nd">@classmethod</span>
|
||||
<span class="k">def</span> <span class="nf">tmpdir</span><span class="p">(</span>
|
||||
<span class="bp">cls</span><span class="p">,</span> <span class="n">prefix</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="nb">dir</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="o">-></span> <span class="n">tempfile</span><span class="o">.</span><span class="n">TemporaryDirectory</span><span class="p">:</span>
|
||||
<span class="sd">"""Securely creates a temporary directory using the same rules as mkdtemp().</span>
|
||||
<span class="sd"> The resulting object can be used as a context manager.</span>
|
||||
<span class="sd"> On completion of the context or destruction of the temporary directory object,</span>
|
||||
<span class="sd"> the newly created temporary directory and all its contents are removed from the filesystem.</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">return</span> <span class="n">TemporaryDirectory</span><span class="p">(</span><span class="n">prefix</span><span class="o">=</span><span class="n">prefix</span><span class="p">,</span> <span class="nb">dir</span><span class="o">=</span><span class="nb">dir</span><span class="p">)</span></div></div>
|
||||
</pre></div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||||
<div class="sphinxsidebarwrapper">
|
||||
<h1 class="logo"><a href="../../index.html">osxphotos</a></h1>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../overview.html">osxphotos</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../tutorial.html">Tutorial</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../cli.html">osxphotos command line interface (CLI)</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../reference.html">osxphotos package</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="relations">
|
||||
<h3>Related Topics</h3>
|
||||
<ul>
|
||||
<li><a href="../../index.html">Documentation overview</a><ul>
|
||||
<li><a href="../index.html">Module code</a><ul>
|
||||
</ul></li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="searchbox" style="display: none" role="search">
|
||||
<h3 id="searchlabel">Quick search</h3>
|
||||
<div class="searchformwrapper">
|
||||
<form class="search" action="../../search.html" method="get">
|
||||
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
|
||||
<input type="submit" value="Go" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<script>$('#searchbox').show(0);</script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
©2021, Rhet Turnbull.
|
||||
|
||||
|
|
||||
Powered by <a href="http://sphinx-doc.org/">Sphinx 4.4.0</a>
|
||||
& <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,173 +0,0 @@
|
||||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>osxphotos.momentinfo — osxphotos 0.47.9 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="../../_static/alabaster.css" />
|
||||
<script data-url_root="../../" id="documentation_options" src="../../_static/documentation_options.js"></script>
|
||||
<script src="../../_static/jquery.js"></script>
|
||||
<script src="../../_static/underscore.js"></script>
|
||||
<script src="../../_static/doctools.js"></script>
|
||||
<link rel="index" title="Index" href="../../genindex.html" />
|
||||
<link rel="search" title="Search" href="../../search.html" />
|
||||
|
||||
<link rel="stylesheet" href="../../_static/custom.css" type="text/css" />
|
||||
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
|
||||
|
||||
</head><body>
|
||||
|
||||
|
||||
<div class="document">
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
|
||||
|
||||
<div class="body" role="main">
|
||||
|
||||
<h1>Source code for osxphotos.momentinfo</h1><div class="highlight"><pre>
|
||||
<span></span><span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"MomentInfo"</span><span class="p">]</span>
|
||||
<span class="sd">"""MomentInfo class with details about photo moments."""</span>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="MomentInfo"><a class="viewcode-back" href="../../reference.html#osxphotos.MomentInfo">[docs]</a><span class="k">class</span> <span class="nc">MomentInfo</span><span class="p">:</span>
|
||||
<span class="sd">"""Info about a photo moment"""</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">db</span><span class="p">,</span> <span class="n">moment_pk</span><span class="p">):</span>
|
||||
<span class="sd">"""Initialize with a moment PK; returns None if PK not found."""</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_db</span> <span class="o">=</span> <span class="n">db</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_pk</span> <span class="o">=</span> <span class="n">moment_pk</span>
|
||||
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_moment</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_db_moment_pk</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">moment_pk</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_moment</span><span class="p">:</span>
|
||||
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"No moment with PK </span><span class="si">{</span><span class="n">moment_pk</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">pk</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""Primary key of the moment."""</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_pk</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">location</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""Location of the moment."""</span>
|
||||
<span class="k">return</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_moment</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"latitude"</span><span class="p">),</span> <span class="bp">self</span><span class="o">.</span><span class="n">_moment</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"longitude"</span><span class="p">))</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">title</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""Title of the moment."""</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_moment</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"title"</span><span class="p">)</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">subtitle</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""Subtitle of the moment."""</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_moment</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"subtitle"</span><span class="p">)</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">start_date</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""Start date of the moment."""</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_moment</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"startDate"</span><span class="p">)</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">end_date</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""Stop date of the moment."""</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_moment</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"endDate"</span><span class="p">)</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">date</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""Date of the moment."""</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_moment</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"representativeDate"</span><span class="p">)</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">modification_date</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""Modification date of the moment."""</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_moment</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"modificationDate"</span><span class="p">)</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">photos</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""All photos in this moment"""</span>
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_photos</span>
|
||||
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
|
||||
<span class="n">photo_uuids</span> <span class="o">=</span> <span class="p">[</span>
|
||||
<span class="n">uuid</span>
|
||||
<span class="k">for</span> <span class="n">uuid</span><span class="p">,</span> <span class="n">photo</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_dbphotos</span><span class="o">.</span><span class="n">items</span><span class="p">()</span>
|
||||
<span class="k">if</span> <span class="n">photo</span><span class="p">[</span><span class="s2">"momentID"</span><span class="p">]</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">_pk</span>
|
||||
<span class="p">]</span>
|
||||
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_photos</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">photos_by_uuid</span><span class="p">(</span><span class="n">photo_uuids</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_photos</span></div>
|
||||
</pre></div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||||
<div class="sphinxsidebarwrapper">
|
||||
<h1 class="logo"><a href="../../index.html">osxphotos</a></h1>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../overview.html">osxphotos</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../tutorial.html">Tutorial</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../cli.html">osxphotos command line interface (CLI)</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../reference.html">osxphotos package</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="relations">
|
||||
<h3>Related Topics</h3>
|
||||
<ul>
|
||||
<li><a href="../../index.html">Documentation overview</a><ul>
|
||||
<li><a href="../index.html">Module code</a><ul>
|
||||
</ul></li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="searchbox" style="display: none" role="search">
|
||||
<h3 id="searchlabel">Quick search</h3>
|
||||
<div class="searchformwrapper">
|
||||
<form class="search" action="../../search.html" method="get">
|
||||
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
|
||||
<input type="submit" value="Go" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<script>$('#searchbox').show(0);</script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
©2021, Rhet Turnbull.
|
||||
|
||||
|
|
||||
Powered by <a href="http://sphinx-doc.org/">Sphinx 4.4.0</a>
|
||||
& <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,606 +0,0 @@
|
||||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>osxphotos.personinfo — osxphotos 0.47.9 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="../../_static/alabaster.css" />
|
||||
<script data-url_root="../../" id="documentation_options" src="../../_static/documentation_options.js"></script>
|
||||
<script src="../../_static/jquery.js"></script>
|
||||
<script src="../../_static/underscore.js"></script>
|
||||
<script src="../../_static/doctools.js"></script>
|
||||
<link rel="index" title="Index" href="../../genindex.html" />
|
||||
<link rel="search" title="Search" href="../../search.html" />
|
||||
|
||||
<link rel="stylesheet" href="../../_static/custom.css" type="text/css" />
|
||||
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
|
||||
|
||||
</head><body>
|
||||
|
||||
|
||||
<div class="document">
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
|
||||
|
||||
<div class="body" role="main">
|
||||
|
||||
<h1>Source code for osxphotos.personinfo</h1><div class="highlight"><pre>
|
||||
<span></span><span class="sd">""" PhotoInfo and FaceInfo classes to expose info about persons and faces in the Photos library """</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">math</span>
|
||||
|
||||
<span class="kn">from</span> <span class="nn">collections</span> <span class="kn">import</span> <span class="n">namedtuple</span>
|
||||
|
||||
<span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"PersonInfo"</span><span class="p">,</span> <span class="s2">"FaceInfo"</span><span class="p">,</span> <span class="s2">"rotate_image_point"</span><span class="p">]</span>
|
||||
|
||||
<span class="n">MWG_RS_Area</span> <span class="o">=</span> <span class="n">namedtuple</span><span class="p">(</span><span class="s2">"MWG_RS_Area"</span><span class="p">,</span> <span class="p">[</span><span class="s2">"x"</span><span class="p">,</span> <span class="s2">"y"</span><span class="p">,</span> <span class="s2">"h"</span><span class="p">,</span> <span class="s2">"w"</span><span class="p">])</span>
|
||||
<span class="n">MPRI_Reg_Rect</span> <span class="o">=</span> <span class="n">namedtuple</span><span class="p">(</span><span class="s2">"MPRI_Reg_Rect"</span><span class="p">,</span> <span class="p">[</span><span class="s2">"x"</span><span class="p">,</span> <span class="s2">"y"</span><span class="p">,</span> <span class="s2">"h"</span><span class="p">,</span> <span class="s2">"w"</span><span class="p">])</span>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="PersonInfo"><a class="viewcode-back" href="../../reference.html#osxphotos.PersonInfo">[docs]</a><span class="k">class</span> <span class="nc">PersonInfo</span><span class="p">:</span>
|
||||
<span class="sd">"""Info about a person in the Photos library"""</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">db</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">pk</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
||||
<span class="sd">"""Creates a new PersonInfo instance</span>
|
||||
|
||||
<span class="sd"> Arguments:</span>
|
||||
<span class="sd"> db: instance of PhotosDB object</span>
|
||||
<span class="sd"> pk: primary key value of person to initialize PersonInfo with</span>
|
||||
|
||||
<span class="sd"> Returns:</span>
|
||||
<span class="sd"> PersonInfo instance</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_db</span> <span class="o">=</span> <span class="n">db</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_pk</span> <span class="o">=</span> <span class="n">pk</span>
|
||||
|
||||
<span class="n">person</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_dbpersons_pk</span><span class="p">[</span><span class="n">pk</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">uuid</span> <span class="o">=</span> <span class="n">person</span><span class="p">[</span><span class="s2">"uuid"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">person</span><span class="p">[</span><span class="s2">"fullname"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">display_name</span> <span class="o">=</span> <span class="n">person</span><span class="p">[</span><span class="s2">"displayname"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">keyface</span> <span class="o">=</span> <span class="n">person</span><span class="p">[</span><span class="s2">"keyface"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">facecount</span> <span class="o">=</span> <span class="n">person</span><span class="p">[</span><span class="s2">"facecount"</span><span class="p">]</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">keyphoto</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_keyphoto</span>
|
||||
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
|
||||
<span class="n">person</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_dbpersons_pk</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">_pk</span><span class="p">]</span>
|
||||
<span class="k">if</span> <span class="n">person</span><span class="p">[</span><span class="s2">"photo_uuid"</span><span class="p">]:</span>
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="n">key_photo</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">get_photo</span><span class="p">(</span><span class="n">person</span><span class="p">[</span><span class="s2">"photo_uuid"</span><span class="p">])</span>
|
||||
<span class="k">except</span> <span class="ne">IndexError</span><span class="p">:</span>
|
||||
<span class="n">key_photo</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="n">key_photo</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_keyphoto</span> <span class="o">=</span> <span class="n">key_photo</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_keyphoto</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">photos</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""Returns list of PhotoInfo objects associated with this person"""</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">photos_by_uuid</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_dbfaces_pk</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">_pk</span><span class="p">])</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">face_info</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""Returns a list of FaceInfo objects associated with this person sorted by quality score</span>
|
||||
<span class="sd"> Highest quality face is result[0] and lowest quality face is result[n]</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="n">faces</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_db_faceinfo_person</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">_pk</span><span class="p">]</span>
|
||||
<span class="k">return</span> <span class="nb">sorted</span><span class="p">(</span>
|
||||
<span class="p">[</span><span class="n">FaceInfo</span><span class="p">(</span><span class="n">db</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="p">,</span> <span class="n">pk</span><span class="o">=</span><span class="n">face</span><span class="p">)</span> <span class="k">for</span> <span class="n">face</span> <span class="ow">in</span> <span class="n">faces</span><span class="p">],</span>
|
||||
<span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">face</span><span class="p">:</span> <span class="n">face</span><span class="o">.</span><span class="n">quality</span><span class="p">,</span>
|
||||
<span class="n">reverse</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
|
||||
<span class="p">)</span>
|
||||
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
|
||||
<span class="c1"># no faces</span>
|
||||
<span class="k">return</span> <span class="p">[]</span>
|
||||
|
||||
<div class="viewcode-block" id="PersonInfo.asdict"><a class="viewcode-back" href="../../reference.html#osxphotos.PersonInfo.asdict">[docs]</a> <span class="k">def</span> <span class="nf">asdict</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""Returns dictionary representation of class instance"""</span>
|
||||
<span class="n">keyphoto</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">keyphoto</span><span class="o">.</span><span class="n">uuid</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">keyphoto</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="k">else</span> <span class="kc">None</span>
|
||||
<span class="k">return</span> <span class="p">{</span>
|
||||
<span class="s2">"uuid"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">uuid</span><span class="p">,</span>
|
||||
<span class="s2">"name"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">,</span>
|
||||
<span class="s2">"displayname"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">display_name</span><span class="p">,</span>
|
||||
<span class="s2">"keyface"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">keyface</span><span class="p">,</span>
|
||||
<span class="s2">"facecount"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">facecount</span><span class="p">,</span>
|
||||
<span class="s2">"keyphoto"</span><span class="p">:</span> <span class="n">keyphoto</span><span class="p">,</span>
|
||||
<span class="p">}</span></div>
|
||||
|
||||
<div class="viewcode-block" id="PersonInfo.json"><a class="viewcode-back" href="../../reference.html#osxphotos.PersonInfo.json">[docs]</a> <span class="k">def</span> <span class="nf">json</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""Returns JSON representation of class instance"""</span>
|
||||
<span class="k">return</span> <span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">asdict</span><span class="p">())</span></div>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="sa">f</span><span class="s2">"PersonInfo(name=</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="si">}</span><span class="s2">, display_name=</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">display_name</span><span class="si">}</span><span class="s2">, uuid=</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">uuid</span><span class="si">}</span><span class="s2">, facecount=</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">facecount</span><span class="si">}</span><span class="s2">)"</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="nb">type</span><span class="p">(</span><span class="bp">self</span><span class="p">)):</span>
|
||||
<span class="k">return</span> <span class="kc">False</span>
|
||||
|
||||
<span class="k">return</span> <span class="nb">all</span><span class="p">(</span>
|
||||
<span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">field</span><span class="p">)</span> <span class="o">==</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="n">field</span><span class="p">)</span> <span class="k">for</span> <span class="n">field</span> <span class="ow">in</span> <span class="p">[</span><span class="s2">"_db"</span><span class="p">,</span> <span class="s2">"_pk"</span><span class="p">]</span>
|
||||
<span class="p">)</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__ne__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="fm">__eq__</span><span class="p">(</span><span class="n">other</span><span class="p">)</span></div>
|
||||
|
||||
|
||||
<span class="k">class</span> <span class="nc">FaceInfo</span><span class="p">:</span>
|
||||
<span class="sd">"""Info about a face in the Photos library"""</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">db</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">pk</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
||||
<span class="sd">"""Creates a new FaceInfo instance</span>
|
||||
|
||||
<span class="sd"> Arguments:</span>
|
||||
<span class="sd"> db: instance of PhotosDB object</span>
|
||||
<span class="sd"> pk: primary key value of face to init the object with</span>
|
||||
|
||||
<span class="sd"> Returns:</span>
|
||||
<span class="sd"> FaceInfo instance</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_db</span> <span class="o">=</span> <span class="n">db</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_pk</span> <span class="o">=</span> <span class="n">pk</span>
|
||||
|
||||
<span class="n">face</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_db_faceinfo_pk</span><span class="p">[</span><span class="n">pk</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_info</span> <span class="o">=</span> <span class="n">face</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">uuid</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"uuid"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"fullname"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">asset_uuid</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"asset_uuid"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_person_pk</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"person"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">center_x</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"centerx"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">center_y</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"centery"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">mouth_x</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"mouthx"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">mouth_y</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"mouthy"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">left_eye_x</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"lefteyex"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">left_eye_y</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"lefteyey"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">right_eye_x</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"righteyex"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">right_eye_y</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"righteyey"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">size</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"size"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">quality</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"quality"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">source_width</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"sourcewidth"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">source_height</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"sourceheight"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">has_smile</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"has_smile"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">left_eye_closed</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"left_eye_closed"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">right_eye_closed</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"right_eye_closed"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">manual</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"manual"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">face_type</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"facetype"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">age_type</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"agetype"</span><span class="p">]</span>
|
||||
<span class="c1"># self.bald_type = face["baldtype"]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">eye_makeup_type</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"eyemakeuptype"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">eye_state</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"eyestate"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">facial_hair_type</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"facialhairtype"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">gender_type</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"gendertype"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">glasses_type</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"glassestype"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">hair_color_type</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"haircolortype"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">intrash</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"intrash"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">lip_makeup_type</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"lipmakeuptype"</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">smile_type</span> <span class="o">=</span> <span class="n">face</span><span class="p">[</span><span class="s2">"smiletype"</span><span class="p">]</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">center</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""Coordinates, in PIL format, for center of face</span>
|
||||
|
||||
<span class="sd"> Returns:</span>
|
||||
<span class="sd"> tuple of coordinates in form (x, y)</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_make_point</span><span class="p">((</span><span class="bp">self</span><span class="o">.</span><span class="n">center_x</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">center_y</span><span class="p">))</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">size_pixels</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""Size of face in pixels (centered around center_x, center_y)</span>
|
||||
|
||||
<span class="sd"> Returns:</span>
|
||||
<span class="sd"> size, in int pixels, of a circle drawn around the center of the face</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="n">photo</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">photo</span>
|
||||
<span class="n">size_reference</span> <span class="o">=</span> <span class="n">photo</span><span class="o">.</span><span class="n">width</span> <span class="k">if</span> <span class="n">photo</span><span class="o">.</span><span class="n">width</span> <span class="o">></span> <span class="n">photo</span><span class="o">.</span><span class="n">height</span> <span class="k">else</span> <span class="n">photo</span><span class="o">.</span><span class="n">height</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">size</span> <span class="o">*</span> <span class="n">size_reference</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">mouth</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""Coordinates, in PIL format, for mouth position</span>
|
||||
|
||||
<span class="sd"> Returns:</span>
|
||||
<span class="sd"> tuple of coordinates in form (x, y)</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_make_point_with_rotation</span><span class="p">((</span><span class="bp">self</span><span class="o">.</span><span class="n">mouth_x</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">mouth_y</span><span class="p">))</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">left_eye</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""Coordinates, in PIL format, for left eye position</span>
|
||||
|
||||
<span class="sd"> Returns:</span>
|
||||
<span class="sd"> tuple of coordinates in form (x, y)</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_make_point_with_rotation</span><span class="p">((</span><span class="bp">self</span><span class="o">.</span><span class="n">left_eye_x</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">left_eye_y</span><span class="p">))</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">right_eye</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""Coordinates, in PIL format, for right eye position</span>
|
||||
|
||||
<span class="sd"> Returns:</span>
|
||||
<span class="sd"> tuple of coordinates in form (x, y)</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_make_point_with_rotation</span><span class="p">((</span><span class="bp">self</span><span class="o">.</span><span class="n">right_eye_x</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">right_eye_y</span><span class="p">))</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">person_info</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""PersonInfo instance for person associated with this face"""</span>
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_person</span>
|
||||
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_person</span> <span class="o">=</span> <span class="n">PersonInfo</span><span class="p">(</span><span class="n">db</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="p">,</span> <span class="n">pk</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_person_pk</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_person</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">photo</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""PhotoInfo instance associated with this face"""</span>
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_photo</span>
|
||||
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_photo</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">get_photo</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">asset_uuid</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="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
||||
<span class="n">logging</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Could not get photo for uuid: </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">asset_uuid</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_photo</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">mwg_rs_area</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""Get coordinates for Metadata Working Group Region Area.</span>
|
||||
|
||||
<span class="sd"> Returns:</span>
|
||||
<span class="sd"> MWG_RS_Area named tuple with x, y, h, w where:</span>
|
||||
<span class="sd"> x = stArea:x</span>
|
||||
<span class="sd"> y = stArea:y</span>
|
||||
<span class="sd"> h = stArea:h</span>
|
||||
<span class="sd"> w = stArea:w</span>
|
||||
|
||||
<span class="sd"> Reference:</span>
|
||||
<span class="sd"> https://photo.stackexchange.com/questions/106410/how-does-xmp-define-the-face-region</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="n">x</span><span class="p">,</span> <span class="n">y</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">center_x</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">center_y</span>
|
||||
<span class="n">x</span><span class="p">,</span> <span class="n">y</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_fix_orientation</span><span class="p">((</span><span class="n">x</span><span class="p">,</span> <span class="n">y</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">orientation</span> <span class="ow">in</span> <span class="p">[</span><span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">8</span><span class="p">]:</span>
|
||||
<span class="n">w</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">size_pixels</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">height</span>
|
||||
<span class="n">h</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">size_pixels</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">width</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="n">h</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">size_pixels</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">height</span>
|
||||
<span class="n">w</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">size_pixels</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">width</span>
|
||||
|
||||
<span class="k">return</span> <span class="n">MWG_RS_Area</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">h</span><span class="p">,</span> <span class="n">w</span><span class="p">)</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">mpri_reg_rect</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""Get coordinates for Microsoft Photo Region Rectangle.</span>
|
||||
|
||||
<span class="sd"> Returns:</span>
|
||||
<span class="sd"> MPRI_Reg_Rect named tuple with x, y, h, w where:</span>
|
||||
<span class="sd"> x = x coordinate of top left corner of rectangle</span>
|
||||
<span class="sd"> y = y coordinate of top left corner of rectangle</span>
|
||||
<span class="sd"> h = height of rectangle</span>
|
||||
<span class="sd"> w = width of rectangle</span>
|
||||
|
||||
<span class="sd"> Reference:</span>
|
||||
<span class="sd"> https://docs.microsoft.com/en-us/windows/win32/wic/-wic-people-tagging</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="n">x</span><span class="p">,</span> <span class="n">y</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">center_x</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">center_y</span>
|
||||
<span class="n">x</span><span class="p">,</span> <span class="n">y</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_fix_orientation</span><span class="p">((</span><span class="n">x</span><span class="p">,</span> <span class="n">y</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">orientation</span> <span class="ow">in</span> <span class="p">[</span><span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">8</span><span class="p">]:</span>
|
||||
<span class="n">w</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">size_pixels</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">width</span>
|
||||
<span class="n">h</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">size_pixels</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">height</span>
|
||||
<span class="n">x</span> <span class="o">=</span> <span class="n">x</span> <span class="o">-</span> <span class="bp">self</span><span class="o">.</span><span class="n">size_pixels</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">height</span> <span class="o">/</span> <span class="mi">2</span>
|
||||
<span class="n">y</span> <span class="o">=</span> <span class="n">y</span> <span class="o">-</span> <span class="bp">self</span><span class="o">.</span><span class="n">size_pixels</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">width</span> <span class="o">/</span> <span class="mi">2</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="n">h</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">size_pixels</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">width</span>
|
||||
<span class="n">w</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">size_pixels</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">height</span>
|
||||
<span class="n">x</span> <span class="o">=</span> <span class="n">x</span> <span class="o">-</span> <span class="bp">self</span><span class="o">.</span><span class="n">size_pixels</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">width</span> <span class="o">/</span> <span class="mi">2</span>
|
||||
<span class="n">y</span> <span class="o">=</span> <span class="n">y</span> <span class="o">-</span> <span class="bp">self</span><span class="o">.</span><span class="n">size_pixels</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">height</span> <span class="o">/</span> <span class="mi">2</span>
|
||||
|
||||
<span class="k">return</span> <span class="n">MPRI_Reg_Rect</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">h</span><span class="p">,</span> <span class="n">w</span><span class="p">)</span>
|
||||
|
||||
<span class="k">def</span> <span class="nf">face_rect</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""Get face rectangle coordinates for current version of the associated image</span>
|
||||
<span class="sd"> If image has been edited, rectangle applies to edited version, otherwise original version</span>
|
||||
<span class="sd"> Coordinates in format and reference frame used by PIL</span>
|
||||
|
||||
<span class="sd"> Returns:</span>
|
||||
<span class="sd"> list [(x0, x1), (y0, y1)] of coordinates in reference frame used by PIL</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="n">photo</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">photo</span>
|
||||
<span class="n">size_reference</span> <span class="o">=</span> <span class="n">photo</span><span class="o">.</span><span class="n">width</span> <span class="k">if</span> <span class="n">photo</span><span class="o">.</span><span class="n">width</span> <span class="o">></span> <span class="n">photo</span><span class="o">.</span><span class="n">height</span> <span class="k">else</span> <span class="n">photo</span><span class="o">.</span><span class="n">height</span>
|
||||
<span class="n">radius</span> <span class="o">=</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">size</span> <span class="o">/</span> <span class="mi">2</span><span class="p">)</span> <span class="o">*</span> <span class="n">size_reference</span>
|
||||
<span class="n">x</span><span class="p">,</span> <span class="n">y</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_make_point</span><span class="p">((</span><span class="bp">self</span><span class="o">.</span><span class="n">center_x</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">center_y</span><span class="p">))</span>
|
||||
<span class="n">x0</span><span class="p">,</span> <span class="n">y0</span> <span class="o">=</span> <span class="n">x</span> <span class="o">-</span> <span class="n">radius</span><span class="p">,</span> <span class="n">y</span> <span class="o">-</span> <span class="n">radius</span>
|
||||
<span class="n">x1</span><span class="p">,</span> <span class="n">y1</span> <span class="o">=</span> <span class="n">x</span> <span class="o">+</span> <span class="n">radius</span><span class="p">,</span> <span class="n">y</span> <span class="o">+</span> <span class="n">radius</span>
|
||||
<span class="k">return</span> <span class="p">[(</span><span class="n">x0</span><span class="p">,</span> <span class="n">y0</span><span class="p">),</span> <span class="p">(</span><span class="n">x1</span><span class="p">,</span> <span class="n">y1</span><span class="p">)]</span>
|
||||
|
||||
<span class="k">def</span> <span class="nf">roll_pitch_yaw</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""Roll, pitch, yaw of face in radians as tuple"""</span>
|
||||
<span class="n">info</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_info</span>
|
||||
<span class="n">roll</span> <span class="o">=</span> <span class="mi">0</span> <span class="k">if</span> <span class="n">info</span><span class="p">[</span><span class="s2">"roll"</span><span class="p">]</span> <span class="ow">is</span> <span class="kc">None</span> <span class="k">else</span> <span class="n">info</span><span class="p">[</span><span class="s2">"roll"</span><span class="p">]</span>
|
||||
<span class="n">pitch</span> <span class="o">=</span> <span class="mi">0</span> <span class="k">if</span> <span class="n">info</span><span class="p">[</span><span class="s2">"pitch"</span><span class="p">]</span> <span class="ow">is</span> <span class="kc">None</span> <span class="k">else</span> <span class="n">info</span><span class="p">[</span><span class="s2">"pitch"</span><span class="p">]</span>
|
||||
<span class="n">yaw</span> <span class="o">=</span> <span class="mi">0</span> <span class="k">if</span> <span class="n">info</span><span class="p">[</span><span class="s2">"yaw"</span><span class="p">]</span> <span class="ow">is</span> <span class="kc">None</span> <span class="k">else</span> <span class="n">info</span><span class="p">[</span><span class="s2">"yaw"</span><span class="p">]</span>
|
||||
|
||||
<span class="k">return</span> <span class="p">(</span><span class="n">roll</span><span class="p">,</span> <span class="n">pitch</span><span class="p">,</span> <span class="n">yaw</span><span class="p">)</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">roll</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""Return roll angle in radians of the face region"""</span>
|
||||
<span class="n">roll</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">roll_pitch_yaw</span><span class="p">()</span>
|
||||
<span class="k">return</span> <span class="n">roll</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">pitch</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""Return pitch angle in radians of the face region"""</span>
|
||||
<span class="n">_</span><span class="p">,</span> <span class="n">pitch</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">roll_pitch_yaw</span><span class="p">()</span>
|
||||
<span class="k">return</span> <span class="n">pitch</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">yaw</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""Return yaw angle in radians of the face region"""</span>
|
||||
<span class="n">_</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">yaw</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">roll_pitch_yaw</span><span class="p">()</span>
|
||||
<span class="k">return</span> <span class="n">yaw</span>
|
||||
|
||||
<span class="k">def</span> <span class="nf">_fix_orientation</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">xy</span><span class="p">):</span>
|
||||
<span class="sd">"""Translate an (x, y) tuple based on image orientation</span>
|
||||
|
||||
<span class="sd"> Arguments:</span>
|
||||
<span class="sd"> xy: tuple of (x, y) coordinates for point to translate</span>
|
||||
<span class="sd"> in format used by Photos (percent of height/width)</span>
|
||||
|
||||
<span class="sd"> Returns:</span>
|
||||
<span class="sd"> (x, y) tuple of translated coordinates</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="c1"># Reference: https://github.com/neilpa/phace/blob/7594776480505d0c389688a42099c94ac5d34f3f/cmd/phace/draw.go#L79-L94</span>
|
||||
|
||||
<span class="n">orientation</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">orientation</span>
|
||||
<span class="n">x</span><span class="p">,</span> <span class="n">y</span> <span class="o">=</span> <span class="n">xy</span>
|
||||
<span class="k">if</span> <span class="n">orientation</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
|
||||
<span class="n">y</span> <span class="o">=</span> <span class="mf">1.0</span> <span class="o">-</span> <span class="n">y</span>
|
||||
<span class="k">elif</span> <span class="n">orientation</span> <span class="o">==</span> <span class="mi">2</span><span class="p">:</span>
|
||||
<span class="n">y</span> <span class="o">=</span> <span class="mf">1.0</span> <span class="o">-</span> <span class="n">y</span>
|
||||
<span class="n">x</span> <span class="o">=</span> <span class="mf">1.0</span> <span class="o">-</span> <span class="n">x</span>
|
||||
<span class="k">elif</span> <span class="n">orientation</span> <span class="o">==</span> <span class="mi">3</span><span class="p">:</span>
|
||||
<span class="n">x</span> <span class="o">=</span> <span class="mf">1.0</span> <span class="o">-</span> <span class="n">x</span>
|
||||
<span class="k">elif</span> <span class="n">orientation</span> <span class="o">==</span> <span class="mi">4</span><span class="p">:</span>
|
||||
<span class="k">pass</span>
|
||||
<span class="k">elif</span> <span class="n">orientation</span> <span class="o">==</span> <span class="mi">5</span><span class="p">:</span>
|
||||
<span class="n">x</span><span class="p">,</span> <span class="n">y</span> <span class="o">=</span> <span class="mf">1.0</span> <span class="o">-</span> <span class="n">y</span><span class="p">,</span> <span class="n">x</span>
|
||||
<span class="k">elif</span> <span class="n">orientation</span> <span class="o">==</span> <span class="mi">6</span><span class="p">:</span>
|
||||
<span class="n">x</span><span class="p">,</span> <span class="n">y</span> <span class="o">=</span> <span class="mf">1.0</span> <span class="o">-</span> <span class="n">y</span><span class="p">,</span> <span class="mf">1.0</span> <span class="o">-</span> <span class="n">x</span>
|
||||
<span class="k">elif</span> <span class="n">orientation</span> <span class="o">==</span> <span class="mi">7</span><span class="p">:</span>
|
||||
<span class="n">x</span><span class="p">,</span> <span class="n">y</span> <span class="o">=</span> <span class="n">y</span><span class="p">,</span> <span class="n">x</span>
|
||||
<span class="n">y</span> <span class="o">=</span> <span class="mf">1.0</span> <span class="o">-</span> <span class="n">y</span>
|
||||
<span class="k">elif</span> <span class="n">orientation</span> <span class="o">==</span> <span class="mi">8</span><span class="p">:</span>
|
||||
<span class="n">x</span><span class="p">,</span> <span class="n">y</span> <span class="o">=</span> <span class="n">y</span><span class="p">,</span> <span class="n">x</span>
|
||||
<span class="k">elif</span> <span class="n">orientation</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
|
||||
<span class="c1"># set by osxphotos if adjusted orientation cannot be read, assume it's 1</span>
|
||||
<span class="n">y</span> <span class="o">=</span> <span class="mf">1.0</span> <span class="o">-</span> <span class="n">y</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="n">logging</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Unhandled orientation: </span><span class="si">{</span><span class="n">orientation</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
|
||||
|
||||
<span class="k">return</span> <span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">)</span>
|
||||
|
||||
<span class="k">def</span> <span class="nf">_make_point</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">xy</span><span class="p">):</span>
|
||||
<span class="sd">"""Translate an (x, y) tuple based on image orientation</span>
|
||||
<span class="sd"> and convert to image coordinates</span>
|
||||
|
||||
<span class="sd"> Arguments:</span>
|
||||
<span class="sd"> xy: tuple of (x, y) coordinates for point to translate</span>
|
||||
<span class="sd"> in format used by Photos (percent of height/width)</span>
|
||||
|
||||
<span class="sd"> Returns:</span>
|
||||
<span class="sd"> (x, y) tuple of translated coordinates in pixels in PIL format/reference frame</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="c1"># Reference: https://github.com/neilpa/phace/blob/7594776480505d0c389688a42099c94ac5d34f3f/cmd/phace/draw.go#L79-L94</span>
|
||||
|
||||
<span class="n">orientation</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">orientation</span>
|
||||
<span class="n">x</span><span class="p">,</span> <span class="n">y</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_fix_orientation</span><span class="p">(</span><span class="n">xy</span><span class="p">)</span>
|
||||
<span class="n">dx</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">width</span>
|
||||
<span class="n">dy</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">height</span>
|
||||
<span class="k">if</span> <span class="n">orientation</span> <span class="ow">in</span> <span class="p">[</span><span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">8</span><span class="p">]:</span>
|
||||
<span class="n">dx</span><span class="p">,</span> <span class="n">dy</span> <span class="o">=</span> <span class="n">dy</span><span class="p">,</span> <span class="n">dx</span>
|
||||
<span class="k">return</span> <span class="p">(</span><span class="nb">int</span><span class="p">(</span><span class="n">x</span> <span class="o">*</span> <span class="n">dx</span><span class="p">),</span> <span class="nb">int</span><span class="p">(</span><span class="n">y</span> <span class="o">*</span> <span class="n">dy</span><span class="p">))</span>
|
||||
|
||||
<span class="k">def</span> <span class="nf">_make_point_with_rotation</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">xy</span><span class="p">):</span>
|
||||
<span class="sd">"""Translate an (x, y) tuple based on image orientation and rotation</span>
|
||||
<span class="sd"> and convert to image coordinates</span>
|
||||
|
||||
<span class="sd"> Arguments:</span>
|
||||
<span class="sd"> xy: tuple of (x, y) coordinates for point to translate</span>
|
||||
<span class="sd"> in format used by Photos (percent of height/width)</span>
|
||||
|
||||
<span class="sd"> Returns:</span>
|
||||
<span class="sd"> (x, y) tuple of translated coordinates in pixels in PIL format/reference frame</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="c1"># convert to image coordinates</span>
|
||||
<span class="n">x</span><span class="p">,</span> <span class="n">y</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_make_point</span><span class="p">(</span><span class="n">xy</span><span class="p">)</span>
|
||||
|
||||
<span class="c1"># rotate about center</span>
|
||||
<span class="n">xmid</span><span class="p">,</span> <span class="n">ymid</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">center</span>
|
||||
<span class="n">roll</span><span class="p">,</span> <span class="n">_</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">roll_pitch_yaw</span><span class="p">()</span>
|
||||
<span class="n">xr</span><span class="p">,</span> <span class="n">yr</span> <span class="o">=</span> <span class="n">rotate_image_point</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">xmid</span><span class="p">,</span> <span class="n">ymid</span><span class="p">,</span> <span class="n">roll</span><span class="p">)</span>
|
||||
|
||||
<span class="k">return</span> <span class="p">(</span><span class="nb">int</span><span class="p">(</span><span class="n">xr</span><span class="p">),</span> <span class="nb">int</span><span class="p">(</span><span class="n">yr</span><span class="p">))</span>
|
||||
|
||||
<span class="k">def</span> <span class="nf">asdict</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""Returns dict representation of class instance"""</span>
|
||||
<span class="n">roll</span><span class="p">,</span> <span class="n">pitch</span><span class="p">,</span> <span class="n">yaw</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">roll_pitch_yaw</span><span class="p">()</span>
|
||||
<span class="k">return</span> <span class="p">{</span>
|
||||
<span class="s2">"_pk"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">_pk</span><span class="p">,</span>
|
||||
<span class="s2">"uuid"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">uuid</span><span class="p">,</span>
|
||||
<span class="s2">"name"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">,</span>
|
||||
<span class="s2">"asset_uuid"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">asset_uuid</span><span class="p">,</span>
|
||||
<span class="s2">"_person_pk"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">_person_pk</span><span class="p">,</span>
|
||||
<span class="s2">"center_x"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">center_x</span><span class="p">,</span>
|
||||
<span class="s2">"center_y"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">center_y</span><span class="p">,</span>
|
||||
<span class="s2">"center"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">center</span><span class="p">,</span>
|
||||
<span class="s2">"mouth_x"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">mouth_x</span><span class="p">,</span>
|
||||
<span class="s2">"mouth_y"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">mouth_y</span><span class="p">,</span>
|
||||
<span class="s2">"mouth"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">mouth</span><span class="p">,</span>
|
||||
<span class="s2">"left_eye_x"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">left_eye_x</span><span class="p">,</span>
|
||||
<span class="s2">"left_eye_y"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">left_eye_y</span><span class="p">,</span>
|
||||
<span class="s2">"left_eye"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">left_eye</span><span class="p">,</span>
|
||||
<span class="s2">"right_eye_x"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">right_eye_x</span><span class="p">,</span>
|
||||
<span class="s2">"right_eye_y"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">right_eye_y</span><span class="p">,</span>
|
||||
<span class="s2">"right_eye"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">right_eye</span><span class="p">,</span>
|
||||
<span class="s2">"size"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">size</span><span class="p">,</span>
|
||||
<span class="s2">"face_rect"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">face_rect</span><span class="p">(),</span>
|
||||
<span class="s2">"mpri_reg_rect"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">mpri_reg_rect</span><span class="o">.</span><span class="n">_asdict</span><span class="p">(),</span>
|
||||
<span class="s2">"mwg_rs_area"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">mwg_rs_area</span><span class="o">.</span><span class="n">_asdict</span><span class="p">(),</span>
|
||||
<span class="s2">"roll"</span><span class="p">:</span> <span class="n">roll</span><span class="p">,</span>
|
||||
<span class="s2">"pitch"</span><span class="p">:</span> <span class="n">pitch</span><span class="p">,</span>
|
||||
<span class="s2">"yaw"</span><span class="p">:</span> <span class="n">yaw</span><span class="p">,</span>
|
||||
<span class="s2">"quality"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">quality</span><span class="p">,</span>
|
||||
<span class="s2">"source_width"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">source_width</span><span class="p">,</span>
|
||||
<span class="s2">"source_height"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">source_height</span><span class="p">,</span>
|
||||
<span class="s2">"has_smile"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">has_smile</span><span class="p">,</span>
|
||||
<span class="s2">"left_eye_closed"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">left_eye_closed</span><span class="p">,</span>
|
||||
<span class="s2">"right_eye_closed"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">right_eye_closed</span><span class="p">,</span>
|
||||
<span class="s2">"manual"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">manual</span><span class="p">,</span>
|
||||
<span class="s2">"face_type"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">face_type</span><span class="p">,</span>
|
||||
<span class="s2">"age_type"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">age_type</span><span class="p">,</span>
|
||||
<span class="c1"># "bald_type": self.bald_type,</span>
|
||||
<span class="s2">"eye_makeup_type"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">eye_makeup_type</span><span class="p">,</span>
|
||||
<span class="s2">"eye_state"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">eye_state</span><span class="p">,</span>
|
||||
<span class="s2">"facial_hair_type"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">facial_hair_type</span><span class="p">,</span>
|
||||
<span class="s2">"gender_type"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">gender_type</span><span class="p">,</span>
|
||||
<span class="s2">"glasses_type"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">glasses_type</span><span class="p">,</span>
|
||||
<span class="s2">"hair_color_type"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">hair_color_type</span><span class="p">,</span>
|
||||
<span class="s2">"intrash"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">intrash</span><span class="p">,</span>
|
||||
<span class="s2">"lip_makeup_type"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">lip_makeup_type</span><span class="p">,</span>
|
||||
<span class="s2">"smile_type"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">smile_type</span><span class="p">,</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="k">def</span> <span class="nf">json</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""Return JSON representation of FaceInfo instance"""</span>
|
||||
<span class="k">return</span> <span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">asdict</span><span class="p">())</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="sa">f</span><span class="s2">"FaceInfo(uuid=</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">uuid</span><span class="si">}</span><span class="s2">, center_x=</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">center_x</span><span class="si">}</span><span class="s2">, center_y = </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">center_y</span><span class="si">}</span><span class="s2">, size=</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">size</span><span class="si">}</span><span class="s2">, person=</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="si">}</span><span class="s2">, asset_uuid=</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">asset_uuid</span><span class="si">}</span><span class="s2">)"</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="sa">f</span><span class="s2">"FaceInfo(db=</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="si">}</span><span class="s2">, pk=</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">_pk</span><span class="si">}</span><span class="s2">)"</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="nb">type</span><span class="p">(</span><span class="bp">self</span><span class="p">)):</span>
|
||||
<span class="k">return</span> <span class="kc">False</span>
|
||||
|
||||
<span class="k">return</span> <span class="nb">all</span><span class="p">(</span>
|
||||
<span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">field</span><span class="p">)</span> <span class="o">==</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="n">field</span><span class="p">)</span> <span class="k">for</span> <span class="n">field</span> <span class="ow">in</span> <span class="p">[</span><span class="s2">"_db"</span><span class="p">,</span> <span class="s2">"_pk"</span><span class="p">]</span>
|
||||
<span class="p">)</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__ne__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="fm">__eq__</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
|
||||
|
||||
|
||||
<span class="k">def</span> <span class="nf">rotate_image_point</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">xmid</span><span class="p">,</span> <span class="n">ymid</span><span class="p">,</span> <span class="n">angle</span><span class="p">):</span>
|
||||
<span class="sd">"""rotate image point about xm, ym by angle in radians</span>
|
||||
|
||||
<span class="sd"> Arguments:</span>
|
||||
<span class="sd"> x: x coordinate of point to rotate</span>
|
||||
<span class="sd"> y: y coordinate of point to rotate</span>
|
||||
<span class="sd"> xmid: x coordinate of center point to rotate about</span>
|
||||
<span class="sd"> ymid: y coordinate of center point to rotate about</span>
|
||||
<span class="sd"> angle: angle in radians about which to coordinate,</span>
|
||||
<span class="sd"> counter-clockwise is positive</span>
|
||||
|
||||
<span class="sd"> Returns:</span>
|
||||
<span class="sd"> tuple of rotated points (xr, yr)</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="c1"># translate point relative to the mid point</span>
|
||||
<span class="n">x</span> <span class="o">=</span> <span class="n">x</span> <span class="o">-</span> <span class="n">xmid</span>
|
||||
<span class="n">y</span> <span class="o">=</span> <span class="n">y</span> <span class="o">-</span> <span class="n">ymid</span>
|
||||
|
||||
<span class="c1"># rotate by angle and translate back</span>
|
||||
<span class="c1"># the photo coordinate system is downwards y is positive so</span>
|
||||
<span class="c1"># need to adjust the rotation accordingly</span>
|
||||
<span class="n">cos_angle</span> <span class="o">=</span> <span class="n">math</span><span class="o">.</span><span class="n">cos</span><span class="p">(</span><span class="n">angle</span><span class="p">)</span>
|
||||
<span class="n">sin_angle</span> <span class="o">=</span> <span class="n">math</span><span class="o">.</span><span class="n">sin</span><span class="p">(</span><span class="n">angle</span><span class="p">)</span>
|
||||
<span class="n">xr</span> <span class="o">=</span> <span class="n">x</span> <span class="o">*</span> <span class="n">cos_angle</span> <span class="o">+</span> <span class="n">y</span> <span class="o">*</span> <span class="n">sin_angle</span> <span class="o">+</span> <span class="n">xmid</span>
|
||||
<span class="n">yr</span> <span class="o">=</span> <span class="o">-</span><span class="n">x</span> <span class="o">*</span> <span class="n">sin_angle</span> <span class="o">+</span> <span class="n">y</span> <span class="o">*</span> <span class="n">cos_angle</span> <span class="o">+</span> <span class="n">ymid</span>
|
||||
|
||||
<span class="k">return</span> <span class="p">(</span><span class="n">xr</span><span class="p">,</span> <span class="n">yr</span><span class="p">)</span>
|
||||
</pre></div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||||
<div class="sphinxsidebarwrapper">
|
||||
<h1 class="logo"><a href="../../index.html">osxphotos</a></h1>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../overview.html">osxphotos</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../tutorial.html">Tutorial</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../cli.html">osxphotos command line interface (CLI)</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../reference.html">osxphotos package</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="relations">
|
||||
<h3>Related Topics</h3>
|
||||
<ul>
|
||||
<li><a href="../../index.html">Documentation overview</a><ul>
|
||||
<li><a href="../index.html">Module code</a><ul>
|
||||
</ul></li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="searchbox" style="display: none" role="search">
|
||||
<h3 id="searchlabel">Quick search</h3>
|
||||
<div class="searchformwrapper">
|
||||
<form class="search" action="../../search.html" method="get">
|
||||
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
|
||||
<input type="submit" value="Go" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<script>$('#searchbox').show(0);</script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
©2021, Rhet Turnbull.
|
||||
|
||||
|
|
||||
Powered by <a href="http://sphinx-doc.org/">Sphinx 4.4.0</a>
|
||||
& <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,195 +0,0 @@
|
||||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>osxphotos.photoinfo._photoinfo_exifinfo — osxphotos 0.41.4 documentation</title>
|
||||
<link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../../../_static/alabaster.css" type="text/css" />
|
||||
<script id="documentation_options" data-url_root="../../../" src="../../../_static/documentation_options.js"></script>
|
||||
<script src="../../../_static/jquery.js"></script>
|
||||
<script src="../../../_static/underscore.js"></script>
|
||||
<script src="../../../_static/doctools.js"></script>
|
||||
<link rel="index" title="Index" href="../../../genindex.html" />
|
||||
<link rel="search" title="Search" href="../../../search.html" />
|
||||
|
||||
<link rel="stylesheet" href="../../../_static/custom.css" type="text/css" />
|
||||
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
|
||||
|
||||
</head><body>
|
||||
|
||||
|
||||
<div class="document">
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
|
||||
|
||||
<div class="body" role="main">
|
||||
|
||||
<h1>Source code for osxphotos.photoinfo._photoinfo_exifinfo</h1><div class="highlight"><pre>
|
||||
<span></span><span class="sd">""" PhotoInfo methods to expose EXIF info from the library """</span>
|
||||
|
||||
<span class="kn">import</span> <span class="nn">logging</span>
|
||||
<span class="kn">from</span> <span class="nn">dataclasses</span> <span class="kn">import</span> <span class="n">dataclass</span>
|
||||
|
||||
<span class="kn">from</span> <span class="nn">.._constants</span> <span class="kn">import</span> <span class="n">_PHOTOS_4_VERSION</span>
|
||||
|
||||
|
||||
<span class="nd">@dataclass</span><span class="p">(</span><span class="n">frozen</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
|
||||
<span class="k">class</span> <span class="nc">ExifInfo</span><span class="p">:</span>
|
||||
<span class="sd">""" EXIF info associated with a photo from the Photos library """</span>
|
||||
|
||||
<span class="n">flash_fired</span><span class="p">:</span> <span class="nb">bool</span>
|
||||
<span class="n">iso</span><span class="p">:</span> <span class="nb">int</span>
|
||||
<span class="n">metering_mode</span><span class="p">:</span> <span class="nb">int</span>
|
||||
<span class="n">sample_rate</span><span class="p">:</span> <span class="nb">int</span>
|
||||
<span class="n">track_format</span><span class="p">:</span> <span class="nb">int</span>
|
||||
<span class="n">white_balance</span><span class="p">:</span> <span class="nb">int</span>
|
||||
<span class="n">aperture</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">bit_rate</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">duration</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">exposure_bias</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">focal_length</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">fps</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">latitude</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">longitude</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">shutter_speed</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">camera_make</span><span class="p">:</span> <span class="nb">str</span>
|
||||
<span class="n">camera_model</span><span class="p">:</span> <span class="nb">str</span>
|
||||
<span class="n">codec</span><span class="p">:</span> <span class="nb">str</span>
|
||||
<span class="n">lens_model</span><span class="p">:</span> <span class="nb">str</span>
|
||||
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">exif_info</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">""" Returns an ExifInfo object with the EXIF data for photo</span>
|
||||
<span class="sd"> Note: the returned EXIF data is the data Photos stores in the database on import;</span>
|
||||
<span class="sd"> ExifInfo does not provide access to the EXIF info in the actual image file</span>
|
||||
<span class="sd"> Some or all of the fields may be None</span>
|
||||
<span class="sd"> Only valid for Photos 5; on earlier database returns None</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_db_version</span> <span class="o"><=</span> <span class="n">_PHOTOS_4_VERSION</span><span class="p">:</span>
|
||||
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="sa">f</span><span class="s2">"exif_info not implemented for this database version"</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="kc">None</span>
|
||||
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="n">exif</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_db_exifinfo_uuid</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">uuid</span><span class="p">]</span>
|
||||
<span class="n">exif_info</span> <span class="o">=</span> <span class="n">ExifInfo</span><span class="p">(</span>
|
||||
<span class="n">iso</span><span class="o">=</span><span class="n">exif</span><span class="p">[</span><span class="s2">"ZISO"</span><span class="p">],</span>
|
||||
<span class="n">flash_fired</span><span class="o">=</span><span class="kc">True</span> <span class="k">if</span> <span class="n">exif</span><span class="p">[</span><span class="s2">"ZFLASHFIRED"</span><span class="p">]</span> <span class="o">==</span> <span class="mi">1</span> <span class="k">else</span> <span class="kc">False</span><span class="p">,</span>
|
||||
<span class="n">metering_mode</span><span class="o">=</span><span class="n">exif</span><span class="p">[</span><span class="s2">"ZMETERINGMODE"</span><span class="p">],</span>
|
||||
<span class="n">sample_rate</span><span class="o">=</span><span class="n">exif</span><span class="p">[</span><span class="s2">"ZSAMPLERATE"</span><span class="p">],</span>
|
||||
<span class="n">track_format</span><span class="o">=</span><span class="n">exif</span><span class="p">[</span><span class="s2">"ZTRACKFORMAT"</span><span class="p">],</span>
|
||||
<span class="n">white_balance</span><span class="o">=</span><span class="n">exif</span><span class="p">[</span><span class="s2">"ZWHITEBALANCE"</span><span class="p">],</span>
|
||||
<span class="n">aperture</span><span class="o">=</span><span class="n">exif</span><span class="p">[</span><span class="s2">"ZAPERTURE"</span><span class="p">],</span>
|
||||
<span class="n">bit_rate</span><span class="o">=</span><span class="n">exif</span><span class="p">[</span><span class="s2">"ZBITRATE"</span><span class="p">],</span>
|
||||
<span class="n">duration</span><span class="o">=</span><span class="n">exif</span><span class="p">[</span><span class="s2">"ZDURATION"</span><span class="p">],</span>
|
||||
<span class="n">exposure_bias</span><span class="o">=</span><span class="n">exif</span><span class="p">[</span><span class="s2">"ZEXPOSUREBIAS"</span><span class="p">],</span>
|
||||
<span class="n">focal_length</span><span class="o">=</span><span class="n">exif</span><span class="p">[</span><span class="s2">"ZFOCALLENGTH"</span><span class="p">],</span>
|
||||
<span class="n">fps</span><span class="o">=</span><span class="n">exif</span><span class="p">[</span><span class="s2">"ZFPS"</span><span class="p">],</span>
|
||||
<span class="n">latitude</span><span class="o">=</span><span class="n">exif</span><span class="p">[</span><span class="s2">"ZLATITUDE"</span><span class="p">],</span>
|
||||
<span class="n">longitude</span><span class="o">=</span><span class="n">exif</span><span class="p">[</span><span class="s2">"ZLONGITUDE"</span><span class="p">],</span>
|
||||
<span class="n">shutter_speed</span><span class="o">=</span><span class="n">exif</span><span class="p">[</span><span class="s2">"ZSHUTTERSPEED"</span><span class="p">],</span>
|
||||
<span class="n">camera_make</span><span class="o">=</span><span class="n">exif</span><span class="p">[</span><span class="s2">"ZCAMERAMAKE"</span><span class="p">],</span>
|
||||
<span class="n">camera_model</span><span class="o">=</span><span class="n">exif</span><span class="p">[</span><span class="s2">"ZCAMERAMODEL"</span><span class="p">],</span>
|
||||
<span class="n">codec</span><span class="o">=</span><span class="n">exif</span><span class="p">[</span><span class="s2">"ZCODEC"</span><span class="p">],</span>
|
||||
<span class="n">lens_model</span><span class="o">=</span><span class="n">exif</span><span class="p">[</span><span class="s2">"ZLENSMODEL"</span><span class="p">],</span>
|
||||
<span class="p">)</span>
|
||||
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
|
||||
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Could not find exif record for uuid </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">uuid</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
|
||||
<span class="n">exif_info</span> <span class="o">=</span> <span class="n">ExifInfo</span><span class="p">(</span>
|
||||
<span class="n">iso</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
|
||||
<span class="n">flash_fired</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
|
||||
<span class="n">metering_mode</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
|
||||
<span class="n">sample_rate</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
|
||||
<span class="n">track_format</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
|
||||
<span class="n">white_balance</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
|
||||
<span class="n">aperture</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
|
||||
<span class="n">bit_rate</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
|
||||
<span class="n">duration</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
|
||||
<span class="n">exposure_bias</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
|
||||
<span class="n">focal_length</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
|
||||
<span class="n">fps</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
|
||||
<span class="n">latitude</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
|
||||
<span class="n">longitude</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
|
||||
<span class="n">shutter_speed</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
|
||||
<span class="n">camera_make</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
|
||||
<span class="n">camera_model</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
|
||||
<span class="n">codec</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
|
||||
<span class="n">lens_model</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
|
||||
<span class="p">)</span>
|
||||
|
||||
<span class="k">return</span> <span class="n">exif_info</span>
|
||||
</pre></div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||||
<div class="sphinxsidebarwrapper">
|
||||
<h1 class="logo"><a href="../../../index.html">osxphotos</a></h1>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../../cli.html">osxphotos command line interface (CLI)</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../../reference.html">osxphotos package</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="relations">
|
||||
<h3>Related Topics</h3>
|
||||
<ul>
|
||||
<li><a href="../../../index.html">Documentation overview</a><ul>
|
||||
<li><a href="../../index.html">Module code</a><ul>
|
||||
</ul></li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="searchbox" style="display: none" role="search">
|
||||
<h3 id="searchlabel">Quick search</h3>
|
||||
<div class="searchformwrapper">
|
||||
<form class="search" action="../../../search.html" method="get">
|
||||
<input type="text" name="q" aria-labelledby="searchlabel" />
|
||||
<input type="submit" value="Go" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<script>$('#searchbox').show(0);</script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
©2021, Rhet Turnbull.
|
||||
|
||||
|
|
||||
Powered by <a href="http://sphinx-doc.org/">Sphinx 3.5.2</a>
|
||||
& <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,220 +0,0 @@
|
||||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>osxphotos.photoinfo._photoinfo_scoreinfo — osxphotos 0.41.4 documentation</title>
|
||||
<link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../../../_static/alabaster.css" type="text/css" />
|
||||
<script id="documentation_options" data-url_root="../../../" src="../../../_static/documentation_options.js"></script>
|
||||
<script src="../../../_static/jquery.js"></script>
|
||||
<script src="../../../_static/underscore.js"></script>
|
||||
<script src="../../../_static/doctools.js"></script>
|
||||
<link rel="index" title="Index" href="../../../genindex.html" />
|
||||
<link rel="search" title="Search" href="../../../search.html" />
|
||||
|
||||
<link rel="stylesheet" href="../../../_static/custom.css" type="text/css" />
|
||||
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
|
||||
|
||||
</head><body>
|
||||
|
||||
|
||||
<div class="document">
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
|
||||
|
||||
<div class="body" role="main">
|
||||
|
||||
<h1>Source code for osxphotos.photoinfo._photoinfo_scoreinfo</h1><div class="highlight"><pre>
|
||||
<span></span><span class="sd">""" PhotoInfo methods to expose computed score info from the library """</span>
|
||||
|
||||
<span class="kn">import</span> <span class="nn">logging</span>
|
||||
<span class="kn">from</span> <span class="nn">dataclasses</span> <span class="kn">import</span> <span class="n">dataclass</span>
|
||||
|
||||
<span class="kn">from</span> <span class="nn">.._constants</span> <span class="kn">import</span> <span class="n">_PHOTOS_4_VERSION</span>
|
||||
|
||||
|
||||
<span class="nd">@dataclass</span><span class="p">(</span><span class="n">frozen</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
|
||||
<span class="k">class</span> <span class="nc">ScoreInfo</span><span class="p">:</span>
|
||||
<span class="sd">""" Computed photo score info associated with a photo from the Photos library """</span>
|
||||
|
||||
<span class="n">overall</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">curation</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">promotion</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">highlight_visibility</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">behavioral</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">failure</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">harmonious_color</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">immersiveness</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">interaction</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">interesting_subject</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">intrusive_object_presence</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">lively_color</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">low_light</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">noise</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">pleasant_camera_tilt</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">pleasant_composition</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">pleasant_lighting</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">pleasant_pattern</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">pleasant_perspective</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">pleasant_post_processing</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">pleasant_reflection</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">pleasant_symmetry</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">sharply_focused_subject</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">tastefully_blurred</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">well_chosen_subject</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">well_framed_subject</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">well_timed_shot</span><span class="p">:</span> <span class="nb">float</span>
|
||||
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">score</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">""" Computed score information for a photo</span>
|
||||
|
||||
<span class="sd"> Returns:</span>
|
||||
<span class="sd"> ScoreInfo instance</span>
|
||||
<span class="sd"> """</span>
|
||||
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_db_version</span> <span class="o"><=</span> <span class="n">_PHOTOS_4_VERSION</span><span class="p">:</span>
|
||||
<span class="n">logging</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="sa">f</span><span class="s2">"score not implemented for this database version"</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="kc">None</span>
|
||||
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_scoreinfo</span> <span class="c1"># pylint: disable=access-member-before-definition</span>
|
||||
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="n">scores</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_db_scoreinfo_uuid</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">uuid</span><span class="p">]</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_scoreinfo</span> <span class="o">=</span> <span class="n">ScoreInfo</span><span class="p">(</span>
|
||||
<span class="n">overall</span><span class="o">=</span><span class="n">scores</span><span class="p">[</span><span class="s2">"overall_aesthetic"</span><span class="p">],</span>
|
||||
<span class="n">curation</span><span class="o">=</span><span class="n">scores</span><span class="p">[</span><span class="s2">"curation"</span><span class="p">],</span>
|
||||
<span class="n">promotion</span><span class="o">=</span><span class="n">scores</span><span class="p">[</span><span class="s2">"promotion"</span><span class="p">],</span>
|
||||
<span class="n">highlight_visibility</span><span class="o">=</span><span class="n">scores</span><span class="p">[</span><span class="s2">"highlight_visibility"</span><span class="p">],</span>
|
||||
<span class="n">behavioral</span><span class="o">=</span><span class="n">scores</span><span class="p">[</span><span class="s2">"behavioral"</span><span class="p">],</span>
|
||||
<span class="n">failure</span><span class="o">=</span><span class="n">scores</span><span class="p">[</span><span class="s2">"failure"</span><span class="p">],</span>
|
||||
<span class="n">harmonious_color</span><span class="o">=</span><span class="n">scores</span><span class="p">[</span><span class="s2">"harmonious_color"</span><span class="p">],</span>
|
||||
<span class="n">immersiveness</span><span class="o">=</span><span class="n">scores</span><span class="p">[</span><span class="s2">"immersiveness"</span><span class="p">],</span>
|
||||
<span class="n">interaction</span><span class="o">=</span><span class="n">scores</span><span class="p">[</span><span class="s2">"interaction"</span><span class="p">],</span>
|
||||
<span class="n">interesting_subject</span><span class="o">=</span><span class="n">scores</span><span class="p">[</span><span class="s2">"interesting_subject"</span><span class="p">],</span>
|
||||
<span class="n">intrusive_object_presence</span><span class="o">=</span><span class="n">scores</span><span class="p">[</span><span class="s2">"intrusive_object_presence"</span><span class="p">],</span>
|
||||
<span class="n">lively_color</span><span class="o">=</span><span class="n">scores</span><span class="p">[</span><span class="s2">"lively_color"</span><span class="p">],</span>
|
||||
<span class="n">low_light</span><span class="o">=</span><span class="n">scores</span><span class="p">[</span><span class="s2">"low_light"</span><span class="p">],</span>
|
||||
<span class="n">noise</span><span class="o">=</span><span class="n">scores</span><span class="p">[</span><span class="s2">"noise"</span><span class="p">],</span>
|
||||
<span class="n">pleasant_camera_tilt</span><span class="o">=</span><span class="n">scores</span><span class="p">[</span><span class="s2">"pleasant_camera_tilt"</span><span class="p">],</span>
|
||||
<span class="n">pleasant_composition</span><span class="o">=</span><span class="n">scores</span><span class="p">[</span><span class="s2">"pleasant_composition"</span><span class="p">],</span>
|
||||
<span class="n">pleasant_lighting</span><span class="o">=</span><span class="n">scores</span><span class="p">[</span><span class="s2">"pleasant_lighting"</span><span class="p">],</span>
|
||||
<span class="n">pleasant_pattern</span><span class="o">=</span><span class="n">scores</span><span class="p">[</span><span class="s2">"pleasant_pattern"</span><span class="p">],</span>
|
||||
<span class="n">pleasant_perspective</span><span class="o">=</span><span class="n">scores</span><span class="p">[</span><span class="s2">"pleasant_perspective"</span><span class="p">],</span>
|
||||
<span class="n">pleasant_post_processing</span><span class="o">=</span><span class="n">scores</span><span class="p">[</span><span class="s2">"pleasant_post_processing"</span><span class="p">],</span>
|
||||
<span class="n">pleasant_reflection</span><span class="o">=</span><span class="n">scores</span><span class="p">[</span><span class="s2">"pleasant_reflection"</span><span class="p">],</span>
|
||||
<span class="n">pleasant_symmetry</span><span class="o">=</span><span class="n">scores</span><span class="p">[</span><span class="s2">"pleasant_symmetry"</span><span class="p">],</span>
|
||||
<span class="n">sharply_focused_subject</span><span class="o">=</span><span class="n">scores</span><span class="p">[</span><span class="s2">"sharply_focused_subject"</span><span class="p">],</span>
|
||||
<span class="n">tastefully_blurred</span><span class="o">=</span><span class="n">scores</span><span class="p">[</span><span class="s2">"tastefully_blurred"</span><span class="p">],</span>
|
||||
<span class="n">well_chosen_subject</span><span class="o">=</span><span class="n">scores</span><span class="p">[</span><span class="s2">"well_chosen_subject"</span><span class="p">],</span>
|
||||
<span class="n">well_framed_subject</span><span class="o">=</span><span class="n">scores</span><span class="p">[</span><span class="s2">"well_framed_subject"</span><span class="p">],</span>
|
||||
<span class="n">well_timed_shot</span><span class="o">=</span><span class="n">scores</span><span class="p">[</span><span class="s2">"well_timed_shot"</span><span class="p">],</span>
|
||||
<span class="p">)</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_scoreinfo</span>
|
||||
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_scoreinfo</span> <span class="o">=</span> <span class="n">ScoreInfo</span><span class="p">(</span>
|
||||
<span class="n">overall</span><span class="o">=</span><span class="mf">0.0</span><span class="p">,</span>
|
||||
<span class="n">curation</span><span class="o">=</span><span class="mf">0.0</span><span class="p">,</span>
|
||||
<span class="n">promotion</span><span class="o">=</span><span class="mf">0.0</span><span class="p">,</span>
|
||||
<span class="n">highlight_visibility</span><span class="o">=</span><span class="mf">0.0</span><span class="p">,</span>
|
||||
<span class="n">behavioral</span><span class="o">=</span><span class="mf">0.0</span><span class="p">,</span>
|
||||
<span class="n">failure</span><span class="o">=</span><span class="mf">0.0</span><span class="p">,</span>
|
||||
<span class="n">harmonious_color</span><span class="o">=</span><span class="mf">0.0</span><span class="p">,</span>
|
||||
<span class="n">immersiveness</span><span class="o">=</span><span class="mf">0.0</span><span class="p">,</span>
|
||||
<span class="n">interaction</span><span class="o">=</span><span class="mf">0.0</span><span class="p">,</span>
|
||||
<span class="n">interesting_subject</span><span class="o">=</span><span class="mf">0.0</span><span class="p">,</span>
|
||||
<span class="n">intrusive_object_presence</span><span class="o">=</span><span class="mf">0.0</span><span class="p">,</span>
|
||||
<span class="n">lively_color</span><span class="o">=</span><span class="mf">0.0</span><span class="p">,</span>
|
||||
<span class="n">low_light</span><span class="o">=</span><span class="mf">0.0</span><span class="p">,</span>
|
||||
<span class="n">noise</span><span class="o">=</span><span class="mf">0.0</span><span class="p">,</span>
|
||||
<span class="n">pleasant_camera_tilt</span><span class="o">=</span><span class="mf">0.0</span><span class="p">,</span>
|
||||
<span class="n">pleasant_composition</span><span class="o">=</span><span class="mf">0.0</span><span class="p">,</span>
|
||||
<span class="n">pleasant_lighting</span><span class="o">=</span><span class="mf">0.0</span><span class="p">,</span>
|
||||
<span class="n">pleasant_pattern</span><span class="o">=</span><span class="mf">0.0</span><span class="p">,</span>
|
||||
<span class="n">pleasant_perspective</span><span class="o">=</span><span class="mf">0.0</span><span class="p">,</span>
|
||||
<span class="n">pleasant_post_processing</span><span class="o">=</span><span class="mf">0.0</span><span class="p">,</span>
|
||||
<span class="n">pleasant_reflection</span><span class="o">=</span><span class="mf">0.0</span><span class="p">,</span>
|
||||
<span class="n">pleasant_symmetry</span><span class="o">=</span><span class="mf">0.0</span><span class="p">,</span>
|
||||
<span class="n">sharply_focused_subject</span><span class="o">=</span><span class="mf">0.0</span><span class="p">,</span>
|
||||
<span class="n">tastefully_blurred</span><span class="o">=</span><span class="mf">0.0</span><span class="p">,</span>
|
||||
<span class="n">well_chosen_subject</span><span class="o">=</span><span class="mf">0.0</span><span class="p">,</span>
|
||||
<span class="n">well_framed_subject</span><span class="o">=</span><span class="mf">0.0</span><span class="p">,</span>
|
||||
<span class="n">well_timed_shot</span><span class="o">=</span><span class="mf">0.0</span><span class="p">,</span>
|
||||
<span class="p">)</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_scoreinfo</span>
|
||||
</pre></div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||||
<div class="sphinxsidebarwrapper">
|
||||
<h1 class="logo"><a href="../../../index.html">osxphotos</a></h1>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../../cli.html">osxphotos command line interface (CLI)</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../../reference.html">osxphotos package</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="relations">
|
||||
<h3>Related Topics</h3>
|
||||
<ul>
|
||||
<li><a href="../../../index.html">Documentation overview</a><ul>
|
||||
<li><a href="../../index.html">Module code</a><ul>
|
||||
</ul></li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="searchbox" style="display: none" role="search">
|
||||
<h3 id="searchlabel">Quick search</h3>
|
||||
<div class="searchformwrapper">
|
||||
<form class="search" action="../../../search.html" method="get">
|
||||
<input type="text" name="q" aria-labelledby="searchlabel" />
|
||||
<input type="submit" value="Go" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<script>$('#searchbox').show(0);</script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
©2021, Rhet Turnbull.
|
||||
|
||||
|
|
||||
Powered by <a href="http://sphinx-doc.org/">Sphinx 3.5.2</a>
|
||||
& <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,378 +0,0 @@
|
||||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>osxphotos.photoinfo._photoinfo_searchinfo — osxphotos 0.41.4 documentation</title>
|
||||
<link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../../../_static/alabaster.css" type="text/css" />
|
||||
<script id="documentation_options" data-url_root="../../../" src="../../../_static/documentation_options.js"></script>
|
||||
<script src="../../../_static/jquery.js"></script>
|
||||
<script src="../../../_static/underscore.js"></script>
|
||||
<script src="../../../_static/doctools.js"></script>
|
||||
<link rel="index" title="Index" href="../../../genindex.html" />
|
||||
<link rel="search" title="Search" href="../../../search.html" />
|
||||
|
||||
<link rel="stylesheet" href="../../../_static/custom.css" type="text/css" />
|
||||
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
|
||||
|
||||
</head><body>
|
||||
|
||||
|
||||
<div class="document">
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
|
||||
|
||||
<div class="body" role="main">
|
||||
|
||||
<h1>Source code for osxphotos.photoinfo._photoinfo_searchinfo</h1><div class="highlight"><pre>
|
||||
<span></span><span class="sd">""" Methods and class for PhotoInfo exposing SearchInfo data such as labels </span>
|
||||
<span class="sd"> Adds the following properties to PhotoInfo (valid only for Photos 5):</span>
|
||||
<span class="sd"> search_info: returns a SearchInfo object</span>
|
||||
<span class="sd"> search_info_normalized: returns a SearchInfo object with properties that produce normalized results</span>
|
||||
<span class="sd"> labels: returns list of labels</span>
|
||||
<span class="sd"> labels_normalized: returns list of normalized labels</span>
|
||||
<span class="sd">"""</span>
|
||||
|
||||
<span class="kn">from</span> <span class="nn">.._constants</span> <span class="kn">import</span> <span class="p">(</span>
|
||||
<span class="n">_PHOTOS_4_VERSION</span><span class="p">,</span>
|
||||
<span class="n">SEARCH_CATEGORY_CITY</span><span class="p">,</span>
|
||||
<span class="n">SEARCH_CATEGORY_LABEL</span><span class="p">,</span>
|
||||
<span class="n">SEARCH_CATEGORY_NEIGHBORHOOD</span><span class="p">,</span>
|
||||
<span class="n">SEARCH_CATEGORY_PLACE_NAME</span><span class="p">,</span>
|
||||
<span class="n">SEARCH_CATEGORY_STREET</span><span class="p">,</span>
|
||||
<span class="n">SEARCH_CATEGORY_ALL_LOCALITY</span><span class="p">,</span>
|
||||
<span class="n">SEARCH_CATEGORY_COUNTRY</span><span class="p">,</span>
|
||||
<span class="n">SEARCH_CATEGORY_STATE</span><span class="p">,</span>
|
||||
<span class="n">SEARCH_CATEGORY_STATE_ABBREVIATION</span><span class="p">,</span>
|
||||
<span class="n">SEARCH_CATEGORY_BODY_OF_WATER</span><span class="p">,</span>
|
||||
<span class="n">SEARCH_CATEGORY_MONTH</span><span class="p">,</span>
|
||||
<span class="n">SEARCH_CATEGORY_YEAR</span><span class="p">,</span>
|
||||
<span class="n">SEARCH_CATEGORY_HOLIDAY</span><span class="p">,</span>
|
||||
<span class="n">SEARCH_CATEGORY_ACTIVITY</span><span class="p">,</span>
|
||||
<span class="n">SEARCH_CATEGORY_SEASON</span><span class="p">,</span>
|
||||
<span class="n">SEARCH_CATEGORY_VENUE</span><span class="p">,</span>
|
||||
<span class="n">SEARCH_CATEGORY_VENUE_TYPE</span><span class="p">,</span>
|
||||
<span class="n">SEARCH_CATEGORY_MEDIA_TYPES</span><span class="p">,</span>
|
||||
<span class="p">)</span>
|
||||
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">search_info</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">""" returns SearchInfo object for photo </span>
|
||||
<span class="sd"> only valid on Photos 5, on older libraries, returns None</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_db_version</span> <span class="o"><=</span> <span class="n">_PHOTOS_4_VERSION</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="kc">None</span>
|
||||
|
||||
<span class="c1"># memoize SearchInfo object</span>
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_search_info</span>
|
||||
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_search_info</span> <span class="o">=</span> <span class="n">SearchInfo</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_search_info</span>
|
||||
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">search_info_normalized</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">""" returns SearchInfo object for photo that produces normalized results</span>
|
||||
<span class="sd"> only valid on Photos 5, on older libraries, returns None</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_db_version</span> <span class="o"><=</span> <span class="n">_PHOTOS_4_VERSION</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="kc">None</span>
|
||||
|
||||
<span class="c1"># memoize SearchInfo object</span>
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_search_info_normalized</span>
|
||||
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_search_info_normalized</span> <span class="o">=</span> <span class="n">SearchInfo</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">normalized</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_search_info_normalized</span>
|
||||
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">labels</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">""" returns list of labels applied to photo by Photos image categorization</span>
|
||||
<span class="sd"> only valid on Photos 5, on older libraries returns empty list </span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_db_version</span> <span class="o"><=</span> <span class="n">_PHOTOS_4_VERSION</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="p">[]</span>
|
||||
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">search_info</span><span class="o">.</span><span class="n">labels</span>
|
||||
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">labels_normalized</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">""" returns normalized list of labels applied to photo by Photos image categorization</span>
|
||||
<span class="sd"> only valid on Photos 5, on older libraries returns empty list </span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_db_version</span> <span class="o"><=</span> <span class="n">_PHOTOS_4_VERSION</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="p">[]</span>
|
||||
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">search_info_normalized</span><span class="o">.</span><span class="n">labels</span>
|
||||
|
||||
|
||||
<span class="k">class</span> <span class="nc">SearchInfo</span><span class="p">:</span>
|
||||
<span class="sd">""" Info about search terms such as machine learning labels that Photos knows about 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="n">normalized</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
|
||||
<span class="sd">""" photo: PhotoInfo object</span>
|
||||
<span class="sd"> normalized: if True, all properties return normalized (lower case) results """</span>
|
||||
|
||||
<span class="k">if</span> <span class="n">photo</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_db_version</span> <span class="o"><=</span> <span class="n">_PHOTOS_4_VERSION</span><span class="p">:</span>
|
||||
<span class="k">raise</span> <span class="ne">NotImplementedError</span><span class="p">(</span>
|
||||
<span class="sa">f</span><span class="s2">"search info not implemented for this database version"</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">_normalized</span> <span class="o">=</span> <span class="n">normalized</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">uuid</span> <span class="o">=</span> <span class="n">photo</span><span class="o">.</span><span class="n">uuid</span>
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="c1"># get search info for this UUID</span>
|
||||
<span class="c1"># there might not be any search info data (e.g. if Photo was missing or photoanalysisd not run yet)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_db_searchinfo</span> <span class="o">=</span> <span class="n">photo</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_db_searchinfo_uuid</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">uuid</span><span class="p">]</span>
|
||||
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_db_searchinfo</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">labels</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">""" return list of labels associated with Photo """</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_text_for_category</span><span class="p">(</span><span class="n">SEARCH_CATEGORY_LABEL</span><span class="p">)</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">place_names</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">""" returns list of place names """</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_text_for_category</span><span class="p">(</span><span class="n">SEARCH_CATEGORY_PLACE_NAME</span><span class="p">)</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">streets</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">""" returns list of street names """</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_text_for_category</span><span class="p">(</span><span class="n">SEARCH_CATEGORY_STREET</span><span class="p">)</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">neighborhoods</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">""" returns list of neighborhoods """</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_text_for_category</span><span class="p">(</span><span class="n">SEARCH_CATEGORY_NEIGHBORHOOD</span><span class="p">)</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">locality_names</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">""" returns list of other locality names """</span>
|
||||
<span class="n">locality</span> <span class="o">=</span> <span class="p">[]</span>
|
||||
<span class="k">for</span> <span class="n">category</span> <span class="ow">in</span> <span class="n">SEARCH_CATEGORY_ALL_LOCALITY</span><span class="p">:</span>
|
||||
<span class="n">locality</span> <span class="o">+=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_text_for_category</span><span class="p">(</span><span class="n">category</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="n">locality</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">city</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">""" returns city/town """</span>
|
||||
<span class="n">city</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_text_for_category</span><span class="p">(</span><span class="n">SEARCH_CATEGORY_CITY</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="n">city</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">if</span> <span class="n">city</span> <span class="k">else</span> <span class="s2">""</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">state</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">""" returns state name """</span>
|
||||
<span class="n">state</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_text_for_category</span><span class="p">(</span><span class="n">SEARCH_CATEGORY_STATE</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="n">state</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">if</span> <span class="n">state</span> <span class="k">else</span> <span class="s2">""</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">state_abbreviation</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">""" returns state abbreviation """</span>
|
||||
<span class="n">abbrev</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_text_for_category</span><span class="p">(</span><span class="n">SEARCH_CATEGORY_STATE_ABBREVIATION</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="n">abbrev</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">if</span> <span class="n">abbrev</span> <span class="k">else</span> <span class="s2">""</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">country</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">""" returns country name """</span>
|
||||
<span class="n">country</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_text_for_category</span><span class="p">(</span><span class="n">SEARCH_CATEGORY_COUNTRY</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="n">country</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">if</span> <span class="n">country</span> <span class="k">else</span> <span class="s2">""</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">month</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">""" returns month name """</span>
|
||||
<span class="n">month</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_text_for_category</span><span class="p">(</span><span class="n">SEARCH_CATEGORY_MONTH</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="n">month</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">if</span> <span class="n">month</span> <span class="k">else</span> <span class="s2">""</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">year</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">""" returns year """</span>
|
||||
<span class="n">year</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_text_for_category</span><span class="p">(</span><span class="n">SEARCH_CATEGORY_YEAR</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="n">year</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">if</span> <span class="n">year</span> <span class="k">else</span> <span class="s2">""</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">bodies_of_water</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">""" returns list of body of water names """</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_text_for_category</span><span class="p">(</span><span class="n">SEARCH_CATEGORY_BODY_OF_WATER</span><span class="p">)</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">holidays</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">""" returns list of holiday names """</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_text_for_category</span><span class="p">(</span><span class="n">SEARCH_CATEGORY_HOLIDAY</span><span class="p">)</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">activities</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">""" returns list of activity names """</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_text_for_category</span><span class="p">(</span><span class="n">SEARCH_CATEGORY_ACTIVITY</span><span class="p">)</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">season</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">""" returns season name """</span>
|
||||
<span class="n">season</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_text_for_category</span><span class="p">(</span><span class="n">SEARCH_CATEGORY_SEASON</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="n">season</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">if</span> <span class="n">season</span> <span class="k">else</span> <span class="s2">""</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">venues</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">""" returns list of venue names """</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_text_for_category</span><span class="p">(</span><span class="n">SEARCH_CATEGORY_VENUE</span><span class="p">)</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">venue_types</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">""" returns list of venue types """</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_text_for_category</span><span class="p">(</span><span class="n">SEARCH_CATEGORY_VENUE_TYPE</span><span class="p">)</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">media_types</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">""" returns list of media types (photo, video, panorama, etc) """</span>
|
||||
<span class="n">types</span> <span class="o">=</span> <span class="p">[]</span>
|
||||
<span class="k">for</span> <span class="n">category</span> <span class="ow">in</span> <span class="n">SEARCH_CATEGORY_MEDIA_TYPES</span><span class="p">:</span>
|
||||
<span class="n">types</span> <span class="o">+=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_text_for_category</span><span class="p">(</span><span class="n">category</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="n">types</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">all</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">""" return all search info properties in a single list """</span>
|
||||
<span class="nb">all</span> <span class="o">=</span> <span class="p">(</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">labels</span>
|
||||
<span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">place_names</span>
|
||||
<span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">streets</span>
|
||||
<span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">neighborhoods</span>
|
||||
<span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">locality_names</span>
|
||||
<span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">bodies_of_water</span>
|
||||
<span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">holidays</span>
|
||||
<span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">activities</span>
|
||||
<span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">venues</span>
|
||||
<span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">venue_types</span>
|
||||
<span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">media_types</span>
|
||||
<span class="p">)</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">city</span><span class="p">:</span>
|
||||
<span class="nb">all</span> <span class="o">+=</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">city</span><span class="p">]</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">state</span><span class="p">:</span>
|
||||
<span class="nb">all</span> <span class="o">+=</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">state</span><span class="p">]</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">state_abbreviation</span><span class="p">:</span>
|
||||
<span class="nb">all</span> <span class="o">+=</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">state_abbreviation</span><span class="p">]</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">country</span><span class="p">:</span>
|
||||
<span class="nb">all</span> <span class="o">+=</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">country</span><span class="p">]</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">month</span><span class="p">:</span>
|
||||
<span class="nb">all</span> <span class="o">+=</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">month</span><span class="p">]</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">year</span><span class="p">:</span>
|
||||
<span class="nb">all</span> <span class="o">+=</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">year</span><span class="p">]</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">season</span><span class="p">:</span>
|
||||
<span class="nb">all</span> <span class="o">+=</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">season</span><span class="p">]</span>
|
||||
|
||||
<span class="k">return</span> <span class="nb">all</span>
|
||||
|
||||
<span class="k">def</span> <span class="nf">asdict</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">""" return dict of search info """</span>
|
||||
<span class="k">return</span> <span class="p">{</span>
|
||||
<span class="s2">"labels"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">labels</span><span class="p">,</span>
|
||||
<span class="s2">"place_names"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">place_names</span><span class="p">,</span>
|
||||
<span class="s2">"streets"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">streets</span><span class="p">,</span>
|
||||
<span class="s2">"neighborhoods"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">neighborhoods</span><span class="p">,</span>
|
||||
<span class="s2">"city"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">city</span><span class="p">,</span>
|
||||
<span class="s2">"locality_names"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">locality_names</span><span class="p">,</span>
|
||||
<span class="s2">"state"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">state</span><span class="p">,</span>
|
||||
<span class="s2">"state_abbreviation"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">state_abbreviation</span><span class="p">,</span>
|
||||
<span class="s2">"country"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">country</span><span class="p">,</span>
|
||||
<span class="s2">"bodies_of_water"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">bodies_of_water</span><span class="p">,</span>
|
||||
<span class="s2">"month"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">month</span><span class="p">,</span>
|
||||
<span class="s2">"year"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">year</span><span class="p">,</span>
|
||||
<span class="s2">"holidays"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">holidays</span><span class="p">,</span>
|
||||
<span class="s2">"activities"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">activities</span><span class="p">,</span>
|
||||
<span class="s2">"season"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">season</span><span class="p">,</span>
|
||||
<span class="s2">"venues"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">venues</span><span class="p">,</span>
|
||||
<span class="s2">"venue_types"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">venue_types</span><span class="p">,</span>
|
||||
<span class="s2">"media_types"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">media_types</span><span class="p">,</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="k">def</span> <span class="nf">_get_text_for_category</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">category</span><span class="p">):</span>
|
||||
<span class="sd">""" return list of text for a specified category ID """</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db_searchinfo</span><span class="p">:</span>
|
||||
<span class="n">content</span> <span class="o">=</span> <span class="s2">"normalized_string"</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_normalized</span> <span class="k">else</span> <span class="s2">"content_string"</span>
|
||||
<span class="k">return</span> <span class="p">[</span>
|
||||
<span class="n">rec</span><span class="p">[</span><span class="n">content</span><span class="p">]</span>
|
||||
<span class="k">for</span> <span class="n">rec</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db_searchinfo</span>
|
||||
<span class="k">if</span> <span class="n">rec</span><span class="p">[</span><span class="s2">"category"</span><span class="p">]</span> <span class="o">==</span> <span class="n">category</span>
|
||||
<span class="p">]</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="p">[]</span>
|
||||
</pre></div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||||
<div class="sphinxsidebarwrapper">
|
||||
<h1 class="logo"><a href="../../../index.html">osxphotos</a></h1>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../../cli.html">osxphotos command line interface (CLI)</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../../reference.html">osxphotos package</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="relations">
|
||||
<h3>Related Topics</h3>
|
||||
<ul>
|
||||
<li><a href="../../../index.html">Documentation overview</a><ul>
|
||||
<li><a href="../../index.html">Module code</a><ul>
|
||||
</ul></li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="searchbox" style="display: none" role="search">
|
||||
<h3 id="searchlabel">Quick search</h3>
|
||||
<div class="searchformwrapper">
|
||||
<form class="search" action="../../../search.html" method="get">
|
||||
<input type="text" name="q" aria-labelledby="searchlabel" />
|
||||
<input type="submit" value="Go" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<script>$('#searchbox').show(0);</script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
©2021, Rhet Turnbull.
|
||||
|
||||
|
|
||||
Powered by <a href="http://sphinx-doc.org/">Sphinx 3.5.2</a>
|
||||
& <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,272 +0,0 @@
|
||||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>osxphotos.photosdb._photosdb_process_comments — osxphotos 0.47.9 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="../../../_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="../../../_static/alabaster.css" />
|
||||
<script data-url_root="../../../" id="documentation_options" src="../../../_static/documentation_options.js"></script>
|
||||
<script src="../../../_static/jquery.js"></script>
|
||||
<script src="../../../_static/underscore.js"></script>
|
||||
<script src="../../../_static/doctools.js"></script>
|
||||
<link rel="index" title="Index" href="../../../genindex.html" />
|
||||
<link rel="search" title="Search" href="../../../search.html" />
|
||||
|
||||
<link rel="stylesheet" href="../../../_static/custom.css" type="text/css" />
|
||||
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
|
||||
|
||||
</head><body>
|
||||
|
||||
|
||||
<div class="document">
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
|
||||
|
||||
<div class="body" role="main">
|
||||
|
||||
<h1>Source code for osxphotos.photosdb._photosdb_process_comments</h1><div class="highlight"><pre>
|
||||
<span></span><span class="sd">""" PhotosDB method for processing comments and likes on shared photos.</span>
|
||||
<span class="sd"> Do not import this module directly """</span>
|
||||
|
||||
<span class="kn">import</span> <span class="nn">dataclasses</span>
|
||||
<span class="kn">import</span> <span class="nn">datetime</span>
|
||||
<span class="kn">from</span> <span class="nn">dataclasses</span> <span class="kn">import</span> <span class="n">dataclass</span>
|
||||
|
||||
<span class="kn">from</span> <span class="nn">.._constants</span> <span class="kn">import</span> <span class="n">_DB_TABLE_NAMES</span><span class="p">,</span> <span class="n">_PHOTOS_4_VERSION</span><span class="p">,</span> <span class="n">TIME_DELTA</span>
|
||||
<span class="kn">from</span> <span class="nn">..utils</span> <span class="kn">import</span> <span class="n">_open_sql_file</span><span class="p">,</span> <span class="n">normalize_unicode</span>
|
||||
|
||||
|
||||
<span class="k">def</span> <span class="nf">_process_comments</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""load the comments and likes data from the database</span>
|
||||
<span class="sd"> this is a PhotosDB method that should be imported in</span>
|
||||
<span class="sd"> the PhotosDB class definition in photosdb.py</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_db_hashed_person_id</span> <span class="o">=</span> <span class="p">{}</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_db_comments_uuid</span> <span class="o">=</span> <span class="p">{}</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db_version</span> <span class="o"><=</span> <span class="n">_PHOTOS_4_VERSION</span><span class="p">:</span>
|
||||
<span class="n">_process_comments_4</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="n">_process_comments_5</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="CommentInfo"><a class="viewcode-back" href="../../../reference.html#osxphotos.CommentInfo">[docs]</a><span class="nd">@dataclass</span>
|
||||
<span class="k">class</span> <span class="nc">CommentInfo</span><span class="p">:</span>
|
||||
<span class="sd">"""Class for shared photo comments"""</span>
|
||||
|
||||
<span class="n">datetime</span><span class="p">:</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span>
|
||||
<span class="n">user</span><span class="p">:</span> <span class="nb">str</span>
|
||||
<span class="n">ismine</span><span class="p">:</span> <span class="nb">bool</span>
|
||||
<span class="n">text</span><span class="p">:</span> <span class="nb">str</span>
|
||||
|
||||
<span class="k">def</span> <span class="nf">asdict</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="n">dataclasses</span><span class="o">.</span><span class="n">asdict</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span></div>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="LikeInfo"><a class="viewcode-back" href="../../../reference.html#osxphotos.LikeInfo">[docs]</a><span class="nd">@dataclass</span>
|
||||
<span class="k">class</span> <span class="nc">LikeInfo</span><span class="p">:</span>
|
||||
<span class="sd">"""Class for shared photo likes"""</span>
|
||||
|
||||
<span class="n">datetime</span><span class="p">:</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span>
|
||||
<span class="n">user</span><span class="p">:</span> <span class="nb">str</span>
|
||||
<span class="n">ismine</span><span class="p">:</span> <span class="nb">bool</span>
|
||||
|
||||
<span class="k">def</span> <span class="nf">asdict</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="n">dataclasses</span><span class="o">.</span><span class="n">asdict</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span></div>
|
||||
|
||||
|
||||
<span class="c1"># The following methods do not get imported into PhotosDB</span>
|
||||
<span class="c1"># but will get called by _process_comments</span>
|
||||
<span class="k">def</span> <span class="nf">_process_comments_4</span><span class="p">(</span><span class="n">photosdb</span><span class="p">):</span>
|
||||
<span class="sd">"""process comments and likes info for Photos <= 4</span>
|
||||
<span class="sd"> photosdb: PhotosDB instance"""</span>
|
||||
<span class="k">raise</span> <span class="ne">NotImplementedError</span><span class="p">(</span>
|
||||
<span class="sa">f</span><span class="s2">"Not implemented for database version </span><span class="si">{</span><span class="n">photosdb</span><span class="o">.</span><span class="n">_db_version</span><span class="si">}</span><span class="s2">."</span>
|
||||
<span class="p">)</span>
|
||||
|
||||
|
||||
<span class="k">def</span> <span class="nf">_process_comments_5</span><span class="p">(</span><span class="n">photosdb</span><span class="p">):</span>
|
||||
<span class="sd">"""process comments and likes info for Photos >= 5</span>
|
||||
<span class="sd"> photosdb: PhotosDB instance"""</span>
|
||||
|
||||
<span class="n">db</span> <span class="o">=</span> <span class="n">photosdb</span><span class="o">.</span><span class="n">_tmp_db</span>
|
||||
|
||||
<span class="n">asset_table</span> <span class="o">=</span> <span class="n">_DB_TABLE_NAMES</span><span class="p">[</span><span class="n">photosdb</span><span class="o">.</span><span class="n">_photos_ver</span><span class="p">][</span><span class="s2">"ASSET"</span><span class="p">]</span>
|
||||
|
||||
<span class="p">(</span><span class="n">conn</span><span class="p">,</span> <span class="n">cursor</span><span class="p">)</span> <span class="o">=</span> <span class="n">_open_sql_file</span><span class="p">(</span><span class="n">db</span><span class="p">)</span>
|
||||
|
||||
<span class="n">results</span> <span class="o">=</span> <span class="n">conn</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="sd"> SELECT DISTINCT</span>
|
||||
<span class="sd"> ZINVITEEHASHEDPERSONID AS HASHEDPERSONID,</span>
|
||||
<span class="sd"> ZINVITEEFIRSTNAME AS FIRSTNAME,</span>
|
||||
<span class="sd"> ZINVITEELASTNAME AS LASTNAME,</span>
|
||||
<span class="sd"> ZINVITEEFULLNAME AS FULLNAME</span>
|
||||
<span class="sd"> FROM ZCLOUDSHAREDALBUMINVITATIONRECORD</span>
|
||||
<span class="sd"> WHERE HASHEDPERSONID IS NOT NULL</span>
|
||||
<span class="sd"> AND HASHEDPERSONID != ""</span>
|
||||
<span class="sd"> AND NOT (FIRSTNAME IS NULL AND LASTNAME IS NULL)</span>
|
||||
<span class="sd"> UNION</span>
|
||||
<span class="sd"> SELECT DISTINCT</span>
|
||||
<span class="sd"> ZCLOUDOWNERHASHEDPERSONID AS HASHEDPERSONID,</span>
|
||||
<span class="sd"> ZCLOUDOWNERFIRSTNAME AS FIRSTNAME,</span>
|
||||
<span class="sd"> ZCLOUDOWNERLASTNAME AS LASTNAME,</span>
|
||||
<span class="sd"> ZCLOUDOWNERFULLNAME AS FULLNAME</span>
|
||||
<span class="sd"> FROM ZGENERICALBUM</span>
|
||||
<span class="sd"> WHERE HASHEDPERSONID IS NOT NULL</span>
|
||||
<span class="sd"> AND HASHEDPERSONID != ""</span>
|
||||
<span class="sd"> AND NOT (FIRSTNAME IS NULL AND LASTNAME IS NULL)</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="p">)</span>
|
||||
|
||||
<span class="c1"># order of results</span>
|
||||
<span class="c1"># 0: ZINVITEEHASHEDPERSONID,</span>
|
||||
<span class="c1"># 1: ZINVITEEFIRSTNAME,</span>
|
||||
<span class="c1"># 2: ZINVITEELASTNAME,</span>
|
||||
<span class="c1"># 3: ZINVITEEFULLNAME</span>
|
||||
|
||||
<span class="n">photosdb</span><span class="o">.</span><span class="n">_db_hashed_person_id</span> <span class="o">=</span> <span class="p">{}</span>
|
||||
<span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">results</span><span class="o">.</span><span class="n">fetchall</span><span class="p">():</span>
|
||||
<span class="n">person_id</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
||||
<span class="n">photosdb</span><span class="o">.</span><span class="n">_db_hashed_person_id</span><span class="p">[</span><span class="n">person_id</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span>
|
||||
<span class="s2">"first_name"</span><span class="p">:</span> <span class="n">normalize_unicode</span><span class="p">(</span><span class="n">row</span><span class="p">[</span><span class="mi">1</span><span class="p">]),</span>
|
||||
<span class="s2">"last_name"</span><span class="p">:</span> <span class="n">normalize_unicode</span><span class="p">(</span><span class="n">row</span><span class="p">[</span><span class="mi">2</span><span class="p">]),</span>
|
||||
<span class="s2">"full_name"</span><span class="p">:</span> <span class="n">normalize_unicode</span><span class="p">(</span><span class="n">row</span><span class="p">[</span><span class="mi">3</span><span class="p">]),</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
<span class="n">results</span> <span class="o">=</span> <span class="n">conn</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span>
|
||||
<span class="sa">f</span><span class="s2">"""</span>
|
||||
<span class="s2"> SELECT </span>
|
||||
<span class="s2"> </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.ZUUID, -- UUID of the photo</span>
|
||||
<span class="s2"> ZCLOUDSHAREDCOMMENT.ZISLIKE, -- comment is actually a "like"</span>
|
||||
<span class="s2"> ZCLOUDSHAREDCOMMENT.ZCOMMENTDATE, -- date of comment</span>
|
||||
<span class="s2"> ZCLOUDSHAREDCOMMENT.ZCOMMENTTEXT, -- text of comment</span>
|
||||
<span class="s2"> ZCLOUDSHAREDCOMMENT.ZCOMMENTERHASHEDPERSONID, -- hashed ID of person who made comment/like</span>
|
||||
<span class="s2"> ZCLOUDSHAREDCOMMENT.ZISMYCOMMENT -- is my (this user's) comment</span>
|
||||
<span class="s2"> FROM ZCLOUDSHAREDCOMMENT</span>
|
||||
<span class="s2"> JOIN </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2"> ON</span>
|
||||
<span class="s2"> </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.Z_PK = ZCLOUDSHAREDCOMMENT.ZCOMMENTEDASSET</span>
|
||||
<span class="s2"> OR</span>
|
||||
<span class="s2"> </span><span class="si">{</span><span class="n">asset_table</span><span class="si">}</span><span class="s2">.Z_PK = ZCLOUDSHAREDCOMMENT.ZLIKEDASSET</span>
|
||||
<span class="s2"> """</span>
|
||||
<span class="p">)</span>
|
||||
|
||||
<span class="c1"># order of results</span>
|
||||
<span class="c1"># 0: ZGENERICASSET.ZUUID, -- UUID of the photo</span>
|
||||
<span class="c1"># 1: ZCLOUDSHAREDCOMMENT.ZISLIKE, -- comment is actually a "like"</span>
|
||||
<span class="c1"># 2: ZCLOUDSHAREDCOMMENT.ZCOMMENTDATE, -- date of comment</span>
|
||||
<span class="c1"># 3: ZCLOUDSHAREDCOMMENT.ZCOMMENTTEXT, -- text of comment</span>
|
||||
<span class="c1"># 4: ZCLOUDSHAREDCOMMENT.ZCOMMENTERHASHEDPERSONID, -- hashed ID of person who made comment/like</span>
|
||||
<span class="c1"># 5: ZCLOUDSHAREDCOMMENT.ZISMYCOMMENT -- is my (this user's) comment</span>
|
||||
|
||||
<span class="n">photosdb</span><span class="o">.</span><span class="n">_db_comments_uuid</span> <span class="o">=</span> <span class="p">{}</span>
|
||||
<span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">results</span><span class="p">:</span>
|
||||
<span class="n">uuid</span> <span class="o">=</span> <span class="n">row</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
||||
<span class="n">is_like</span> <span class="o">=</span> <span class="nb">bool</span><span class="p">(</span><span class="n">row</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
|
||||
<span class="n">text</span> <span class="o">=</span> <span class="n">normalize_unicode</span><span class="p">(</span><span class="n">row</span><span class="p">[</span><span class="mi">3</span><span class="p">])</span>
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="n">user_name</span> <span class="o">=</span> <span class="n">photosdb</span><span class="o">.</span><span class="n">_db_hashed_person_id</span><span class="p">[</span><span class="n">row</span><span class="p">[</span><span class="mi">4</span><span class="p">]][</span><span class="s2">"full_name"</span><span class="p">]</span>
|
||||
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
|
||||
<span class="n">user_name</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="n">dt</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">fromtimestamp</span><span class="p">(</span><span class="n">row</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="o">+</span> <span class="n">TIME_DELTA</span><span class="p">)</span>
|
||||
<span class="k">except</span><span class="p">:</span>
|
||||
<span class="n">dt</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="p">(</span><span class="mi">1970</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
|
||||
|
||||
<span class="n">ismine</span> <span class="o">=</span> <span class="nb">bool</span><span class="p">(</span><span class="n">row</span><span class="p">[</span><span class="mi">5</span><span class="p">])</span>
|
||||
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="n">db_comments</span> <span class="o">=</span> <span class="n">photosdb</span><span class="o">.</span><span class="n">_db_comments_uuid</span><span class="p">[</span><span class="n">uuid</span><span class="p">]</span>
|
||||
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
|
||||
<span class="n">photosdb</span><span class="o">.</span><span class="n">_db_comments_uuid</span><span class="p">[</span><span class="n">uuid</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="s2">"likes"</span><span class="p">:</span> <span class="p">[],</span> <span class="s2">"comments"</span><span class="p">:</span> <span class="p">[]}</span>
|
||||
<span class="n">db_comments</span> <span class="o">=</span> <span class="n">photosdb</span><span class="o">.</span><span class="n">_db_comments_uuid</span><span class="p">[</span><span class="n">uuid</span><span class="p">]</span>
|
||||
|
||||
<span class="k">if</span> <span class="n">is_like</span><span class="p">:</span>
|
||||
<span class="n">db_comments</span><span class="p">[</span><span class="s2">"likes"</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">LikeInfo</span><span class="p">(</span><span class="n">dt</span><span class="p">,</span> <span class="n">user_name</span><span class="p">,</span> <span class="n">ismine</span><span class="p">))</span>
|
||||
<span class="k">elif</span> <span class="n">text</span><span class="p">:</span>
|
||||
<span class="n">db_comments</span><span class="p">[</span><span class="s2">"comments"</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">CommentInfo</span><span class="p">(</span><span class="n">dt</span><span class="p">,</span> <span class="n">user_name</span><span class="p">,</span> <span class="n">ismine</span><span class="p">,</span> <span class="n">text</span><span class="p">))</span>
|
||||
|
||||
<span class="c1"># sort results</span>
|
||||
<span class="k">for</span> <span class="n">uuid</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">photosdb</span><span class="o">.</span><span class="n">_db_comments_uuid</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
|
||||
<span class="k">if</span> <span class="n">photosdb</span><span class="o">.</span><span class="n">_db_comments_uuid</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"likes"</span><span class="p">]:</span>
|
||||
<span class="n">photosdb</span><span class="o">.</span><span class="n">_db_comments_uuid</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"likes"</span><span class="p">]</span><span class="o">.</span><span class="n">sort</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">x</span><span class="p">:</span> <span class="n">x</span><span class="o">.</span><span class="n">datetime</span><span class="p">)</span>
|
||||
<span class="k">if</span> <span class="n">photosdb</span><span class="o">.</span><span class="n">_db_comments_uuid</span><span class="p">[</span><span class="n">uuid</span><span class="p">][</span><span class="s2">"comments"</span><span class="p">]:</span>
|
||||
<span class="n">value</span><span class="p">[</span><span class="s2">"comments"</span><span class="p">]</span><span class="o">.</span><span class="n">sort</span><span class="p">(</span><span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">x</span><span class="p">:</span> <span class="n">x</span><span class="o">.</span><span class="n">datetime</span><span class="p">)</span>
|
||||
|
||||
<span class="n">conn</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
|
||||
</pre></div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||||
<div class="sphinxsidebarwrapper">
|
||||
<h1 class="logo"><a href="../../../index.html">osxphotos</a></h1>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../../overview.html">osxphotos</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../../tutorial.html">Tutorial</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../../cli.html">osxphotos command line interface (CLI)</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../../reference.html">osxphotos package</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="relations">
|
||||
<h3>Related Topics</h3>
|
||||
<ul>
|
||||
<li><a href="../../../index.html">Documentation overview</a><ul>
|
||||
<li><a href="../../index.html">Module code</a><ul>
|
||||
</ul></li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="searchbox" style="display: none" role="search">
|
||||
<h3 id="searchlabel">Quick search</h3>
|
||||
<div class="searchformwrapper">
|
||||
<form class="search" action="../../../search.html" method="get">
|
||||
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
|
||||
<input type="submit" value="Go" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<script>$('#searchbox').show(0);</script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
©2021, Rhet Turnbull.
|
||||
|
||||
|
|
||||
Powered by <a href="http://sphinx-doc.org/">Sphinx 4.4.0</a>
|
||||
& <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,758 +0,0 @@
|
||||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>osxphotos.placeinfo — osxphotos 0.47.9 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="../../_static/alabaster.css" />
|
||||
<script data-url_root="../../" id="documentation_options" src="../../_static/documentation_options.js"></script>
|
||||
<script src="../../_static/jquery.js"></script>
|
||||
<script src="../../_static/underscore.js"></script>
|
||||
<script src="../../_static/doctools.js"></script>
|
||||
<link rel="index" title="Index" href="../../genindex.html" />
|
||||
<link rel="search" title="Search" href="../../search.html" />
|
||||
|
||||
<link rel="stylesheet" href="../../_static/custom.css" type="text/css" />
|
||||
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
|
||||
|
||||
</head><body>
|
||||
|
||||
|
||||
<div class="document">
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
|
||||
|
||||
<div class="body" role="main">
|
||||
|
||||
<h1>Source code for osxphotos.placeinfo</h1><div class="highlight"><pre>
|
||||
<span></span><span class="sd">""" </span>
|
||||
<span class="sd"> PlaceInfo class</span>
|
||||
<span class="sd"> Provides reverse geolocation info for photos </span>
|
||||
<span class="sd"> </span>
|
||||
<span class="sd"> See https://developer.apple.com/documentation/corelocation/clplacemark</span>
|
||||
<span class="sd"> for additional documentation on reverse geolocation data</span>
|
||||
<span class="sd">"""</span>
|
||||
<span class="kn">from</span> <span class="nn">abc</span> <span class="kn">import</span> <span class="n">ABC</span><span class="p">,</span> <span class="n">abstractmethod</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">import</span> <span class="nn">yaml</span>
|
||||
<span class="kn">from</span> <span class="nn">bpylist</span> <span class="kn">import</span> <span class="n">archiver</span>
|
||||
|
||||
<span class="kn">from</span> <span class="nn">._constants</span> <span class="kn">import</span> <span class="n">UNICODE_FORMAT</span>
|
||||
<span class="kn">from</span> <span class="nn">.utils</span> <span class="kn">import</span> <span class="n">normalize_unicode</span>
|
||||
|
||||
<span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span>
|
||||
<span class="s2">"PLRevGeoLocationInfo"</span><span class="p">,</span>
|
||||
<span class="s2">"PLRevGeoMapItem"</span><span class="p">,</span>
|
||||
<span class="s2">"PLRevGeoMapItemAdditionalPlaceInfo"</span><span class="p">,</span>
|
||||
<span class="s2">"CNPostalAddress"</span><span class="p">,</span>
|
||||
<span class="s2">"PlaceInfo"</span><span class="p">,</span>
|
||||
<span class="s2">"PlaceInfo4"</span><span class="p">,</span>
|
||||
<span class="s2">"PlaceInfo5"</span><span class="p">,</span>
|
||||
<span class="p">]</span>
|
||||
|
||||
<span class="c1"># postal address information, returned by PlaceInfo.address</span>
|
||||
<span class="n">PostalAddress</span> <span class="o">=</span> <span class="n">namedtuple</span><span class="p">(</span>
|
||||
<span class="s2">"PostalAddress"</span><span class="p">,</span>
|
||||
<span class="p">[</span>
|
||||
<span class="s2">"street"</span><span class="p">,</span>
|
||||
<span class="s2">"sub_locality"</span><span class="p">,</span>
|
||||
<span class="s2">"city"</span><span class="p">,</span>
|
||||
<span class="s2">"sub_administrative_area"</span><span class="p">,</span>
|
||||
<span class="s2">"state_province"</span><span class="p">,</span>
|
||||
<span class="s2">"postal_code"</span><span class="p">,</span>
|
||||
<span class="s2">"country"</span><span class="p">,</span>
|
||||
<span class="s2">"iso_country_code"</span><span class="p">,</span>
|
||||
<span class="p">],</span>
|
||||
<span class="p">)</span>
|
||||
|
||||
<span class="c1"># PlaceNames tuple returned by PlaceInfo.names</span>
|
||||
<span class="c1"># order of fields 0 - 17 is mapped to placeType value in</span>
|
||||
<span class="c1"># PLRevGeoLocationInfo.mapInfo.sortedPlaceInfos</span>
|
||||
<span class="c1"># field 18 is combined bodies of water (ocean + inland_water)</span>
|
||||
<span class="c1"># and maps to Photos <= 4, RKPlace.type == 44</span>
|
||||
<span class="c1"># (Photos <= 4 doesn't have ocean or inland_water types)</span>
|
||||
<span class="c1"># The fields named "field0", etc. appear to be unused</span>
|
||||
<span class="n">PlaceNames</span> <span class="o">=</span> <span class="n">namedtuple</span><span class="p">(</span>
|
||||
<span class="s2">"PlaceNames"</span><span class="p">,</span>
|
||||
<span class="p">[</span>
|
||||
<span class="s2">"field0"</span><span class="p">,</span>
|
||||
<span class="s2">"country"</span><span class="p">,</span> <span class="c1"># The name of the country associated with the placemark.</span>
|
||||
<span class="s2">"state_province"</span><span class="p">,</span> <span class="c1"># administrativeArea, The state or province associated with the placemark.</span>
|
||||
<span class="s2">"sub_administrative_area"</span><span class="p">,</span> <span class="c1"># Additional administrative area information for the placemark.</span>
|
||||
<span class="s2">"city"</span><span class="p">,</span> <span class="c1"># locality, The city associated with the placemark.</span>
|
||||
<span class="s2">"field5"</span><span class="p">,</span>
|
||||
<span class="s2">"additional_city_info"</span><span class="p">,</span> <span class="c1"># subLocality, Additional city-level information for the placemark.</span>
|
||||
<span class="s2">"ocean"</span><span class="p">,</span> <span class="c1"># The name of the ocean associated with the placemark.</span>
|
||||
<span class="s2">"area_of_interest"</span><span class="p">,</span> <span class="c1"># areasOfInterest, The relevant areas of interest associated with the placemark.</span>
|
||||
<span class="s2">"inland_water"</span><span class="p">,</span> <span class="c1"># The name of the inland water body associated with the placemark.</span>
|
||||
<span class="s2">"field10"</span><span class="p">,</span>
|
||||
<span class="s2">"region"</span><span class="p">,</span> <span class="c1"># The geographic region associated with the placemark.</span>
|
||||
<span class="s2">"sub_throughfare"</span><span class="p">,</span> <span class="c1"># Additional street-level information for the placemark.</span>
|
||||
<span class="s2">"field13"</span><span class="p">,</span>
|
||||
<span class="s2">"postal_code"</span><span class="p">,</span> <span class="c1"># The postal code associated with the placemark.</span>
|
||||
<span class="s2">"field15"</span><span class="p">,</span>
|
||||
<span class="s2">"field16"</span><span class="p">,</span>
|
||||
<span class="s2">"street_address"</span><span class="p">,</span> <span class="c1"># throughfare, The street address associated with the placemark.</span>
|
||||
<span class="s2">"body_of_water"</span><span class="p">,</span> <span class="c1"># RKPlace.type == 44, appears to be any body of water (ocean or inland)</span>
|
||||
<span class="p">],</span>
|
||||
<span class="p">)</span>
|
||||
|
||||
<span class="c1"># The following classes represent Photo Library Reverse Geolocation Info as stored</span>
|
||||
<span class="c1"># in ZADDITIONALASSETATTRIBUTES.ZREVERSELOCATIONDATA</span>
|
||||
<span class="c1"># These classes are used by bpylist.archiver to unarchive the serialized objects</span>
|
||||
<span class="k">class</span> <span class="nc">PLRevGeoLocationInfo</span><span class="p">:</span>
|
||||
<span class="sd">"""The top level reverse geolocation object"""</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">addressString</span><span class="p">,</span>
|
||||
<span class="n">countryCode</span><span class="p">,</span>
|
||||
<span class="n">mapItem</span><span class="p">,</span>
|
||||
<span class="n">isHome</span><span class="p">,</span>
|
||||
<span class="n">compoundNames</span><span class="p">,</span>
|
||||
<span class="n">compoundSecondaryNames</span><span class="p">,</span>
|
||||
<span class="n">version</span><span class="p">,</span>
|
||||
<span class="n">geoServiceProvider</span><span class="p">,</span>
|
||||
<span class="n">postalAddress</span><span class="p">,</span>
|
||||
<span class="p">):</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">addressString</span> <span class="o">=</span> <span class="n">normalize_unicode</span><span class="p">(</span><span class="n">addressString</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">countryCode</span> <span class="o">=</span> <span class="n">countryCode</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">mapItem</span> <span class="o">=</span> <span class="n">mapItem</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">isHome</span> <span class="o">=</span> <span class="n">isHome</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">compoundNames</span> <span class="o">=</span> <span class="n">normalize_unicode</span><span class="p">(</span><span class="n">compoundNames</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">compoundSecondaryNames</span> <span class="o">=</span> <span class="n">normalize_unicode</span><span class="p">(</span><span class="n">compoundSecondaryNames</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">version</span> <span class="o">=</span> <span class="n">version</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">geoServiceProvider</span> <span class="o">=</span> <span class="n">geoServiceProvider</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">postalAddress</span> <span class="o">=</span> <span class="n">postalAddress</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="nb">all</span><span class="p">(</span>
|
||||
<span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">field</span><span class="p">)</span> <span class="o">==</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="n">field</span><span class="p">)</span>
|
||||
<span class="k">for</span> <span class="n">field</span> <span class="ow">in</span> <span class="p">[</span>
|
||||
<span class="s2">"addressString"</span><span class="p">,</span>
|
||||
<span class="s2">"countryCode"</span><span class="p">,</span>
|
||||
<span class="s2">"isHome"</span><span class="p">,</span>
|
||||
<span class="s2">"compoundNames"</span><span class="p">,</span>
|
||||
<span class="s2">"compoundSecondaryNames"</span><span class="p">,</span>
|
||||
<span class="s2">"version"</span><span class="p">,</span>
|
||||
<span class="s2">"geoServiceProvider"</span><span class="p">,</span>
|
||||
<span class="s2">"postalAddress"</span><span class="p">,</span>
|
||||
<span class="p">]</span>
|
||||
<span class="p">)</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__ne__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="fm">__eq__</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="sa">f</span><span class="s2">"addressString: </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">addressString</span><span class="si">}</span><span class="s2">, countryCode: </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">countryCode</span><span class="si">}</span><span class="s2">, isHome: </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">isHome</span><span class="si">}</span><span class="s2">, mapItem: </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">mapItem</span><span class="si">}</span><span class="s2">, postalAddress: </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">postalAddress</span><span class="si">}</span><span class="s2">"</span>
|
||||
|
||||
<span class="nd">@staticmethod</span>
|
||||
<span class="k">def</span> <span class="nf">encode_archive</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">archive</span><span class="p">):</span>
|
||||
<span class="n">archive</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s2">"addressString"</span><span class="p">,</span> <span class="n">obj</span><span class="o">.</span><span class="n">addressString</span><span class="p">)</span>
|
||||
<span class="n">archive</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s2">"countryCode"</span><span class="p">,</span> <span class="n">obj</span><span class="o">.</span><span class="n">countryCode</span><span class="p">)</span>
|
||||
<span class="n">archive</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s2">"mapItem"</span><span class="p">,</span> <span class="n">obj</span><span class="o">.</span><span class="n">mapItem</span><span class="p">)</span>
|
||||
<span class="n">archive</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s2">"isHome"</span><span class="p">,</span> <span class="n">obj</span><span class="o">.</span><span class="n">isHome</span><span class="p">)</span>
|
||||
<span class="n">archive</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s2">"compoundNames"</span><span class="p">,</span> <span class="n">obj</span><span class="o">.</span><span class="n">compoundNames</span><span class="p">)</span>
|
||||
<span class="n">archive</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s2">"compoundSecondaryNames"</span><span class="p">,</span> <span class="n">obj</span><span class="o">.</span><span class="n">compoundSecondaryNames</span><span class="p">)</span>
|
||||
<span class="n">archive</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s2">"version"</span><span class="p">,</span> <span class="n">obj</span><span class="o">.</span><span class="n">version</span><span class="p">)</span>
|
||||
<span class="n">archive</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s2">"geoServiceProvider"</span><span class="p">,</span> <span class="n">obj</span><span class="o">.</span><span class="n">geoServiceProvider</span><span class="p">)</span>
|
||||
<span class="n">archive</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s2">"postalAddress"</span><span class="p">,</span> <span class="n">obj</span><span class="o">.</span><span class="n">postalAddress</span><span class="p">)</span>
|
||||
|
||||
<span class="nd">@staticmethod</span>
|
||||
<span class="k">def</span> <span class="nf">decode_archive</span><span class="p">(</span><span class="n">archive</span><span class="p">):</span>
|
||||
<span class="n">addressString</span> <span class="o">=</span> <span class="n">archive</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s2">"addressString"</span><span class="p">)</span>
|
||||
<span class="n">countryCode</span> <span class="o">=</span> <span class="n">archive</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s2">"countryCode"</span><span class="p">)</span>
|
||||
<span class="n">mapItem</span> <span class="o">=</span> <span class="n">archive</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s2">"mapItem"</span><span class="p">)</span>
|
||||
<span class="n">isHome</span> <span class="o">=</span> <span class="n">archive</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s2">"isHome"</span><span class="p">)</span>
|
||||
<span class="n">compoundNames</span> <span class="o">=</span> <span class="n">archive</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s2">"compoundNames"</span><span class="p">)</span>
|
||||
<span class="n">compoundSecondaryNames</span> <span class="o">=</span> <span class="n">archive</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s2">"compoundSecondaryNames"</span><span class="p">)</span>
|
||||
<span class="n">version</span> <span class="o">=</span> <span class="n">archive</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s2">"version"</span><span class="p">)</span>
|
||||
<span class="n">geoServiceProvider</span> <span class="o">=</span> <span class="n">archive</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s2">"geoServiceProvider"</span><span class="p">)</span>
|
||||
<span class="n">postalAddress</span> <span class="o">=</span> <span class="n">archive</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s2">"postalAddress"</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="n">PLRevGeoLocationInfo</span><span class="p">(</span>
|
||||
<span class="n">addressString</span><span class="p">,</span>
|
||||
<span class="n">countryCode</span><span class="p">,</span>
|
||||
<span class="n">mapItem</span><span class="p">,</span>
|
||||
<span class="n">isHome</span><span class="p">,</span>
|
||||
<span class="n">compoundNames</span><span class="p">,</span>
|
||||
<span class="n">compoundSecondaryNames</span><span class="p">,</span>
|
||||
<span class="n">version</span><span class="p">,</span>
|
||||
<span class="n">geoServiceProvider</span><span class="p">,</span>
|
||||
<span class="n">postalAddress</span><span class="p">,</span>
|
||||
<span class="p">)</span>
|
||||
|
||||
|
||||
<span class="k">class</span> <span class="nc">PLRevGeoMapItem</span><span class="p">:</span>
|
||||
<span class="sd">"""Stores the list of place names, organized by area"""</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">sortedPlaceInfos</span><span class="p">,</span> <span class="n">finalPlaceInfos</span><span class="p">):</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">sortedPlaceInfos</span> <span class="o">=</span> <span class="n">sortedPlaceInfos</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">finalPlaceInfos</span> <span class="o">=</span> <span class="n">finalPlaceInfos</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="nb">all</span><span class="p">(</span>
|
||||
<span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">field</span><span class="p">)</span> <span class="o">==</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="n">field</span><span class="p">)</span>
|
||||
<span class="k">for</span> <span class="n">field</span> <span class="ow">in</span> <span class="p">[</span><span class="s2">"sortedPlaceInfos"</span><span class="p">,</span> <span class="s2">"finalPlaceInfos"</span><span class="p">]</span>
|
||||
<span class="p">)</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__ne__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="fm">__eq__</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="n">sortedPlaceInfos</span> <span class="o">=</span> <span class="p">[</span><span class="nb">str</span><span class="p">(</span><span class="n">place</span><span class="p">)</span> <span class="k">for</span> <span class="n">place</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">sortedPlaceInfos</span><span class="p">]</span>
|
||||
<span class="n">finalPlaceInfos</span> <span class="o">=</span> <span class="p">[</span><span class="nb">str</span><span class="p">(</span><span class="n">place</span><span class="p">)</span> <span class="k">for</span> <span class="n">place</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">finalPlaceInfos</span><span class="p">]</span>
|
||||
<span class="k">return</span> <span class="p">(</span>
|
||||
<span class="sa">f</span><span class="s2">"finalPlaceInfos: </span><span class="si">{</span><span class="n">finalPlaceInfos</span><span class="si">}</span><span class="s2">, sortedPlaceInfos: </span><span class="si">{</span><span class="n">sortedPlaceInfos</span><span class="si">}</span><span class="s2">"</span>
|
||||
<span class="p">)</span>
|
||||
|
||||
<span class="nd">@staticmethod</span>
|
||||
<span class="k">def</span> <span class="nf">encode_archive</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">archive</span><span class="p">):</span>
|
||||
<span class="n">archive</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s2">"sortedPlaceInfos"</span><span class="p">,</span> <span class="n">obj</span><span class="o">.</span><span class="n">sortedPlaceInfos</span><span class="p">)</span>
|
||||
<span class="n">archive</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s2">"finalPlaceInfos"</span><span class="p">,</span> <span class="n">obj</span><span class="o">.</span><span class="n">finalPlaceInfos</span><span class="p">)</span>
|
||||
|
||||
<span class="nd">@staticmethod</span>
|
||||
<span class="k">def</span> <span class="nf">decode_archive</span><span class="p">(</span><span class="n">archive</span><span class="p">):</span>
|
||||
<span class="n">sortedPlaceInfos</span> <span class="o">=</span> <span class="n">archive</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s2">"sortedPlaceInfos"</span><span class="p">)</span>
|
||||
<span class="n">finalPlaceInfos</span> <span class="o">=</span> <span class="n">archive</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s2">"finalPlaceInfos"</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="n">PLRevGeoMapItem</span><span class="p">(</span><span class="n">sortedPlaceInfos</span><span class="p">,</span> <span class="n">finalPlaceInfos</span><span class="p">)</span>
|
||||
|
||||
|
||||
<span class="k">class</span> <span class="nc">PLRevGeoMapItemAdditionalPlaceInfo</span><span class="p">:</span>
|
||||
<span class="sd">"""Additional info about individual places"""</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">area</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">placeType</span><span class="p">,</span> <span class="n">dominantOrderType</span><span class="p">):</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">area</span> <span class="o">=</span> <span class="n">area</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">normalize_unicode</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">placeType</span> <span class="o">=</span> <span class="n">placeType</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">dominantOrderType</span> <span class="o">=</span> <span class="n">dominantOrderType</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="nb">all</span><span class="p">(</span>
|
||||
<span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">field</span><span class="p">)</span> <span class="o">==</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="n">field</span><span class="p">)</span>
|
||||
<span class="k">for</span> <span class="n">field</span> <span class="ow">in</span> <span class="p">[</span><span class="s2">"area"</span><span class="p">,</span> <span class="s2">"name"</span><span class="p">,</span> <span class="s2">"placeType"</span><span class="p">,</span> <span class="s2">"dominantOrderType"</span><span class="p">]</span>
|
||||
<span class="p">)</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__ne__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="fm">__eq__</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="sa">f</span><span class="s2">"area: </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">area</span><span class="si">}</span><span class="s2">, name: </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="si">}</span><span class="s2">, placeType: </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">placeType</span><span class="si">}</span><span class="s2">"</span>
|
||||
|
||||
<span class="nd">@staticmethod</span>
|
||||
<span class="k">def</span> <span class="nf">encode_archive</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">archive</span><span class="p">):</span>
|
||||
<span class="n">archive</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s2">"area"</span><span class="p">,</span> <span class="n">obj</span><span class="o">.</span><span class="n">area</span><span class="p">)</span>
|
||||
<span class="n">archive</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s2">"name"</span><span class="p">,</span> <span class="n">obj</span><span class="o">.</span><span class="n">name</span><span class="p">)</span>
|
||||
<span class="n">archive</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s2">"placeType"</span><span class="p">,</span> <span class="n">obj</span><span class="o">.</span><span class="n">placeType</span><span class="p">)</span>
|
||||
<span class="n">archive</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s2">"dominantOrderType"</span><span class="p">,</span> <span class="n">obj</span><span class="o">.</span><span class="n">dominantOrderType</span><span class="p">)</span>
|
||||
|
||||
<span class="nd">@staticmethod</span>
|
||||
<span class="k">def</span> <span class="nf">decode_archive</span><span class="p">(</span><span class="n">archive</span><span class="p">):</span>
|
||||
<span class="n">area</span> <span class="o">=</span> <span class="n">archive</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s2">"area"</span><span class="p">)</span>
|
||||
<span class="n">name</span> <span class="o">=</span> <span class="n">archive</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s2">"name"</span><span class="p">)</span>
|
||||
<span class="n">placeType</span> <span class="o">=</span> <span class="n">archive</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s2">"placeType"</span><span class="p">)</span>
|
||||
<span class="n">dominantOrderType</span> <span class="o">=</span> <span class="n">archive</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s2">"dominantOrderType"</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="n">PLRevGeoMapItemAdditionalPlaceInfo</span><span class="p">(</span>
|
||||
<span class="n">area</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">placeType</span><span class="p">,</span> <span class="n">dominantOrderType</span>
|
||||
<span class="p">)</span>
|
||||
|
||||
|
||||
<span class="k">class</span> <span class="nc">CNPostalAddress</span><span class="p">:</span>
|
||||
<span class="sd">"""postal address for the reverse geolocation info"""</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">_ISOCountryCode</span><span class="p">,</span>
|
||||
<span class="n">_city</span><span class="p">,</span>
|
||||
<span class="n">_country</span><span class="p">,</span>
|
||||
<span class="n">_postalCode</span><span class="p">,</span>
|
||||
<span class="n">_state</span><span class="p">,</span>
|
||||
<span class="n">_street</span><span class="p">,</span>
|
||||
<span class="n">_subAdministrativeArea</span><span class="p">,</span>
|
||||
<span class="n">_subLocality</span><span class="p">,</span>
|
||||
<span class="p">):</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_ISOCountryCode</span> <span class="o">=</span> <span class="n">_ISOCountryCode</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_city</span> <span class="o">=</span> <span class="n">normalize_unicode</span><span class="p">(</span><span class="n">_city</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_country</span> <span class="o">=</span> <span class="n">normalize_unicode</span><span class="p">(</span><span class="n">_country</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_postalCode</span> <span class="o">=</span> <span class="n">normalize_unicode</span><span class="p">(</span><span class="n">_postalCode</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_state</span> <span class="o">=</span> <span class="n">normalize_unicode</span><span class="p">(</span><span class="n">_state</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_street</span> <span class="o">=</span> <span class="n">normalize_unicode</span><span class="p">(</span><span class="n">_street</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_subAdministrativeArea</span> <span class="o">=</span> <span class="n">normalize_unicode</span><span class="p">(</span><span class="n">_subAdministrativeArea</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_subLocality</span> <span class="o">=</span> <span class="n">normalize_unicode</span><span class="p">(</span><span class="n">_subLocality</span><span class="p">)</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="nb">all</span><span class="p">(</span>
|
||||
<span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">field</span><span class="p">)</span> <span class="o">==</span> <span class="nb">getattr</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="n">field</span><span class="p">)</span>
|
||||
<span class="k">for</span> <span class="n">field</span> <span class="ow">in</span> <span class="p">[</span>
|
||||
<span class="s2">"_ISOCountryCode"</span><span class="p">,</span>
|
||||
<span class="s2">"_city"</span><span class="p">,</span>
|
||||
<span class="s2">"_country"</span><span class="p">,</span>
|
||||
<span class="s2">"_postalCode"</span><span class="p">,</span>
|
||||
<span class="s2">"_state"</span><span class="p">,</span>
|
||||
<span class="s2">"_street"</span><span class="p">,</span>
|
||||
<span class="s2">"_subAdministrativeArea"</span><span class="p">,</span>
|
||||
<span class="s2">"_subLocality"</span><span class="p">,</span>
|
||||
<span class="p">]</span>
|
||||
<span class="p">)</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__ne__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="fm">__eq__</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="s2">", "</span><span class="o">.</span><span class="n">join</span><span class="p">(</span>
|
||||
<span class="nb">map</span><span class="p">(</span>
|
||||
<span class="nb">str</span><span class="p">,</span>
|
||||
<span class="p">[</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_street</span><span class="p">,</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_city</span><span class="p">,</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_subLocality</span><span class="p">,</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_subAdministrativeArea</span><span class="p">,</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_state</span><span class="p">,</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_postalCode</span><span class="p">,</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_country</span><span class="p">,</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_ISOCountryCode</span><span class="p">,</span>
|
||||
<span class="p">],</span>
|
||||
<span class="p">)</span>
|
||||
<span class="p">)</span>
|
||||
|
||||
<span class="nd">@staticmethod</span>
|
||||
<span class="k">def</span> <span class="nf">encode_archive</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">archive</span><span class="p">):</span>
|
||||
<span class="n">archive</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s2">"_ISOCountryCode"</span><span class="p">,</span> <span class="n">obj</span><span class="o">.</span><span class="n">_ISOCountryCode</span><span class="p">)</span>
|
||||
<span class="n">archive</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s2">"_country"</span><span class="p">,</span> <span class="n">obj</span><span class="o">.</span><span class="n">_country</span><span class="p">)</span>
|
||||
<span class="n">archive</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s2">"_city"</span><span class="p">,</span> <span class="n">obj</span><span class="o">.</span><span class="n">_city</span><span class="p">)</span>
|
||||
<span class="n">archive</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s2">"_postalCode"</span><span class="p">,</span> <span class="n">obj</span><span class="o">.</span><span class="n">_postalCode</span><span class="p">)</span>
|
||||
<span class="n">archive</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s2">"_state"</span><span class="p">,</span> <span class="n">obj</span><span class="o">.</span><span class="n">_state</span><span class="p">)</span>
|
||||
<span class="n">archive</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s2">"_street"</span><span class="p">,</span> <span class="n">obj</span><span class="o">.</span><span class="n">_street</span><span class="p">)</span>
|
||||
<span class="n">archive</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s2">"_subAdministrativeArea"</span><span class="p">,</span> <span class="n">obj</span><span class="o">.</span><span class="n">_subAdministrativeArea</span><span class="p">)</span>
|
||||
<span class="n">archive</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s2">"_subLocality"</span><span class="p">,</span> <span class="n">obj</span><span class="o">.</span><span class="n">_subLocality</span><span class="p">)</span>
|
||||
|
||||
<span class="nd">@staticmethod</span>
|
||||
<span class="k">def</span> <span class="nf">decode_archive</span><span class="p">(</span><span class="n">archive</span><span class="p">):</span>
|
||||
<span class="n">_ISOCountryCode</span> <span class="o">=</span> <span class="n">archive</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s2">"_ISOCountryCode"</span><span class="p">)</span>
|
||||
<span class="n">_country</span> <span class="o">=</span> <span class="n">archive</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s2">"_country"</span><span class="p">)</span>
|
||||
<span class="n">_city</span> <span class="o">=</span> <span class="n">archive</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s2">"_city"</span><span class="p">)</span>
|
||||
<span class="n">_postalCode</span> <span class="o">=</span> <span class="n">archive</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s2">"_postalCode"</span><span class="p">)</span>
|
||||
<span class="n">_state</span> <span class="o">=</span> <span class="n">archive</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s2">"_state"</span><span class="p">)</span>
|
||||
<span class="n">_street</span> <span class="o">=</span> <span class="n">archive</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s2">"_street"</span><span class="p">)</span>
|
||||
<span class="n">_subAdministrativeArea</span> <span class="o">=</span> <span class="n">archive</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s2">"_subAdministrativeArea"</span><span class="p">)</span>
|
||||
<span class="n">_subLocality</span> <span class="o">=</span> <span class="n">archive</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s2">"_subLocality"</span><span class="p">)</span>
|
||||
|
||||
<span class="k">return</span> <span class="n">CNPostalAddress</span><span class="p">(</span>
|
||||
<span class="n">_ISOCountryCode</span><span class="p">,</span>
|
||||
<span class="n">_city</span><span class="p">,</span>
|
||||
<span class="n">_country</span><span class="p">,</span>
|
||||
<span class="n">_postalCode</span><span class="p">,</span>
|
||||
<span class="n">_state</span><span class="p">,</span>
|
||||
<span class="n">_street</span><span class="p">,</span>
|
||||
<span class="n">_subAdministrativeArea</span><span class="p">,</span>
|
||||
<span class="n">_subLocality</span><span class="p">,</span>
|
||||
<span class="p">)</span>
|
||||
|
||||
|
||||
<span class="c1"># register the classes with bpylist.archiver</span>
|
||||
<span class="n">archiver</span><span class="o">.</span><span class="n">update_class_map</span><span class="p">({</span><span class="s2">"CNPostalAddress"</span><span class="p">:</span> <span class="n">CNPostalAddress</span><span class="p">})</span>
|
||||
<span class="n">archiver</span><span class="o">.</span><span class="n">update_class_map</span><span class="p">(</span>
|
||||
<span class="p">{</span><span class="s2">"PLRevGeoMapItemAdditionalPlaceInfo"</span><span class="p">:</span> <span class="n">PLRevGeoMapItemAdditionalPlaceInfo</span><span class="p">}</span>
|
||||
<span class="p">)</span>
|
||||
<span class="n">archiver</span><span class="o">.</span><span class="n">update_class_map</span><span class="p">({</span><span class="s2">"PLRevGeoMapItem"</span><span class="p">:</span> <span class="n">PLRevGeoMapItem</span><span class="p">})</span>
|
||||
<span class="n">archiver</span><span class="o">.</span><span class="n">update_class_map</span><span class="p">({</span><span class="s2">"PLRevGeoLocationInfo"</span><span class="p">:</span> <span class="n">PLRevGeoLocationInfo</span><span class="p">})</span>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="PlaceInfo"><a class="viewcode-back" href="../../reference.html#osxphotos.PlaceInfo">[docs]</a><span class="k">class</span> <span class="nc">PlaceInfo</span><span class="p">(</span><span class="n">ABC</span><span class="p">):</span>
|
||||
<span class="nd">@property</span>
|
||||
<span class="nd">@abstractmethod</span>
|
||||
<span class="k">def</span> <span class="nf">address_str</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="k">pass</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="nd">@abstractmethod</span>
|
||||
<span class="k">def</span> <span class="nf">country_code</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="k">pass</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="nd">@abstractmethod</span>
|
||||
<span class="k">def</span> <span class="nf">ishome</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="k">pass</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="nd">@abstractmethod</span>
|
||||
<span class="k">def</span> <span class="nf">name</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="k">pass</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="nd">@abstractmethod</span>
|
||||
<span class="k">def</span> <span class="nf">names</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="k">pass</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="nd">@abstractmethod</span>
|
||||
<span class="k">def</span> <span class="nf">address</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="k">pass</span></div>
|
||||
|
||||
|
||||
<span class="k">class</span> <span class="nc">PlaceInfo4</span><span class="p">(</span><span class="n">PlaceInfo</span><span class="p">):</span>
|
||||
<span class="sd">"""Reverse geolocation place info for a photo (Photos <= 4)"""</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">place_names</span><span class="p">,</span> <span class="n">country_code</span><span class="p">):</span>
|
||||
<span class="sd">"""place_names: list of place name tuples in ascending order by area</span>
|
||||
<span class="sd"> tuple fields are: modelID, place name, place type, area, e.g.</span>
|
||||
<span class="sd"> [(5, "St James's Park", 45, 0),</span>
|
||||
<span class="sd"> (4, 'Westminster', 16, 22097376),</span>
|
||||
<span class="sd"> (3, 'London', 4, 1596146816),</span>
|
||||
<span class="sd"> (2, 'England', 2, 180406091776),</span>
|
||||
<span class="sd"> (1, 'United Kingdom', 1, 414681432064)]</span>
|
||||
<span class="sd"> country_code: two letter country code for the country</span>
|
||||
<span class="sd"> """</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_place_names</span> <span class="o">=</span> <span class="n">place_names</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_country_code</span> <span class="o">=</span> <span class="n">country_code</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_process_place_info</span><span class="p">()</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">address_str</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="kc">None</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">country_code</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_country_code</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">ishome</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="kc">None</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">name</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_name</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">names</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_names</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">address</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="n">PostalAddress</span><span class="p">(</span><span class="kc">None</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="nb">type</span><span class="p">(</span><span class="bp">self</span><span class="p">)):</span>
|
||||
<span class="k">return</span> <span class="kc">False</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="p">(</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_place_names</span> <span class="o">==</span> <span class="n">other</span><span class="o">.</span><span class="n">_place_names</span>
|
||||
<span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">_country_code</span> <span class="o">==</span> <span class="n">other</span><span class="o">.</span><span class="n">_country_code</span>
|
||||
<span class="p">)</span>
|
||||
|
||||
<span class="k">def</span> <span class="nf">_process_place_info</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""Process place_names to set self._name and self._names"""</span>
|
||||
<span class="n">places</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_place_names</span>
|
||||
|
||||
<span class="c1"># build a dictionary where key is placetype</span>
|
||||
<span class="n">places_dict</span> <span class="o">=</span> <span class="p">{}</span>
|
||||
<span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">places</span><span class="p">:</span>
|
||||
<span class="c1"># places in format:</span>
|
||||
<span class="c1"># [(5, "St James's Park", 45, 0), ]</span>
|
||||
<span class="c1"># 0: modelID</span>
|
||||
<span class="c1"># 1: name</span>
|
||||
<span class="c1"># 2: type</span>
|
||||
<span class="c1"># 3: area</span>
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="n">places_dict</span><span class="p">[</span><span class="n">p</span><span class="p">[</span><span class="mi">2</span><span class="p">]]</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">normalize_unicode</span><span class="p">(</span><span class="n">p</span><span class="p">[</span><span class="mi">1</span><span class="p">]),</span> <span class="n">p</span><span class="p">[</span><span class="mi">3</span><span class="p">]))</span>
|
||||
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
|
||||
<span class="n">places_dict</span><span class="p">[</span><span class="n">p</span><span class="p">[</span><span class="mi">2</span><span class="p">]]</span> <span class="o">=</span> <span class="p">[(</span><span class="n">normalize_unicode</span><span class="p">(</span><span class="n">p</span><span class="p">[</span><span class="mi">1</span><span class="p">]),</span> <span class="n">p</span><span class="p">[</span><span class="mi">3</span><span class="p">])]</span>
|
||||
|
||||
<span class="c1"># build list to populate PlaceNames tuple</span>
|
||||
<span class="c1"># initialize with empty lists for each field in PlaceNames</span>
|
||||
<span class="n">place_info</span> <span class="o">=</span> <span class="p">[[]]</span> <span class="o">*</span> <span class="mi">19</span>
|
||||
|
||||
<span class="c1"># add the place names sorted by area (ascending)</span>
|
||||
<span class="c1"># in Photos <=4, possible place type values are:</span>
|
||||
<span class="c1"># 45: areasOfInterest (The relevant areas of interest associated with the placemark.)</span>
|
||||
<span class="c1"># 44: body of water (includes both inlandWater and ocean)</span>
|
||||
<span class="c1"># 43: subLocality (Additional city-level information for the placemark.</span>
|
||||
<span class="c1"># 16: locality (The city associated with the placemark.)</span>
|
||||
<span class="c1"># 4: subAdministrativeArea (Additional administrative area information for the placemark.)</span>
|
||||
<span class="c1"># 2: administrativeArea (The state or province associated with the placemark.)</span>
|
||||
<span class="c1"># 1: country</span>
|
||||
<span class="c1"># mapping = mapping from PlaceNames to field in places_dict</span>
|
||||
<span class="c1"># PlaceNames fields map to the placeType value in Photos5 (0..17)</span>
|
||||
<span class="c1"># but place type in Photos <=4 has different values</span>
|
||||
<span class="c1"># hence (3, 4) means PlaceNames[3] = places_dict[4] (sub_administrative_area)</span>
|
||||
<span class="n">mapping</span> <span class="o">=</span> <span class="p">[(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">2</span><span class="p">),</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">),</span> <span class="p">(</span><span class="mi">4</span><span class="p">,</span> <span class="mi">16</span><span class="p">),</span> <span class="p">(</span><span class="mi">18</span><span class="p">,</span> <span class="mi">44</span><span class="p">),</span> <span class="p">(</span><span class="mi">8</span><span class="p">,</span> <span class="mi">45</span><span class="p">)]</span>
|
||||
<span class="k">for</span> <span class="n">field5</span><span class="p">,</span> <span class="n">field4</span> <span class="ow">in</span> <span class="n">mapping</span><span class="p">:</span>
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="n">place_info</span><span class="p">[</span><span class="n">field5</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span>
|
||||
<span class="n">p</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
||||
<span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">places_dict</span><span class="p">[</span><span class="n">field4</span><span class="p">],</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">place</span><span class="p">:</span> <span class="n">place</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
|
||||
<span class="p">]</span>
|
||||
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
|
||||
<span class="k">pass</span>
|
||||
|
||||
<span class="n">place_names</span> <span class="o">=</span> <span class="n">PlaceNames</span><span class="p">(</span><span class="o">*</span><span class="n">place_info</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_names</span> <span class="o">=</span> <span class="n">place_names</span>
|
||||
|
||||
<span class="c1"># build the name as it appears in Photos</span>
|
||||
<span class="c1"># the length of the name is at most 3 fields and appears to be based on available</span>
|
||||
<span class="c1"># reverse geolocation data in the following order (left to right, joined by ',')</span>
|
||||
<span class="c1"># always has country if available then either area of interest and city OR</span>
|
||||
<span class="c1"># city and state</span>
|
||||
<span class="c1"># e.g. 4, 2, 1 OR 8, 4, 1</span>
|
||||
<span class="c1"># 8 (45): area_of_interest</span>
|
||||
<span class="c1"># 4 (16): locality / city</span>
|
||||
<span class="c1"># 2 (2): administrative area (state/province)</span>
|
||||
<span class="c1"># 1 (1): country</span>
|
||||
<span class="n">name_list</span> <span class="o">=</span> <span class="p">[]</span>
|
||||
<span class="k">if</span> <span class="n">place_names</span><span class="p">[</span><span class="mi">8</span><span class="p">]:</span>
|
||||
<span class="n">name_list</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">place_names</span><span class="p">[</span><span class="mi">8</span><span class="p">][</span><span class="mi">0</span><span class="p">])</span>
|
||||
<span class="k">if</span> <span class="n">place_names</span><span class="p">[</span><span class="mi">4</span><span class="p">]:</span>
|
||||
<span class="n">name_list</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">place_names</span><span class="p">[</span><span class="mi">4</span><span class="p">][</span><span class="mi">0</span><span class="p">])</span>
|
||||
<span class="k">elif</span> <span class="n">place_names</span><span class="p">[</span><span class="mi">4</span><span class="p">]:</span>
|
||||
<span class="n">name_list</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">place_names</span><span class="p">[</span><span class="mi">4</span><span class="p">][</span><span class="mi">0</span><span class="p">])</span>
|
||||
<span class="k">if</span> <span class="n">place_names</span><span class="p">[</span><span class="mi">2</span><span class="p">]:</span>
|
||||
<span class="n">name_list</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">place_names</span><span class="p">[</span><span class="mi">2</span><span class="p">][</span><span class="mi">0</span><span class="p">])</span>
|
||||
<span class="k">elif</span> <span class="n">place_names</span><span class="p">[</span><span class="mi">2</span><span class="p">]:</span>
|
||||
<span class="n">name_list</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">place_names</span><span class="p">[</span><span class="mi">2</span><span class="p">][</span><span class="mi">0</span><span class="p">])</span>
|
||||
|
||||
<span class="c1"># add country</span>
|
||||
<span class="k">if</span> <span class="n">place_names</span><span class="p">[</span><span class="mi">1</span><span class="p">]:</span>
|
||||
<span class="n">name_list</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">place_names</span><span class="p">[</span><span class="mi">1</span><span class="p">][</span><span class="mi">0</span><span class="p">])</span>
|
||||
|
||||
<span class="n">name</span> <span class="o">=</span> <span class="s2">", "</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">name_list</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_name</span> <span class="o">=</span> <span class="n">name</span> <span class="k">if</span> <span class="n">name</span> <span class="o">!=</span> <span class="s2">""</span> <span class="k">else</span> <span class="kc">None</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__ne__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="fm">__eq__</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="n">info</span> <span class="o">=</span> <span class="p">{</span>
|
||||
<span class="s2">"name"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">,</span>
|
||||
<span class="s2">"names"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">names</span><span class="p">,</span>
|
||||
<span class="s2">"country_code"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">country_code</span><span class="p">,</span>
|
||||
<span class="p">}</span>
|
||||
<span class="k">return</span> <span class="s2">"PlaceInfo("</span> <span class="o">+</span> <span class="s2">", "</span><span class="o">.</span><span class="n">join</span><span class="p">([</span><span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">k</span><span class="si">}</span><span class="s2">='</span><span class="si">{</span><span class="n">v</span><span class="si">}</span><span class="s2">'"</span> <span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">info</span><span class="o">.</span><span class="n">items</span><span class="p">()])</span> <span class="o">+</span> <span class="s2">")"</span>
|
||||
|
||||
<span class="k">def</span> <span class="nf">asdict</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="p">{</span>
|
||||
<span class="s2">"name"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">,</span>
|
||||
<span class="s2">"names"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">names</span><span class="o">.</span><span class="n">_asdict</span><span class="p">(),</span>
|
||||
<span class="s2">"country_code"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">country_code</span><span class="p">,</span>
|
||||
<span class="p">}</span>
|
||||
|
||||
|
||||
<span class="k">class</span> <span class="nc">PlaceInfo5</span><span class="p">(</span><span class="n">PlaceInfo</span><span class="p">):</span>
|
||||
<span class="sd">"""Reverse geolocation place info for a photo (Photos >= 5)"""</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">revgeoloc_bplist</span><span class="p">):</span>
|
||||
<span class="sd">"""revgeoloc_bplist: a binary plist blob containing</span>
|
||||
<span class="sd"> a serialized PLRevGeoLocationInfo object"""</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_bplist</span> <span class="o">=</span> <span class="n">revgeoloc_bplist</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_plrevgeoloc</span> <span class="o">=</span> <span class="n">archiver</span><span class="o">.</span><span class="n">unarchive</span><span class="p">(</span><span class="n">revgeoloc_bplist</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_process_place_info</span><span class="p">()</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">address_str</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""returns the postal address as a string"""</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_plrevgeoloc</span><span class="o">.</span><span class="n">addressString</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">country_code</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""returns the country code"""</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_plrevgeoloc</span><span class="o">.</span><span class="n">countryCode</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">ishome</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""returns True if place is user's home address"""</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_plrevgeoloc</span><span class="o">.</span><span class="n">isHome</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">name</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""returns local place name"""</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_name</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">names</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""returns PlaceNames tuple with detailed reverse geolocation place names"""</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_names</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">address</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="n">addr</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_plrevgeoloc</span><span class="o">.</span><span class="n">postalAddress</span>
|
||||
<span class="k">if</span> <span class="n">addr</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
|
||||
<span class="n">postal_address</span> <span class="o">=</span> <span class="n">PostalAddress</span><span class="p">(</span>
|
||||
<span class="n">street</span><span class="o">=</span><span class="n">addr</span><span class="o">.</span><span class="n">_street</span><span class="p">,</span>
|
||||
<span class="n">sub_locality</span><span class="o">=</span><span class="n">addr</span><span class="o">.</span><span class="n">_subLocality</span><span class="p">,</span>
|
||||
<span class="n">city</span><span class="o">=</span><span class="n">addr</span><span class="o">.</span><span class="n">_city</span><span class="p">,</span>
|
||||
<span class="n">sub_administrative_area</span><span class="o">=</span><span class="n">addr</span><span class="o">.</span><span class="n">_subAdministrativeArea</span><span class="p">,</span>
|
||||
<span class="n">state_province</span><span class="o">=</span><span class="n">addr</span><span class="o">.</span><span class="n">_state</span><span class="p">,</span>
|
||||
<span class="n">postal_code</span><span class="o">=</span><span class="n">addr</span><span class="o">.</span><span class="n">_postalCode</span><span class="p">,</span>
|
||||
<span class="n">country</span><span class="o">=</span><span class="n">addr</span><span class="o">.</span><span class="n">_country</span><span class="p">,</span>
|
||||
<span class="n">iso_country_code</span><span class="o">=</span><span class="n">addr</span><span class="o">.</span><span class="n">_ISOCountryCode</span><span class="p">,</span>
|
||||
<span class="p">)</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="n">postal_address</span> <span class="o">=</span> <span class="n">PostalAddress</span><span class="p">(</span>
|
||||
<span class="kc">None</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="kc">None</span>
|
||||
<span class="p">)</span>
|
||||
|
||||
<span class="k">return</span> <span class="n">postal_address</span>
|
||||
|
||||
<span class="k">def</span> <span class="nf">_process_place_info</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""Process sortedPlaceInfos to set self._name and self._names"""</span>
|
||||
<span class="n">places</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_plrevgeoloc</span><span class="o">.</span><span class="n">mapItem</span><span class="o">.</span><span class="n">sortedPlaceInfos</span>
|
||||
|
||||
<span class="c1"># build a dictionary where key is placetype</span>
|
||||
<span class="n">places_dict</span> <span class="o">=</span> <span class="p">{}</span>
|
||||
<span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">places</span><span class="p">:</span>
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="n">places_dict</span><span class="p">[</span><span class="n">p</span><span class="o">.</span><span class="n">placeType</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">p</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="n">p</span><span class="o">.</span><span class="n">area</span><span class="p">))</span>
|
||||
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
|
||||
<span class="n">places_dict</span><span class="p">[</span><span class="n">p</span><span class="o">.</span><span class="n">placeType</span><span class="p">]</span> <span class="o">=</span> <span class="p">[(</span><span class="n">p</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="n">p</span><span class="o">.</span><span class="n">area</span><span class="p">)]</span>
|
||||
|
||||
<span class="c1"># build list to populate PlaceNames tuple</span>
|
||||
<span class="n">place_info</span> <span class="o">=</span> <span class="p">[]</span>
|
||||
<span class="k">for</span> <span class="n">field</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">18</span><span class="p">):</span>
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="c1"># add the place names sorted by area (ascending)</span>
|
||||
<span class="n">place_info</span><span class="o">.</span><span class="n">append</span><span class="p">(</span>
|
||||
<span class="p">[</span>
|
||||
<span class="n">p</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
||||
<span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">places_dict</span><span class="p">[</span><span class="n">field</span><span class="p">],</span> <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">place</span><span class="p">:</span> <span class="n">place</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span>
|
||||
<span class="p">]</span>
|
||||
<span class="p">)</span>
|
||||
<span class="k">except</span><span class="p">:</span>
|
||||
<span class="n">place_info</span><span class="o">.</span><span class="n">append</span><span class="p">([])</span>
|
||||
|
||||
<span class="c1"># fill in body_of_water for compatibility with Photos <= 4</span>
|
||||
<span class="n">place_info</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">place_info</span><span class="p">[</span><span class="mi">7</span><span class="p">]</span> <span class="o">+</span> <span class="n">place_info</span><span class="p">[</span><span class="mi">9</span><span class="p">])</span>
|
||||
|
||||
<span class="n">place_names</span> <span class="o">=</span> <span class="n">PlaceNames</span><span class="p">(</span><span class="o">*</span><span class="n">place_info</span><span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_names</span> <span class="o">=</span> <span class="n">place_names</span>
|
||||
|
||||
<span class="c1"># build the name as it appears in Photos</span>
|
||||
<span class="c1"># the length of the name is variable and appears to be based on available</span>
|
||||
<span class="c1"># reverse geolocation data in the following order (left to right, joined by ',')</span>
|
||||
<span class="c1"># 8: area_of_interest</span>
|
||||
<span class="c1"># 11: region (I've only seen this applied to islands)</span>
|
||||
<span class="c1"># 4: locality / city</span>
|
||||
<span class="c1"># 2: administrative area (state/province)</span>
|
||||
<span class="c1"># 1: country</span>
|
||||
<span class="c1"># 9: inland_water</span>
|
||||
<span class="c1"># 7: ocean</span>
|
||||
<span class="n">name</span> <span class="o">=</span> <span class="s2">", "</span><span class="o">.</span><span class="n">join</span><span class="p">(</span>
|
||||
<span class="p">[</span>
|
||||
<span class="n">p</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
||||
<span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="p">[</span>
|
||||
<span class="n">place_names</span><span class="p">[</span><span class="mi">8</span><span class="p">],</span> <span class="c1"># area of interest</span>
|
||||
<span class="n">place_names</span><span class="p">[</span><span class="mi">11</span><span class="p">],</span> <span class="c1"># region (I've only seen this applied to islands)</span>
|
||||
<span class="n">place_names</span><span class="p">[</span><span class="mi">4</span><span class="p">],</span> <span class="c1"># locality / city</span>
|
||||
<span class="n">place_names</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="c1"># administrative area (state/province)</span>
|
||||
<span class="n">place_names</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="c1"># country</span>
|
||||
<span class="n">place_names</span><span class="p">[</span><span class="mi">9</span><span class="p">],</span> <span class="c1"># inland_water</span>
|
||||
<span class="n">place_names</span><span class="p">[</span><span class="mi">7</span><span class="p">],</span> <span class="c1"># ocean</span>
|
||||
<span class="p">]</span>
|
||||
<span class="k">if</span> <span class="n">p</span> <span class="ow">and</span> <span class="n">p</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
|
||||
<span class="p">]</span>
|
||||
<span class="p">)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_name</span> <span class="o">=</span> <span class="n">name</span> <span class="k">if</span> <span class="n">name</span> <span class="o">!=</span> <span class="s2">""</span> <span class="k">else</span> <span class="kc">None</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
|
||||
<span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">other</span><span class="p">,</span> <span class="nb">type</span><span class="p">(</span><span class="bp">self</span><span class="p">)):</span>
|
||||
<span class="k">return</span> <span class="kc">False</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_plrevgeoloc</span> <span class="o">==</span> <span class="n">other</span><span class="o">.</span><span class="n">_plrevgeoloc</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__ne__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="fm">__eq__</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
|
||||
|
||||
<span class="k">def</span> <span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="n">info</span> <span class="o">=</span> <span class="p">{</span>
|
||||
<span class="s2">"name"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">,</span>
|
||||
<span class="s2">"names"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">names</span><span class="p">,</span>
|
||||
<span class="s2">"country_code"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">country_code</span><span class="p">,</span>
|
||||
<span class="s2">"ishome"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">ishome</span><span class="p">,</span>
|
||||
<span class="s2">"address_str"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">address_str</span><span class="p">,</span>
|
||||
<span class="s2">"address"</span><span class="p">:</span> <span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">address</span><span class="p">),</span>
|
||||
<span class="p">}</span>
|
||||
<span class="k">return</span> <span class="s2">"PlaceInfo("</span> <span class="o">+</span> <span class="s2">", "</span><span class="o">.</span><span class="n">join</span><span class="p">([</span><span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="n">k</span><span class="si">}</span><span class="s2">='</span><span class="si">{</span><span class="n">v</span><span class="si">}</span><span class="s2">'"</span> <span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">info</span><span class="o">.</span><span class="n">items</span><span class="p">()])</span> <span class="o">+</span> <span class="s2">")"</span>
|
||||
|
||||
<span class="k">def</span> <span class="nf">asdict</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="k">return</span> <span class="p">{</span>
|
||||
<span class="s2">"name"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">,</span>
|
||||
<span class="s2">"names"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">names</span><span class="o">.</span><span class="n">_asdict</span><span class="p">(),</span>
|
||||
<span class="s2">"country_code"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">country_code</span><span class="p">,</span>
|
||||
<span class="s2">"ishome"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">ishome</span><span class="p">,</span>
|
||||
<span class="s2">"address_str"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">address_str</span><span class="p">,</span>
|
||||
<span class="s2">"address"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">address</span><span class="o">.</span><span class="n">_asdict</span><span class="p">()</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">address</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="k">else</span> <span class="kc">None</span><span class="p">,</span>
|
||||
<span class="p">}</span>
|
||||
</pre></div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||||
<div class="sphinxsidebarwrapper">
|
||||
<h1 class="logo"><a href="../../index.html">osxphotos</a></h1>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../overview.html">osxphotos</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../tutorial.html">Tutorial</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../cli.html">osxphotos command line interface (CLI)</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../reference.html">osxphotos package</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="relations">
|
||||
<h3>Related Topics</h3>
|
||||
<ul>
|
||||
<li><a href="../../index.html">Documentation overview</a><ul>
|
||||
<li><a href="../index.html">Module code</a><ul>
|
||||
</ul></li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="searchbox" style="display: none" role="search">
|
||||
<h3 id="searchlabel">Quick search</h3>
|
||||
<div class="searchformwrapper">
|
||||
<form class="search" action="../../search.html" method="get">
|
||||
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
|
||||
<input type="submit" value="Go" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<script>$('#searchbox').show(0);</script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
©2021, Rhet Turnbull.
|
||||
|
||||
|
|
||||
Powered by <a href="http://sphinx-doc.org/">Sphinx 4.4.0</a>
|
||||
& <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,411 +0,0 @@
|
||||
<!doctype html>
|
||||
<html class="no-js">
|
||||
<head><meta charset="utf-8"/>
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1"/>
|
||||
<meta name="color-scheme" content="light dark"><link rel="index" title="Index" href="../../genindex.html" /><link rel="search" title="Search" href="../../search.html" />
|
||||
|
||||
<meta name="generator" content="sphinx-4.4.0, furo 2022.04.07"/>
|
||||
<title>osxphotos.queryoptions - osxphotos 0.47.9 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" />
|
||||
|
||||
|
||||
|
||||
|
||||
<style>
|
||||
body {
|
||||
--color-code-background: #f8f8f8;
|
||||
--color-code-foreground: black;
|
||||
|
||||
}
|
||||
@media not print {
|
||||
body[data-theme="dark"] {
|
||||
--color-code-background: #202020;
|
||||
--color-code-foreground: #d0d0d0;
|
||||
|
||||
}
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body:not([data-theme="light"]) {
|
||||
--color-code-background: #202020;
|
||||
--color-code-foreground: #d0d0d0;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</style></head>
|
||||
<body>
|
||||
|
||||
<script>
|
||||
document.body.dataset.theme = localStorage.getItem("theme") || "auto";
|
||||
</script>
|
||||
|
||||
|
||||
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
|
||||
<symbol id="svg-toc" viewBox="0 0 24 24">
|
||||
<title>Contents</title>
|
||||
<svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 1024 1024">
|
||||
<path d="M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM115.4 518.9L271.7 642c5.8 4.6 14.4.5 14.4-6.9V388.9c0-7.4-8.5-11.5-14.4-6.9L115.4 505.1a8.74 8.74 0 0 0 0 13.8z"/>
|
||||
</svg>
|
||||
</symbol>
|
||||
<symbol id="svg-menu" viewBox="0 0 24 24">
|
||||
<title>Menu</title>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather-menu">
|
||||
<line x1="3" y1="12" x2="21" y2="12"></line>
|
||||
<line x1="3" y1="6" x2="21" y2="6"></line>
|
||||
<line x1="3" y1="18" x2="21" y2="18"></line>
|
||||
</svg>
|
||||
</symbol>
|
||||
<symbol id="svg-arrow-right" viewBox="0 0 24 24">
|
||||
<title>Expand</title>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather-chevron-right">
|
||||
<polyline points="9 18 15 12 9 6"></polyline>
|
||||
</svg>
|
||||
</symbol>
|
||||
<symbol id="svg-sun" viewBox="0 0 24 24">
|
||||
<title>Light mode</title>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="feather-sun">
|
||||
<circle cx="12" cy="12" r="5"></circle>
|
||||
<line x1="12" y1="1" x2="12" y2="3"></line>
|
||||
<line x1="12" y1="21" x2="12" y2="23"></line>
|
||||
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
|
||||
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
|
||||
<line x1="1" y1="12" x2="3" y2="12"></line>
|
||||
<line x1="21" y1="12" x2="23" y2="12"></line>
|
||||
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
|
||||
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
|
||||
</svg>
|
||||
</symbol>
|
||||
<symbol id="svg-moon" viewBox="0 0 24 24">
|
||||
<title>Dark mode</title>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="icon-tabler-moon">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M12 3c.132 0 .263 0 .393 0a7.5 7.5 0 0 0 7.92 12.446a9 9 0 1 1 -8.313 -12.454z" />
|
||||
</svg>
|
||||
</symbol>
|
||||
<symbol id="svg-sun-half" viewBox="0 0 24 24">
|
||||
<title>Auto light/dark mode</title>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="icon-tabler-shadow">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"/>
|
||||
<circle cx="12" cy="12" r="9" />
|
||||
<path d="M13 12h5" />
|
||||
<path d="M13 15h4" />
|
||||
<path d="M13 18h1" />
|
||||
<path d="M13 9h4" />
|
||||
<path d="M13 6h1" />
|
||||
</svg>
|
||||
</symbol>
|
||||
</svg>
|
||||
|
||||
<input type="checkbox" class="sidebar-toggle" name="__navigation" id="__navigation">
|
||||
<input type="checkbox" class="sidebar-toggle" name="__toc" id="__toc">
|
||||
<label class="overlay sidebar-overlay" for="__navigation">
|
||||
<div class="visually-hidden">Hide navigation sidebar</div>
|
||||
</label>
|
||||
<label class="overlay toc-overlay" for="__toc">
|
||||
<div class="visually-hidden">Hide table of contents sidebar</div>
|
||||
</label>
|
||||
|
||||
|
||||
|
||||
<div class="page">
|
||||
<header class="mobile-header">
|
||||
<div class="header-left">
|
||||
<label class="nav-overlay-icon" for="__navigation">
|
||||
<div class="visually-hidden">Toggle site navigation sidebar</div>
|
||||
<i class="icon"><svg><use href="#svg-menu"></use></svg></i>
|
||||
</label>
|
||||
</div>
|
||||
<div class="header-center">
|
||||
<a href="../../index.html"><div class="brand">osxphotos 0.47.9 documentation</div></a>
|
||||
</div>
|
||||
<div class="header-right">
|
||||
<div class="theme-toggle-container theme-toggle-header">
|
||||
<button class="theme-toggle">
|
||||
<div class="visually-hidden">Toggle Light / Dark / Auto color theme</div>
|
||||
<svg class="theme-icon-when-auto"><use href="#svg-sun-half"></use></svg>
|
||||
<svg class="theme-icon-when-dark"><use href="#svg-moon"></use></svg>
|
||||
<svg class="theme-icon-when-light"><use href="#svg-sun"></use></svg>
|
||||
</button>
|
||||
</div>
|
||||
<label class="toc-overlay-icon toc-header-icon no-toc" for="__toc">
|
||||
<div class="visually-hidden">Toggle table of contents sidebar</div>
|
||||
<i class="icon"><svg><use href="#svg-toc"></use></svg></i>
|
||||
</label>
|
||||
</div>
|
||||
</header>
|
||||
<aside class="sidebar-drawer">
|
||||
<div class="sidebar-container">
|
||||
|
||||
<div class="sidebar-sticky"><a class="sidebar-brand" href="../../index.html">
|
||||
|
||||
|
||||
<span class="sidebar-brand-text">osxphotos 0.47.9 documentation</span>
|
||||
|
||||
</a><form class="sidebar-search-container" method="get" action="../../search.html" role="search">
|
||||
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
|
||||
<input type="hidden" name="check_keywords" value="yes">
|
||||
<input type="hidden" name="area" value="default">
|
||||
</form>
|
||||
<div id="searchbox"></div><div class="sidebar-scroll"><div class="sidebar-tree">
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../overview.html">osxphotos</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../tutorial.html">osxphotos Tutorial</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../cli.html">osxphotos Command Line Interface (CLI)</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../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>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</aside>
|
||||
<div class="main">
|
||||
<div class="content">
|
||||
<div class="article-container">
|
||||
<a href="#" class="back-to-top muted-link">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
|
||||
<path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8v12z"></path>
|
||||
</svg>
|
||||
<span>Back to top</span>
|
||||
</a>
|
||||
<div class="content-icon-container"><div class="theme-toggle-container theme-toggle-content">
|
||||
<button class="theme-toggle">
|
||||
<div class="visually-hidden">Toggle Light / Dark / Auto color theme</div>
|
||||
<svg class="theme-icon-when-auto"><use href="#svg-sun-half"></use></svg>
|
||||
<svg class="theme-icon-when-dark"><use href="#svg-moon"></use></svg>
|
||||
<svg class="theme-icon-when-light"><use href="#svg-sun"></use></svg>
|
||||
</button>
|
||||
</div>
|
||||
<label class="toc-overlay-icon toc-content-icon no-toc" for="__toc">
|
||||
<div class="visually-hidden">Toggle table of contents sidebar</div>
|
||||
<i class="icon"><svg><use href="#svg-toc"></use></svg></i>
|
||||
</label>
|
||||
</div>
|
||||
<article role="main">
|
||||
<h1>Source code for osxphotos.queryoptions</h1><div class="highlight"><pre>
|
||||
<span></span><span class="sd">""" QueryOptions class for PhotosDB.query """</span>
|
||||
|
||||
<span class="kn">import</span> <span class="nn">datetime</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>
|
||||
<span class="kn">from</span> <span class="nn">typing</span> <span class="kn">import</span> <span class="n">Iterable</span><span class="p">,</span> <span class="n">List</span><span class="p">,</span> <span class="n">Optional</span><span class="p">,</span> <span class="n">Tuple</span>
|
||||
|
||||
<span class="kn">import</span> <span class="nn">bitmath</span>
|
||||
|
||||
<span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"QueryOptions"</span><span class="p">]</span>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="QueryOptions"><a class="viewcode-back" href="../../reference.html#osxphotos.QueryOptions">[docs]</a><span class="nd">@dataclass</span>
|
||||
<span class="k">class</span> <span class="nc">QueryOptions</span><span class="p">:</span>
|
||||
|
||||
<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"> 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"> 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"> edited: search for edited photos</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"> 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"> 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"> 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">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">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">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">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">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">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">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>
|
||||
<span class="k">return</span> <span class="n">asdict</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span></div>
|
||||
</pre></div>
|
||||
</article>
|
||||
</div>
|
||||
<footer>
|
||||
|
||||
<div class="related-pages">
|
||||
|
||||
|
||||
</div>
|
||||
<div class="bottom-of-page">
|
||||
<div class="left-details">
|
||||
<div class="copyright">
|
||||
Copyright © 2021, Rhet Turnbull
|
||||
</div>
|
||||
Made with <a href="https://www.sphinx-doc.org/">Sphinx</a> and <a class="muted-link" href="https://pradyunsg.me">@pradyunsg</a>'s
|
||||
|
||||
<a href="https://github.com/pradyunsg/furo">Furo</a>
|
||||
|
||||
</div>
|
||||
<div class="right-details">
|
||||
<div class="icons">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</footer>
|
||||
</div>
|
||||
<aside class="toc-drawer no-toc">
|
||||
|
||||
|
||||
|
||||
</aside>
|
||||
</div>
|
||||
</div><script data-url_root="../../" id="documentation_options" src="../../_static/documentation_options.js"></script>
|
||||
<script src="../../_static/jquery.js"></script>
|
||||
<script src="../../_static/underscore.js"></script>
|
||||
<script src="../../_static/doctools.js"></script>
|
||||
<script src="../../_static/scripts/furo.js"></script>
|
||||
<script src="../../_static/clipboard.min.js"></script>
|
||||
<script src="../../_static/copybutton.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,143 +0,0 @@
|
||||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>osxphotos.scoreinfo — osxphotos 0.47.9 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="../../_static/alabaster.css" />
|
||||
<script data-url_root="../../" id="documentation_options" src="../../_static/documentation_options.js"></script>
|
||||
<script src="../../_static/jquery.js"></script>
|
||||
<script src="../../_static/underscore.js"></script>
|
||||
<script src="../../_static/doctools.js"></script>
|
||||
<link rel="index" title="Index" href="../../genindex.html" />
|
||||
<link rel="search" title="Search" href="../../search.html" />
|
||||
|
||||
<link rel="stylesheet" href="../../_static/custom.css" type="text/css" />
|
||||
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
|
||||
|
||||
</head><body>
|
||||
|
||||
|
||||
<div class="document">
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
|
||||
|
||||
<div class="body" role="main">
|
||||
|
||||
<h1>Source code for osxphotos.scoreinfo</h1><div class="highlight"><pre>
|
||||
<span></span><span class="sd">""" ScoreInfo class to expose computed score info from the library """</span>
|
||||
|
||||
<span class="kn">from</span> <span class="nn">dataclasses</span> <span class="kn">import</span> <span class="n">dataclass</span>
|
||||
|
||||
<span class="kn">from</span> <span class="nn">._constants</span> <span class="kn">import</span> <span class="n">_PHOTOS_4_VERSION</span>
|
||||
|
||||
<span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"ScoreInfo"</span><span class="p">]</span>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="ScoreInfo"><a class="viewcode-back" href="../../reference.html#osxphotos.ScoreInfo">[docs]</a><span class="nd">@dataclass</span><span class="p">(</span><span class="n">frozen</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
|
||||
<span class="k">class</span> <span class="nc">ScoreInfo</span><span class="p">:</span>
|
||||
<span class="sd">"""Computed photo score info associated with a photo from the Photos library"""</span>
|
||||
|
||||
<span class="n">overall</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">curation</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">promotion</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">highlight_visibility</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">behavioral</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">failure</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">harmonious_color</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">immersiveness</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">interaction</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">interesting_subject</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">intrusive_object_presence</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">lively_color</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">low_light</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">noise</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">pleasant_camera_tilt</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">pleasant_composition</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">pleasant_lighting</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">pleasant_pattern</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">pleasant_perspective</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">pleasant_post_processing</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">pleasant_reflection</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">pleasant_symmetry</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">sharply_focused_subject</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">tastefully_blurred</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">well_chosen_subject</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">well_framed_subject</span><span class="p">:</span> <span class="nb">float</span>
|
||||
<span class="n">well_timed_shot</span><span class="p">:</span> <span class="nb">float</span></div>
|
||||
</pre></div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||||
<div class="sphinxsidebarwrapper">
|
||||
<h1 class="logo"><a href="../../index.html">osxphotos</a></h1>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../overview.html">osxphotos</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../tutorial.html">Tutorial</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../cli.html">osxphotos command line interface (CLI)</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../reference.html">osxphotos package</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="relations">
|
||||
<h3>Related Topics</h3>
|
||||
<ul>
|
||||
<li><a href="../../index.html">Documentation overview</a><ul>
|
||||
<li><a href="../index.html">Module code</a><ul>
|
||||
</ul></li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="searchbox" style="display: none" role="search">
|
||||
<h3 id="searchlabel">Quick search</h3>
|
||||
<div class="searchformwrapper">
|
||||
<form class="search" action="../../search.html" method="get">
|
||||
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
|
||||
<input type="submit" value="Go" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<script>$('#searchbox').show(0);</script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
©2021, Rhet Turnbull.
|
||||
|
||||
|
|
||||
Powered by <a href="http://sphinx-doc.org/">Sphinx 4.4.0</a>
|
||||
& <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,325 +0,0 @@
|
||||
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>osxphotos.searchinfo — osxphotos 0.47.9 documentation</title>
|
||||
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css" />
|
||||
<link rel="stylesheet" type="text/css" href="../../_static/alabaster.css" />
|
||||
<script data-url_root="../../" id="documentation_options" src="../../_static/documentation_options.js"></script>
|
||||
<script src="../../_static/jquery.js"></script>
|
||||
<script src="../../_static/underscore.js"></script>
|
||||
<script src="../../_static/doctools.js"></script>
|
||||
<link rel="index" title="Index" href="../../genindex.html" />
|
||||
<link rel="search" title="Search" href="../../search.html" />
|
||||
|
||||
<link rel="stylesheet" href="../../_static/custom.css" type="text/css" />
|
||||
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
|
||||
|
||||
</head><body>
|
||||
|
||||
|
||||
<div class="document">
|
||||
<div class="documentwrapper">
|
||||
<div class="bodywrapper">
|
||||
|
||||
|
||||
<div class="body" role="main">
|
||||
|
||||
<h1>Source code for osxphotos.searchinfo</h1><div class="highlight"><pre>
|
||||
<span></span><span class="sd">""" class for PhotoInfo exposing SearchInfo data such as labels </span>
|
||||
<span class="sd">"""</span>
|
||||
|
||||
<span class="kn">from</span> <span class="nn">._constants</span> <span class="kn">import</span> <span class="p">(</span>
|
||||
<span class="n">_PHOTOS_4_VERSION</span><span class="p">,</span>
|
||||
<span class="n">SEARCH_CATEGORY_ACTIVITY</span><span class="p">,</span>
|
||||
<span class="n">SEARCH_CATEGORY_ALL_LOCALITY</span><span class="p">,</span>
|
||||
<span class="n">SEARCH_CATEGORY_BODY_OF_WATER</span><span class="p">,</span>
|
||||
<span class="n">SEARCH_CATEGORY_CITY</span><span class="p">,</span>
|
||||
<span class="n">SEARCH_CATEGORY_COUNTRY</span><span class="p">,</span>
|
||||
<span class="n">SEARCH_CATEGORY_HOLIDAY</span><span class="p">,</span>
|
||||
<span class="n">SEARCH_CATEGORY_LABEL</span><span class="p">,</span>
|
||||
<span class="n">SEARCH_CATEGORY_MEDIA_TYPES</span><span class="p">,</span>
|
||||
<span class="n">SEARCH_CATEGORY_MONTH</span><span class="p">,</span>
|
||||
<span class="n">SEARCH_CATEGORY_NEIGHBORHOOD</span><span class="p">,</span>
|
||||
<span class="n">SEARCH_CATEGORY_PLACE_NAME</span><span class="p">,</span>
|
||||
<span class="n">SEARCH_CATEGORY_SEASON</span><span class="p">,</span>
|
||||
<span class="n">SEARCH_CATEGORY_STATE</span><span class="p">,</span>
|
||||
<span class="n">SEARCH_CATEGORY_STATE_ABBREVIATION</span><span class="p">,</span>
|
||||
<span class="n">SEARCH_CATEGORY_STREET</span><span class="p">,</span>
|
||||
<span class="n">SEARCH_CATEGORY_VENUE</span><span class="p">,</span>
|
||||
<span class="n">SEARCH_CATEGORY_VENUE_TYPE</span><span class="p">,</span>
|
||||
<span class="n">SEARCH_CATEGORY_YEAR</span><span class="p">,</span>
|
||||
<span class="p">)</span>
|
||||
|
||||
<span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"SearchInfo"</span><span class="p">]</span>
|
||||
|
||||
|
||||
<div class="viewcode-block" id="SearchInfo"><a class="viewcode-back" href="../../reference.html#osxphotos.SearchInfo">[docs]</a><span class="k">class</span> <span class="nc">SearchInfo</span><span class="p">:</span>
|
||||
<span class="sd">"""Info about search terms such as machine learning labels that Photos knows about 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="n">normalized</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
|
||||
<span class="sd">"""photo: PhotoInfo object</span>
|
||||
<span class="sd"> normalized: if True, all properties return normalized (lower case) results"""</span>
|
||||
|
||||
<span class="k">if</span> <span class="n">photo</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_db_version</span> <span class="o"><=</span> <span class="n">_PHOTOS_4_VERSION</span><span class="p">:</span>
|
||||
<span class="k">raise</span> <span class="ne">NotImplementedError</span><span class="p">(</span>
|
||||
<span class="s2">"search info not implemented for this database version"</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">_normalized</span> <span class="o">=</span> <span class="n">normalized</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">uuid</span> <span class="o">=</span> <span class="n">photo</span><span class="o">.</span><span class="n">uuid</span>
|
||||
<span class="k">try</span><span class="p">:</span>
|
||||
<span class="c1"># get search info for this UUID</span>
|
||||
<span class="c1"># there might not be any search info data (e.g. if Photo was missing or photoanalysisd not run yet)</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_db_searchinfo</span> <span class="o">=</span> <span class="n">photo</span><span class="o">.</span><span class="n">_db</span><span class="o">.</span><span class="n">_db_searchinfo_uuid</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">uuid</span><span class="p">]</span>
|
||||
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">_db_searchinfo</span> <span class="o">=</span> <span class="kc">None</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">labels</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""return list of labels associated with Photo"""</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_text_for_category</span><span class="p">(</span><span class="n">SEARCH_CATEGORY_LABEL</span><span class="p">)</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">place_names</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""returns list of place names"""</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_text_for_category</span><span class="p">(</span><span class="n">SEARCH_CATEGORY_PLACE_NAME</span><span class="p">)</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">streets</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""returns list of street names"""</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_text_for_category</span><span class="p">(</span><span class="n">SEARCH_CATEGORY_STREET</span><span class="p">)</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">neighborhoods</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""returns list of neighborhoods"""</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_text_for_category</span><span class="p">(</span><span class="n">SEARCH_CATEGORY_NEIGHBORHOOD</span><span class="p">)</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">locality_names</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""returns list of other locality names"""</span>
|
||||
<span class="n">locality</span> <span class="o">=</span> <span class="p">[]</span>
|
||||
<span class="k">for</span> <span class="n">category</span> <span class="ow">in</span> <span class="n">SEARCH_CATEGORY_ALL_LOCALITY</span><span class="p">:</span>
|
||||
<span class="n">locality</span> <span class="o">+=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_text_for_category</span><span class="p">(</span><span class="n">category</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="n">locality</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">city</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""returns city/town"""</span>
|
||||
<span class="n">city</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_text_for_category</span><span class="p">(</span><span class="n">SEARCH_CATEGORY_CITY</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="n">city</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">if</span> <span class="n">city</span> <span class="k">else</span> <span class="s2">""</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">state</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""returns state name"""</span>
|
||||
<span class="n">state</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_text_for_category</span><span class="p">(</span><span class="n">SEARCH_CATEGORY_STATE</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="n">state</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">if</span> <span class="n">state</span> <span class="k">else</span> <span class="s2">""</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">state_abbreviation</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""returns state abbreviation"""</span>
|
||||
<span class="n">abbrev</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_text_for_category</span><span class="p">(</span><span class="n">SEARCH_CATEGORY_STATE_ABBREVIATION</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="n">abbrev</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">if</span> <span class="n">abbrev</span> <span class="k">else</span> <span class="s2">""</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">country</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""returns country name"""</span>
|
||||
<span class="n">country</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_text_for_category</span><span class="p">(</span><span class="n">SEARCH_CATEGORY_COUNTRY</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="n">country</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">if</span> <span class="n">country</span> <span class="k">else</span> <span class="s2">""</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">month</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""returns month name"""</span>
|
||||
<span class="n">month</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_text_for_category</span><span class="p">(</span><span class="n">SEARCH_CATEGORY_MONTH</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="n">month</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">if</span> <span class="n">month</span> <span class="k">else</span> <span class="s2">""</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">year</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""returns year"""</span>
|
||||
<span class="n">year</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_text_for_category</span><span class="p">(</span><span class="n">SEARCH_CATEGORY_YEAR</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="n">year</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">if</span> <span class="n">year</span> <span class="k">else</span> <span class="s2">""</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">bodies_of_water</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""returns list of body of water names"""</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_text_for_category</span><span class="p">(</span><span class="n">SEARCH_CATEGORY_BODY_OF_WATER</span><span class="p">)</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">holidays</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""returns list of holiday names"""</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_text_for_category</span><span class="p">(</span><span class="n">SEARCH_CATEGORY_HOLIDAY</span><span class="p">)</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">activities</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""returns list of activity names"""</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_text_for_category</span><span class="p">(</span><span class="n">SEARCH_CATEGORY_ACTIVITY</span><span class="p">)</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">season</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""returns season name"""</span>
|
||||
<span class="n">season</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_text_for_category</span><span class="p">(</span><span class="n">SEARCH_CATEGORY_SEASON</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="n">season</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">if</span> <span class="n">season</span> <span class="k">else</span> <span class="s2">""</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">venues</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""returns list of venue names"""</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_text_for_category</span><span class="p">(</span><span class="n">SEARCH_CATEGORY_VENUE</span><span class="p">)</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">venue_types</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""returns list of venue types"""</span>
|
||||
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_text_for_category</span><span class="p">(</span><span class="n">SEARCH_CATEGORY_VENUE_TYPE</span><span class="p">)</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">media_types</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""returns list of media types (photo, video, panorama, etc)"""</span>
|
||||
<span class="n">types</span> <span class="o">=</span> <span class="p">[]</span>
|
||||
<span class="k">for</span> <span class="n">category</span> <span class="ow">in</span> <span class="n">SEARCH_CATEGORY_MEDIA_TYPES</span><span class="p">:</span>
|
||||
<span class="n">types</span> <span class="o">+=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_text_for_category</span><span class="p">(</span><span class="n">category</span><span class="p">)</span>
|
||||
<span class="k">return</span> <span class="n">types</span>
|
||||
|
||||
<span class="nd">@property</span>
|
||||
<span class="k">def</span> <span class="nf">all</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""return all search info properties in a single list"""</span>
|
||||
<span class="nb">all</span> <span class="o">=</span> <span class="p">(</span>
|
||||
<span class="bp">self</span><span class="o">.</span><span class="n">labels</span>
|
||||
<span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">place_names</span>
|
||||
<span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">streets</span>
|
||||
<span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">neighborhoods</span>
|
||||
<span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">locality_names</span>
|
||||
<span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">bodies_of_water</span>
|
||||
<span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">holidays</span>
|
||||
<span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">activities</span>
|
||||
<span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">venues</span>
|
||||
<span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">venue_types</span>
|
||||
<span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">media_types</span>
|
||||
<span class="p">)</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">city</span><span class="p">:</span>
|
||||
<span class="nb">all</span> <span class="o">+=</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">city</span><span class="p">]</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">state</span><span class="p">:</span>
|
||||
<span class="nb">all</span> <span class="o">+=</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">state</span><span class="p">]</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">state_abbreviation</span><span class="p">:</span>
|
||||
<span class="nb">all</span> <span class="o">+=</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">state_abbreviation</span><span class="p">]</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">country</span><span class="p">:</span>
|
||||
<span class="nb">all</span> <span class="o">+=</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">country</span><span class="p">]</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">month</span><span class="p">:</span>
|
||||
<span class="nb">all</span> <span class="o">+=</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">month</span><span class="p">]</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">year</span><span class="p">:</span>
|
||||
<span class="nb">all</span> <span class="o">+=</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">year</span><span class="p">]</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">season</span><span class="p">:</span>
|
||||
<span class="nb">all</span> <span class="o">+=</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">season</span><span class="p">]</span>
|
||||
|
||||
<span class="k">return</span> <span class="nb">all</span>
|
||||
|
||||
<div class="viewcode-block" id="SearchInfo.asdict"><a class="viewcode-back" href="../../reference.html#osxphotos.SearchInfo.asdict">[docs]</a> <span class="k">def</span> <span class="nf">asdict</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
||||
<span class="sd">"""return dict of search info"""</span>
|
||||
<span class="k">return</span> <span class="p">{</span>
|
||||
<span class="s2">"labels"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">labels</span><span class="p">,</span>
|
||||
<span class="s2">"place_names"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">place_names</span><span class="p">,</span>
|
||||
<span class="s2">"streets"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">streets</span><span class="p">,</span>
|
||||
<span class="s2">"neighborhoods"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">neighborhoods</span><span class="p">,</span>
|
||||
<span class="s2">"city"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">city</span><span class="p">,</span>
|
||||
<span class="s2">"locality_names"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">locality_names</span><span class="p">,</span>
|
||||
<span class="s2">"state"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">state</span><span class="p">,</span>
|
||||
<span class="s2">"state_abbreviation"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">state_abbreviation</span><span class="p">,</span>
|
||||
<span class="s2">"country"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">country</span><span class="p">,</span>
|
||||
<span class="s2">"bodies_of_water"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">bodies_of_water</span><span class="p">,</span>
|
||||
<span class="s2">"month"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">month</span><span class="p">,</span>
|
||||
<span class="s2">"year"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">year</span><span class="p">,</span>
|
||||
<span class="s2">"holidays"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">holidays</span><span class="p">,</span>
|
||||
<span class="s2">"activities"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">activities</span><span class="p">,</span>
|
||||
<span class="s2">"season"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">season</span><span class="p">,</span>
|
||||
<span class="s2">"venues"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">venues</span><span class="p">,</span>
|
||||
<span class="s2">"venue_types"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">venue_types</span><span class="p">,</span>
|
||||
<span class="s2">"media_types"</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">media_types</span><span class="p">,</span>
|
||||
<span class="p">}</span></div>
|
||||
|
||||
<span class="k">def</span> <span class="nf">_get_text_for_category</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">category</span><span class="p">):</span>
|
||||
<span class="sd">"""return list of text for a specified category ID"""</span>
|
||||
<span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db_searchinfo</span><span class="p">:</span>
|
||||
<span class="n">content</span> <span class="o">=</span> <span class="s2">"normalized_string"</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_normalized</span> <span class="k">else</span> <span class="s2">"content_string"</span>
|
||||
<span class="k">return</span> <span class="nb">sorted</span><span class="p">(</span>
|
||||
<span class="p">[</span>
|
||||
<span class="n">rec</span><span class="p">[</span><span class="n">content</span><span class="p">]</span>
|
||||
<span class="k">for</span> <span class="n">rec</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_db_searchinfo</span>
|
||||
<span class="k">if</span> <span class="n">rec</span><span class="p">[</span><span class="s2">"category"</span><span class="p">]</span> <span class="o">==</span> <span class="n">category</span>
|
||||
<span class="p">]</span>
|
||||
<span class="p">)</span>
|
||||
<span class="k">else</span><span class="p">:</span>
|
||||
<span class="k">return</span> <span class="p">[]</span></div>
|
||||
</pre></div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||||
<div class="sphinxsidebarwrapper">
|
||||
<h1 class="logo"><a href="../../index.html">osxphotos</a></h1>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h3>Navigation</h3>
|
||||
<ul>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../overview.html">osxphotos</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../tutorial.html">Tutorial</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../cli.html">osxphotos command line interface (CLI)</a></li>
|
||||
<li class="toctree-l1"><a class="reference internal" href="../../reference.html">osxphotos package</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="relations">
|
||||
<h3>Related Topics</h3>
|
||||
<ul>
|
||||
<li><a href="../../index.html">Documentation overview</a><ul>
|
||||
<li><a href="../index.html">Module code</a><ul>
|
||||
</ul></li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="searchbox" style="display: none" role="search">
|
||||
<h3 id="searchlabel">Quick search</h3>
|
||||
<div class="searchformwrapper">
|
||||
<form class="search" action="../../search.html" method="get">
|
||||
<input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
|
||||
<input type="submit" value="Go" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<script>$('#searchbox').show(0);</script>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearer"></div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
©2021, Rhet Turnbull.
|
||||
|
||||
|
|
||||
Powered by <a href="http://sphinx-doc.org/">Sphinx 4.4.0</a>
|
||||
& <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,8 +0,0 @@
|
||||
osxphotos Command Line Interface (CLI)
|
||||
======================================
|
||||
|
||||
.. click:: osxphotos.cli:cli_main
|
||||
:prog: osxphotos
|
||||
:nested: full
|
||||
|
||||
.. program-output:: python3 -m osxphotos --help
|
||||
@@ -1,7 +0,0 @@
|
||||
osxphotos export
|
||||
======================================
|
||||
|
||||
.. click:: osxphotos.cli:cli_main
|
||||
:prog: osxphotos
|
||||
:commands: export
|
||||
:nested: full
|
||||
@@ -1,25 +0,0 @@
|
||||
.. osxphotos documentation master file, created by
|
||||
sphinx-quickstart on Sat Jan 23 13:27:27 2021.
|
||||
You can adapt this file completely to your liking, but it should at least
|
||||
contain the root `toctree` directive.
|
||||
|
||||
Welcome to osxphotos's documentation!
|
||||
=====================================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 4
|
||||
|
||||
overview
|
||||
tutorial
|
||||
cli
|
||||
template_help
|
||||
package_overview
|
||||
reference
|
||||
|
||||
|
||||
Indices and tables
|
||||
==================
|
||||
|
||||
* :ref:`genindex`
|
||||
* :ref:`modindex`
|
||||
* :ref:`search`
|
||||
@@ -1,5 +0,0 @@
|
||||
osxphotos
|
||||
===========
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 4
|
||||
@@ -1,81 +0,0 @@
|
||||
osxphotos
|
||||
=========
|
||||
|
||||
What is osxphotos?
|
||||
------------------
|
||||
|
||||
osxphotos provides both the ability to interact with and query Apple's Photos.app library on macOS directly from your python code
|
||||
as well as a very flexible command line interface (CLI) app for exporting photos.
|
||||
You can query the Photos library database -- for example, file name, file path, and metadata such as keywords/tags, persons/faces, albums, etc.
|
||||
You can also easily export both the original and edited photos.
|
||||
|
||||
Supported operating systems
|
||||
---------------------------
|
||||
|
||||
Only works on macOS (aka Mac OS X). Tested on macOS Sierra (10.12.6) through macOS Monterey (12.3).
|
||||
|
||||
This package will read Photos databases for any supported version on any supported macOS version.
|
||||
E.g. you can read a database created with Photos 5.0 on MacOS 10.15 on a machine running macOS 10.12 and vice versa.
|
||||
|
||||
Requires python >= ``3.8``.
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
The recommended way of installing ``osxphotos`` is with `pipx <https://github.com/pipxproject/pipx>`_. The easiest way to do this on a Mac is to use `homebrew <https://brew.sh/>`_\ :
|
||||
|
||||
|
||||
* Open ``Terminal`` (search for ``Terminal`` in Spotlight or look in ``Applications/Utilities``\ )
|
||||
* Install ``homebrew`` according to instructions at `https://brew.sh/ <https://brew.sh/>`_
|
||||
* Type the following into Terminal: ``brew install pipx``
|
||||
* Then type this: ``pipx install osxphotos``
|
||||
* Now you should be able to run ``osxphotos`` by typing: ``osxphotos``
|
||||
|
||||
Command Line Usage
|
||||
------------------
|
||||
|
||||
This package will install a command line utility called ``osxphotos`` that allows you to query the Photos database and export photos.
|
||||
|
||||
.. code-block::
|
||||
|
||||
> osxphotos
|
||||
Usage: osxphotos [OPTIONS] COMMAND [ARGS]...
|
||||
|
||||
Options:
|
||||
--db <Photos database path> Specify Photos database path. Path to Photos
|
||||
library/database can be specified using either
|
||||
--db or directly as PHOTOS_LIBRARY positional
|
||||
argument. If neither --db or PHOTOS_LIBRARY
|
||||
provided, will attempt to find the library to
|
||||
use in the following order: 1. last opened
|
||||
library, 2. system library, 3.
|
||||
~/Pictures/Photos Library.photoslibrary
|
||||
--json Print output in JSON format.
|
||||
-v, --version Show the version and exit.
|
||||
-h, --help Show this message and exit.
|
||||
|
||||
Commands:
|
||||
about Print information about osxphotos including license.
|
||||
albums Print out albums found in the Photos library.
|
||||
diff Compare two Photos databases and print out differences
|
||||
docs Open osxphotos documentation in your browser.
|
||||
dump Print list of all photos & associated info from the Photos...
|
||||
export Export photos from the Photos database.
|
||||
help Print help; for help on commands: help <command>.
|
||||
info Print out descriptive info of the Photos library database.
|
||||
install Install Python packages into the same environment as osxphotos
|
||||
keywords Print out keywords found in the Photos library.
|
||||
labels Print out image classification labels found in the Photos...
|
||||
list Print list of Photos libraries found on the system.
|
||||
persons Print out persons (faces) found in the Photos library.
|
||||
places Print out places found in the Photos library.
|
||||
query Query the Photos database using 1 or more search options; if...
|
||||
repl Run interactive osxphotos REPL shell (useful for debugging,...
|
||||
run Run a python file using same environment as osxphotos
|
||||
snap Create snapshot of Photos database to use with diff command
|
||||
theme Manage osxphotos color themes.
|
||||
tutorial Display osxphotos tutorial.
|
||||
uninstall Uninstall Python packages from the osxphotos environment
|
||||
uuid Print out unique IDs (UUID) of photos selected in Photos
|
||||
|
||||
To get help on a specific command, use ``osxphotos help <command_name>``
|
||||
@@ -1,119 +0,0 @@
|
||||
|
||||
Example uses of the python package
|
||||
----------------------------------
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
""" Simple usage of the package """
|
||||
import osxphotos
|
||||
|
||||
def main():
|
||||
photosdb = osxphotos.PhotosDB()
|
||||
print(photosdb.keywords)
|
||||
print(photosdb.persons)
|
||||
print(photosdb.album_names)
|
||||
|
||||
print(photosdb.keywords_as_dict)
|
||||
print(photosdb.persons_as_dict)
|
||||
print(photosdb.albums_as_dict)
|
||||
|
||||
# find all photos with Keyword = Foo and containing John Smith
|
||||
photos = photosdb.photos(keywords=["Foo"],persons=["John Smith"])
|
||||
|
||||
# find all photos that include Alice Smith but do not contain the keyword Bar
|
||||
photos = [p for p in photosdb.photos(persons=["Alice Smith"])
|
||||
if p not in photosdb.photos(keywords=["Bar"]) ]
|
||||
for p in photos:
|
||||
print(
|
||||
p.uuid,
|
||||
p.filename,
|
||||
p.original_filename,
|
||||
p.date,
|
||||
p.description,
|
||||
p.title,
|
||||
p.keywords,
|
||||
p.albums,
|
||||
p.persons,
|
||||
p.path,
|
||||
)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
""" Export all photos to specified directory using album names as folders
|
||||
If file has been edited, also export the edited version,
|
||||
otherwise, export the original version
|
||||
This will result in duplicate photos if photo is in more than album """
|
||||
|
||||
import os.path
|
||||
import pathlib
|
||||
import sys
|
||||
|
||||
import click
|
||||
from pathvalidate import is_valid_filepath, sanitize_filepath
|
||||
|
||||
import osxphotos
|
||||
|
||||
|
||||
@click.command()
|
||||
@click.argument("export_path", type=click.Path(exists=True))
|
||||
@click.option(
|
||||
"--default-album",
|
||||
help="Default folder for photos with no album. Defaults to 'unfiled'",
|
||||
default="unfiled",
|
||||
)
|
||||
@click.option(
|
||||
"--library-path",
|
||||
help="Path to Photos library, default to last used library",
|
||||
default=None,
|
||||
)
|
||||
def export(export_path, default_album, library_path):
|
||||
export_path = os.path.expanduser(export_path)
|
||||
library_path = os.path.expanduser(library_path) if library_path else None
|
||||
|
||||
if library_path is not None:
|
||||
photosdb = osxphotos.PhotosDB(library_path)
|
||||
else:
|
||||
photosdb = osxphotos.PhotosDB()
|
||||
|
||||
photos = photosdb.photos()
|
||||
|
||||
for p in photos:
|
||||
if not p.ismissing:
|
||||
albums = p.albums
|
||||
if not albums:
|
||||
albums = [default_album]
|
||||
for album in albums:
|
||||
click.echo(f"exporting {p.filename} in album {album}")
|
||||
|
||||
# make sure no invalid characters in destination path (could be in album name)
|
||||
album_name = sanitize_filepath(album, platform="auto")
|
||||
|
||||
# create destination folder, if necessary, based on album name
|
||||
dest_dir = os.path.join(export_path, album_name)
|
||||
|
||||
# verify path is a valid path
|
||||
if not is_valid_filepath(dest_dir, platform="auto"):
|
||||
sys.exit(f"Invalid filepath {dest_dir}")
|
||||
|
||||
# create destination dir if needed
|
||||
if not os.path.isdir(dest_dir):
|
||||
os.makedirs(dest_dir)
|
||||
|
||||
# export the photo
|
||||
if p.hasadjustments:
|
||||
# export edited version
|
||||
exported = p.export(dest_dir, edited=True)
|
||||
edited_name = pathlib.Path(p.path_edited).name
|
||||
click.echo(f"Exported {edited_name} to {exported}")
|
||||
# export unedited version
|
||||
exported = p.export(dest_dir)
|
||||
click.echo(f"Exported {p.filename} to {exported}")
|
||||
else:
|
||||
click.echo(f"Skipping missing photo: {p.filename}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
export()
|
||||
@@ -1,5 +0,0 @@
|
||||
osxphotos python API
|
||||
====================
|
||||
|
||||
.. automodule:: osxphotos
|
||||
:members:
|
||||
@@ -1,364 +0,0 @@
|
||||
|
||||
osxphotos Template System
|
||||
=========================
|
||||
|
||||
The templating system converts one or template statements, written in osxphotos metadata templating language, to one or more rendered values using information from the photo being processed.
|
||||
|
||||
In its simplest form, a template statement has the form: ``"{template_field}"``\ , for example ``"{title}"`` which would resolve to the title of the photo.
|
||||
|
||||
Template statements may contain one or more modifiers. The full syntax is:
|
||||
|
||||
``"pretext{delim+template_field:subfield|filter(path_sep)[find,replace] conditional?bool_value,default}posttext"``
|
||||
|
||||
Template statements are white-space sensitive meaning that white space (spaces, tabs) changes the meaning of the template statement.
|
||||
|
||||
``pretext`` and ``posttext`` are free form text. For example, if a photo has title "My Photo Title" the template statement ``"The title of the photo is {title}"``\ , resolves to ``"The title of the photo is My Photo Title"``. The ``pretext`` in this example is ``"The title if the photo is "`` and the template_field is ``{title}``.
|
||||
|
||||
``delim``\ : optional delimiter string to use when expanding multi-valued template values in-place
|
||||
|
||||
``+``\ : If present before template ``name``\ , expands the template in place. If ``delim`` not provided, values are joined with no delimiter.
|
||||
|
||||
e.g. if Photo keywords are ``["foo","bar"]``\ :
|
||||
|
||||
|
||||
* ``"{keyword}"`` renders to ``"foo", "bar"``
|
||||
* ``"{,+keyword}"`` renders to: ``"foo,bar"``
|
||||
* ``"{; +keyword}"`` renders to: ``"foo; bar"``
|
||||
* ``"{+keyword}"`` renders to ``"foobar"``
|
||||
|
||||
``template_field``\ : The template field to resolve. See `Template Substitutions <#template-substitutions>`_ for full list of template fields.
|
||||
|
||||
`:subfield`: Some templates have sub-fields, For example, `{exiftool:IPTC:Make}\ ``; the template_field is``\ exiftool\ ``and the sub-field is``\ IPTC:Make`.
|
||||
|
||||
`|filter`: You may optionally append one or more filter commands to the end of the template field using the vertical pipe ('|') symbol. Filters may be combined, separated by '|' as in: ``{keyword|capitalize|parens}``.
|
||||
|
||||
Valid filters are:
|
||||
|
||||
|
||||
* ``lower``\ : Convert value to lower case, e.g. 'Value' => 'value'.
|
||||
* ``upper``\ : Convert value to upper case, e.g. 'Value' => 'VALUE'.
|
||||
* ``strip``\ : Strip whitespace from beginning/end of value, e.g. ' Value ' => 'Value'.
|
||||
* ``titlecase``\ : Convert value to title case, e.g. 'my value' => 'My Value'.
|
||||
* ``capitalize``\ : Capitalize first word of value and convert other words to lower case, e.g. 'MY VALUE' => 'My value'.
|
||||
* ``braces``\ : Enclose value in curly braces, e.g. 'value => '{value}'.
|
||||
* ``parens``\ : Enclose value in parentheses, e.g. 'value' => '(value')
|
||||
* ``brackets``\ : Enclose value in brackets, e.g. 'value' => '[value]'
|
||||
* ``shell_quote``\ : Quotes the value for safe usage in the shell, e.g. My file.jpeg => 'My file.jpeg'; only adds quotes if needed.
|
||||
* `function`: Run custom python function to filter value; use in format 'function:/path/to/file.py::function_name'. See example at https://github.com/RhetTbull/osxphotos/blob/master/examples/template_filter.py
|
||||
|
||||
e.g. if Photo keywords are ``["FOO","bar"]``\ :
|
||||
|
||||
|
||||
* ``"{keyword|lower}"`` renders to ``"foo", "bar"``
|
||||
* ``"{keyword|upper}"`` renders to: ``"FOO", "BAR"``
|
||||
* ``"{keyword|capitalize}"`` renders to: ``"Foo", "Bar"``
|
||||
* ``"{keyword|lower|parens}"`` renders to: ``"(foo)", "(bar)"``
|
||||
|
||||
e.g. if Photo description is "my description":
|
||||
|
||||
|
||||
* ``"{descr|titlecase}"`` renders to: ``"My Description"``
|
||||
|
||||
``(path_sep)``\ : optional path separator to use when joining path-like fields, for example ``{folder_album}``. Default is "/".
|
||||
|
||||
e.g. If Photo is in ``Album1`` in ``Folder1``\ :
|
||||
|
||||
|
||||
* ``"{folder_album}"`` renders to ``["Folder1/Album1"]``
|
||||
* ``"{folder_album(>)}"`` renders to ``["Folder1>Album1"]``
|
||||
* ``"{folder_album()}"`` renders to ``["Folder1Album1"]``
|
||||
|
||||
`[find,replace]`: optional text replacement to perform on rendered template value. For example, to replace "/" in an album name, you could use the template `"{album[/,-]}"`. Multiple replacements can be made by appending "|" and adding another find|replace pair. e.g. to replace both "/" and ":" in album name: ``"{album[/,-|:,-]}"``. find/replace pairs are not limited to single characters. The "|" character cannot be used in a find/replace pair.
|
||||
|
||||
`conditional`: optional conditional expression that is evaluated as boolean (True/False) for use with the `?bool_value` modifier. Conditional expressions take the form '` not operator value`' where `not` is an optional modifier that negates the `operator`. Note: the space before the conditional expression is required if you use a conditional expression. Valid comparison operators are:
|
||||
|
||||
|
||||
* ``contains``\ : template field contains value, similar to python's ``in``
|
||||
* `matches`: template field contains exactly value, unlike `contains`: does not match partial matches
|
||||
* ``startswith``\ : template field starts with value
|
||||
* ``endswith``\ : template field ends with value
|
||||
* ``<=``\ : template field is less than or equal to value
|
||||
* ``>=``\ : template field is greater than or equal to value
|
||||
* ``<``\ : template field is less than value
|
||||
* ``>``\ : template field is greater than value
|
||||
* ``==``\ : template field equals value
|
||||
* ``!=``\ : template field does not equal value
|
||||
|
||||
The ``value`` part of the conditional expression is treated as a bare (unquoted) word/phrase. Multiple values may be separated by '|' (the pipe symbol). ``value`` is itself a template statement so you can use one or more template fields in ``value`` which will be resolved before the comparison occurs.
|
||||
|
||||
For example:
|
||||
|
||||
|
||||
* ``{keyword matches Beach}`` resolves to True if 'Beach' is a keyword. It would not match keyword 'BeachDay'.
|
||||
* ``{keyword contains Beach}`` resolves to True if any keyword contains the word 'Beach' so it would match both 'Beach' and 'BeachDay'.
|
||||
* ``{photo.score.overall > 0.7}`` resolves to True if the photo's overall aesthetic score is greater than 0.7.
|
||||
* ``{keyword|lower contains beach}`` uses the lower case filter to do case-insensitive matching to match any keyword that contains the word 'beach'.
|
||||
* ``{keyword|lower not contains beach}`` uses the ``not`` modifier to negate the comparison so this resolves to True if there is no keyword that matches 'beach'.
|
||||
|
||||
Examples: to export photos that contain certain keywords with the ``osxphotos export`` command's ``--directory`` option:
|
||||
|
||||
``--directory "{keyword|lower matches travel|vacation?Travel-Photos,Not-Travel-Photos}"``
|
||||
|
||||
This exports any photo that has keywords 'travel' or 'vacation' into a directory 'Travel-Photos' and all other photos into directory 'Not-Travel-Photos'.
|
||||
|
||||
This can be used to rename files as well, for example:
|
||||
``--filename "{favorite?Favorite-{original_name},{original_name}}"``
|
||||
|
||||
This renames any photo that is a favorite as 'Favorite-ImageName.jpg' (where 'ImageName.jpg' is the original name of the photo) and all other photos with the unmodified original name.
|
||||
|
||||
``?bool_value``\ : Template fields may be evaluated as boolean (True/False) by appending "?" after the field name (and following "(path_sep)" or "[find/replace]". If a field is True (e.g. photo is HDR and field is ``"{hdr}"``\ ) or has any value, the value following the "?" will be used to render the template instead of the actual field value. If the template field evaluates to False (e.g. in above example, photo is not HDR) or has no value (e.g. photo has no title and field is ``"{title}"``\ ) then the default value following a "," will be used.
|
||||
|
||||
e.g. if photo is an HDR image,
|
||||
|
||||
|
||||
* ``"{hdr?ISHDR,NOTHDR}"`` renders to ``"ISHDR"``
|
||||
|
||||
and if it is not an HDR image,
|
||||
|
||||
|
||||
* ``"{hdr?ISHDR,NOTHDR}"`` renders to ``"NOTHDR"``
|
||||
|
||||
``,default``\ : optional default value to use if the template name has no value. This modifier is also used for the value if False for boolean-type fields (see above) as well as to hold a sub-template for values like ``{created.strftime}``. If no default value provided, "_" is used.
|
||||
|
||||
e.g., if photo has no title set,
|
||||
|
||||
|
||||
* ``"{title}"`` renders to "_"
|
||||
* ``"{title,I have no title}"`` renders to ``"I have no title"``
|
||||
|
||||
Template fields such as ``created.strftime`` use the default value to pass the template to use for ``strftime``.
|
||||
|
||||
e.g., if photo date is 4 February 2020, 19:07:38,
|
||||
|
||||
|
||||
* ``"{created.strftime,%Y-%m-%d-%H%M%S}"`` renders to ``"2020-02-04-190738"``
|
||||
|
||||
Some template fields such as ``"{media_type}"`` use the default value to allow customization of the output. For example, ``"{media_type}"`` resolves to the special media type of the photo such as ``panorama`` or ``selfie``. You may use the default value to override these in form: ``"{media_type,video=vidéo;time_lapse=vidéo_accélérée}"``. In this example, if photo was a time_lapse photo, ``media_type`` would resolve to ``vidéo_accélérée`` instead of ``time_lapse``.
|
||||
|
||||
Either or both bool_value or default (False value) may be empty which would result in empty string ``""`` when rendered.
|
||||
|
||||
If you want to include "{" or "}" in the output, use "{openbrace}" or "{closebrace}" template substitution.
|
||||
|
||||
e.g. ``"{created.year}/{openbrace}{title}{closebrace}"`` would result in ``"2020/{Photo Title}"``.
|
||||
|
||||
Template Substitutions
|
||||
----------------------
|
||||
|
||||
.. list-table::
|
||||
:header-rows: 1
|
||||
|
||||
* - Substitution
|
||||
- Description
|
||||
* - {name}
|
||||
- Current filename of the photo
|
||||
* - {original_name}
|
||||
- Photo's original filename when imported to Photos
|
||||
* - {title}
|
||||
- Title of the photo
|
||||
* - {descr}
|
||||
- Description of the photo
|
||||
* - {media_type}
|
||||
- Special media type resolved in this precedence: selfie, time_lapse, panorama, slow_mo, screenshot, portrait, live_photo, burst, photo, video. Defaults to 'photo' or 'video' if no special type. Customize one or more media types using format: '{media_type,video=vidéo;time_lapse=vidéo_accélérée}'
|
||||
* - {photo_or_video}
|
||||
- 'photo' or 'video' depending on what type the image is. To customize, use default value as in '{photo_or_video,photo=fotos;video=videos}'
|
||||
* - {hdr}
|
||||
- Photo is HDR?; True/False value, use in format '{hdr?VALUE_IF_TRUE,VALUE_IF_FALSE}'
|
||||
* - {edited}
|
||||
- True if photo has been edited (has adjustments), otherwise False; use in format '{edited?VALUE_IF_TRUE,VALUE_IF_FALSE}'
|
||||
* - {edited_version}
|
||||
- True if template is being rendered for the edited version of a photo, otherwise False.
|
||||
* - {favorite}
|
||||
- Photo has been marked as favorite?; True/False value, use in format '{favorite?VALUE_IF_TRUE,VALUE_IF_FALSE}'
|
||||
* - {created.date}
|
||||
- Photo's creation date in ISO format, e.g. '2020-03-22'
|
||||
* - {created.year}
|
||||
- 4-digit year of photo creation time
|
||||
* - {created.yy}
|
||||
- 2-digit year of photo creation time
|
||||
* - {created.mm}
|
||||
- 2-digit month of the photo creation time (zero padded)
|
||||
* - {created.month}
|
||||
- Month name in user's locale of the photo creation time
|
||||
* - {created.mon}
|
||||
- Month abbreviation in the user's locale of the photo creation time
|
||||
* - {created.dd}
|
||||
- 2-digit day of the month (zero padded) of photo creation time
|
||||
* - {created.dow}
|
||||
- Day of week in user's locale of the photo creation time
|
||||
* - {created.doy}
|
||||
- 3-digit day of year (e.g Julian day) of photo creation time, starting from 1 (zero padded)
|
||||
* - {created.hour}
|
||||
- 2-digit hour of the photo creation time
|
||||
* - {created.min}
|
||||
- 2-digit minute of the photo creation time
|
||||
* - {created.sec}
|
||||
- 2-digit second of the photo creation time
|
||||
* - {created.strftime}
|
||||
- Apply strftime template to file creation date/time. Should be used in form {created.strftime,TEMPLATE} where TEMPLATE is a valid strftime template, e.g. {created.strftime,%Y-%U} would result in year-week number of year: '2020-23'. If used with no template will return null value. See https://strftime.org/ for help on strftime templates.
|
||||
* - {modified.date}
|
||||
- Photo's modification date in ISO format, e.g. '2020-03-22'; uses creation date if photo is not modified
|
||||
* - {modified.year}
|
||||
- 4-digit year of photo modification time; uses creation date if photo is not modified
|
||||
* - {modified.yy}
|
||||
- 2-digit year of photo modification time; uses creation date if photo is not modified
|
||||
* - {modified.mm}
|
||||
- 2-digit month of the photo modification time (zero padded); uses creation date if photo is not modified
|
||||
* - {modified.month}
|
||||
- Month name in user's locale of the photo modification time; uses creation date if photo is not modified
|
||||
* - {modified.mon}
|
||||
- Month abbreviation in the user's locale of the photo modification time; uses creation date if photo is not modified
|
||||
* - {modified.dd}
|
||||
- 2-digit day of the month (zero padded) of the photo modification time; uses creation date if photo is not modified
|
||||
* - {modified.dow}
|
||||
- Day of week in user's locale of the photo modification time; uses creation date if photo is not modified
|
||||
* - {modified.doy}
|
||||
- 3-digit day of year (e.g Julian day) of photo modification time, starting from 1 (zero padded); uses creation date if photo is not modified
|
||||
* - {modified.hour}
|
||||
- 2-digit hour of the photo modification time; uses creation date if photo is not modified
|
||||
* - {modified.min}
|
||||
- 2-digit minute of the photo modification time; uses creation date if photo is not modified
|
||||
* - {modified.sec}
|
||||
- 2-digit second of the photo modification time; uses creation date if photo is not modified
|
||||
* - {modified.strftime}
|
||||
- Apply strftime template to file modification date/time. Should be used in form {modified.strftime,TEMPLATE} where TEMPLATE is a valid strftime template, e.g. {modified.strftime,%Y-%U} would result in year-week number of year: '2020-23'. If used with no template will return null value. Uses creation date if photo is not modified. See https://strftime.org/ for help on strftime templates.
|
||||
* - {today.date}
|
||||
- Current date in iso format, e.g. '2020-03-22'
|
||||
* - {today.year}
|
||||
- 4-digit year of current date
|
||||
* - {today.yy}
|
||||
- 2-digit year of current date
|
||||
* - {today.mm}
|
||||
- 2-digit month of the current date (zero padded)
|
||||
* - {today.month}
|
||||
- Month name in user's locale of the current date
|
||||
* - {today.mon}
|
||||
- Month abbreviation in the user's locale of the current date
|
||||
* - {today.dd}
|
||||
- 2-digit day of the month (zero padded) of current date
|
||||
* - {today.dow}
|
||||
- Day of week in user's locale of the current date
|
||||
* - {today.doy}
|
||||
- 3-digit day of year (e.g Julian day) of current date, starting from 1 (zero padded)
|
||||
* - {today.hour}
|
||||
- 2-digit hour of the current date
|
||||
* - {today.min}
|
||||
- 2-digit minute of the current date
|
||||
* - {today.sec}
|
||||
- 2-digit second of the current date
|
||||
* - {today.strftime}
|
||||
- Apply strftime template to current date/time. Should be used in form {today.strftime,TEMPLATE} where TEMPLATE is a valid strftime template, e.g. {today.strftime,%Y-%U} would result in year-week number of year: '2020-23'. If used with no template will return null value. See https://strftime.org/ for help on strftime templates.
|
||||
* - {place.name}
|
||||
- Place name from the photo's reverse geolocation data, as displayed in Photos
|
||||
* - {place.country_code}
|
||||
- The ISO country code from the photo's reverse geolocation data
|
||||
* - {place.name.country}
|
||||
- Country name from the photo's reverse geolocation data
|
||||
* - {place.name.state_province}
|
||||
- State or province name from the photo's reverse geolocation data
|
||||
* - {place.name.city}
|
||||
- City or locality name from the photo's reverse geolocation data
|
||||
* - {place.name.area_of_interest}
|
||||
- Area of interest name (e.g. landmark or public place) from the photo's reverse geolocation data
|
||||
* - {place.address}
|
||||
- Postal address from the photo's reverse geolocation data, e.g. '2007 18th St NW, Washington, DC 20009, United States'
|
||||
* - {place.address.street}
|
||||
- Street part of the postal address, e.g. '2007 18th St NW'
|
||||
* - {place.address.city}
|
||||
- City part of the postal address, e.g. 'Washington'
|
||||
* - {place.address.state_province}
|
||||
- State/province part of the postal address, e.g. 'DC'
|
||||
* - {place.address.postal_code}
|
||||
- Postal code part of the postal address, e.g. '20009'
|
||||
* - {place.address.country}
|
||||
- Country name of the postal address, e.g. 'United States'
|
||||
* - {place.address.country_code}
|
||||
- ISO country code of the postal address, e.g. 'US'
|
||||
* - {searchinfo.season}
|
||||
- Season of the year associated with a photo, e.g. 'Summer'; (Photos 5+ only, applied automatically by Photos' image categorization algorithms).
|
||||
* - {exif.camera_make}
|
||||
- Camera make from original photo's EXIF information as imported by Photos, e.g. 'Apple'
|
||||
* - {exif.camera_model}
|
||||
- Camera model from original photo's EXIF information as imported by Photos, e.g. 'iPhone 6s'
|
||||
* - {exif.lens_model}
|
||||
- Lens model from original photo's EXIF information as imported by Photos, e.g. 'iPhone 6s back camera 4.15mm f/2.2'
|
||||
* - {uuid}
|
||||
- Photo's internal universally unique identifier (UUID) for the photo, a 36-character string unique to the photo, e.g. '128FB4C6-0B16-4E7D-9108-FB2E90DA1546'
|
||||
* - {id}
|
||||
- A unique number for the photo based on its primary key in the Photos database. A sequential integer, e.g. 1, 2, 3...etc. Each asset associated with a photo (e.g. an image and Live Photo preview) will share the same id. May be formatted using a python string format code. For example, to format as a 5-digit integer and pad with zeros, use '{id:05d}' which results in 00001, 00002, 00003...etc.
|
||||
* - {album_seq}
|
||||
- An integer, starting at 0, indicating the photo's index (sequence) in the containing album. Only valid when used in a '--filename' template and only when '{album}' or '{folder_album}' is used in the '--directory' template. For example '--directory "{folder_album}" --filename "{album\ *seq}*\ {original_name}"'. To start counting at a value other than 0, append append a period and the starting value to the field name. For example, to start counting at 1 instead of 0: '{album_seq.1}'. May be formatted using a python string format code. For example, to format as a 5-digit integer and pad with zeros, use '{album_seq:05d}' which results in 00000, 00001, 00002...etc. This may result in incorrect sequences if you have duplicate albums with the same name; see also '{folder_album_seq}'.
|
||||
* - {folder_album_seq}
|
||||
- An integer, starting at 0, indicating the photo's index (sequence) in the containing album and folder path. Only valid when used in a '--filename' template and only when '{folder_album}' is used in the '--directory' template. For example '--directory "{folder_album}" --filename "{folder_album\ *seq}*\ {original_name}"'. To start counting at a value other than 0, append append a period and the starting value to the field name. For example, to start counting at 1 instead of 0: '{folder_album_seq.1}' May be formatted using a python string format code. For example, to format as a 5-digit integer and pad with zeros, use '{folder_album_seq:05d}' which results in 00000, 00001, 00002...etc. This may result in incorrect sequences if you have duplicate albums with the same name in the same folder; see also '{album_seq}'.
|
||||
* - {comma}
|
||||
- A comma: ','
|
||||
* - {semicolon}
|
||||
- A semicolon: ';'
|
||||
* - {questionmark}
|
||||
- A question mark: '?'
|
||||
* - {pipe}
|
||||
- A vertical pipe: '|'
|
||||
* - {openbrace}
|
||||
- An open brace: '{'
|
||||
* - {closebrace}
|
||||
- A close brace: '}'
|
||||
* - {openparens}
|
||||
- An open parentheses: '('
|
||||
* - {closeparens}
|
||||
- A close parentheses: ')'
|
||||
* - {openbracket}
|
||||
- An open bracket: '['
|
||||
* - {closebracket}
|
||||
- A close bracket: ']'
|
||||
* - {newline}
|
||||
- A newline: '\n'
|
||||
* - {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.47.10'
|
||||
* - {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
|
||||
* - {project}
|
||||
- Project(s) photo is contained in (such as greeting cards, calendars, slideshows)
|
||||
* - {album_project}
|
||||
- Album(s) and project(s) photo is contained in; treats projects as regular albums
|
||||
* - {folder_album_project}
|
||||
- Folder path + album (includes projects as albums) photo is contained in. e.g. 'Folder/Subfolder/Album' or just 'Album' if no enclosing folder
|
||||
* - {keyword}
|
||||
- Keyword(s) assigned to photo
|
||||
* - {person}
|
||||
- Person(s) / face(s) in a photo
|
||||
* - {label}
|
||||
- Image categorization label associated with a photo (Photos 5+ only). Labels are added automatically by Photos using machine learning algorithms to categorize images. These are not the same as {keyword} which refers to the user-defined keywords/tags applied in Photos.
|
||||
* - {label_normalized}
|
||||
- All lower case version of 'label' (Photos 5+ only)
|
||||
* - {comment}
|
||||
- Comment(s) on shared Photos; format is 'Person name: comment text' (Photos 5+ only)
|
||||
* - {exiftool}
|
||||
- Format: '{exiftool:GROUP:TAGNAME}'; use exiftool (https://exiftool.org) to extract metadata, in form GROUP:TAGNAME, from image. E.g. '{exiftool:EXIF:Make}' to get camera make, or {exiftool:IPTC:Keywords} to extract keywords. See https://exiftool.org/TagNames/ for list of valid tag names. You must specify group (e.g. EXIF, IPTC, etc) as used in ``exiftool -G``. exiftool must be installed in the path to use this template.
|
||||
* - {searchinfo.holiday}
|
||||
- Holiday names associated with a photo, e.g. 'Christmas Day'; (Photos 5+ only, applied automatically by Photos' image categorization algorithms).
|
||||
* - {searchinfo.activity}
|
||||
- Activities associated with a photo, e.g. 'Sporting Event'; (Photos 5+ only, applied automatically by Photos' image categorization algorithms).
|
||||
* - {searchinfo.venue}
|
||||
- Venues associated with a photo, e.g. name of restaurant; (Photos 5+ only, applied automatically by Photos' image categorization algorithms).
|
||||
* - {searchinfo.venue_type}
|
||||
- Venue types associated with a photo, e.g. 'Restaurant'; (Photos 5+ only, applied automatically by Photos' image categorization algorithms).
|
||||
* - {photo}
|
||||
- Provides direct access to the PhotoInfo object for the photo. Must be used in format '{photo.property}' where 'property' represents a PhotoInfo property. For example: '{photo.favorite}' is the same as '{favorite}' and '{photo.place.name}' is the same as '{place.name}'. '{photo}' provides access to properties that are not available as separate template fields but it assumes some knowledge of the underlying PhotoInfo class. See https://rhettbull.github.io/osxphotos/ for additional documentation on the PhotoInfo class.
|
||||
* - {detected_text}
|
||||
- List of text strings found in the image after performing text detection. Using '{detected_text}' will cause osxphotos to perform text detection on your photos using the built-in macOS text detection algorithms which will slow down your export. The results for each photo will be cached in the export database so that future exports with '--update' do not need to reprocess each photo. You may pass a confidence threshold value between 0.0 and 1.0 after a colon as in '{detected_text:0.5}'; The default confidence threshold is 0.75. '{detected_text}' works only on macOS Catalina (10.15) or later. Note: this feature is not the same thing as Live Text in macOS Monterey, which osxphotos does not yet support.
|
||||
* - {shell_quote}
|
||||
- Use in form '{shell_quote,TEMPLATE}'; quotes the rendered TEMPLATE value(s) for safe usage in the shell, e.g. My file.jpeg => 'My file.jpeg'; only adds quotes if needed.
|
||||
* - {strip}
|
||||
- Use in form '{strip,TEMPLATE}'; strips whitespace from begining and end of rendered TEMPLATE value(s).
|
||||
* - {function}
|
||||
- Execute a python function from an external file and use return value as template substitution. Use in format: {function:file.py::function_name} where 'file.py' is the name of the python file and 'function_name' is the name of the function to call. The function will be passed the PhotoInfo object for the photo. See https://github.com/RhetTbull/osxphotos/blob/master/examples/template_function.py for an example of how to implement a template function.
|
||||
|
||||
@@ -1,354 +0,0 @@
|
||||
<!-- OSXPHOTOS-TUTORIAL-HEADER:START -->
|
||||
# OSXPhotos Tutorial
|
||||
|
||||
## Tutorial
|
||||
<!-- OSXPHOTOS-TUTORIAL-HEADER:END -->
|
||||
|
||||
The design philosophy for osxphotos is "make the easy things easy and make the hard things possible". To "make the hard things possible", osxphotos is very flexible and has many, many configuration options -- the `export` command for example, has over 100 command line options. Thus, osxphotos may seem daunting at first. The purpose of this tutorial is to explain a number of common use cases with examples and, hopefully, make osxphotos less daunting to use. osxphotos includes several commands for retrieving information from your Photos library but the one most users are interested in is the `export` command which exports photos from the library so that's the focus of this tutorial.
|
||||
|
||||
### Export your photos
|
||||
|
||||
`osxphotos export /path/to/export`
|
||||
|
||||
This command exports all your photos to the `/path/to/export` directory.
|
||||
|
||||
**Note**: osxphotos uses the term 'photo' to refer to a generic media asset in your Photos Library. A photo may be an image, a video file, a combination of still image and video file (e.g. an Apple "Live Photo" which is an image and an associated "live preview" video file), a JPEG image with an associated RAW image, etc.
|
||||
|
||||
### Export by date
|
||||
|
||||
While the previous command will export all your photos (and videos--see note above), it probably doesn't do exactly what you want. In the previous example, all the photos will be exported to a single folder: `/path/to/export`. If you have a large library with thousands of images and videos, this likely isn't very useful. You can use the `--export-by-date` option to export photos to a folder structure organized by year, month, day, e.g. `2021/04/21`:
|
||||
|
||||
`osxphotos export /path/to/export --export-by-date`
|
||||
|
||||
With this command, a photo that was created on 31 May 2015 would be exported to: `/path/to/export/2015/05/31`
|
||||
|
||||
### Specify directory structure
|
||||
|
||||
If you prefer a different directory structure for your exported images, osxphotos provides a very flexible <!-- OSXPHOTOS-TEMPLATE-SYSTEM-LINK:START -->template system<!-- OSXPHOTOS-TEMPLATE-SYSTEM-LINK:END --> that allows you to specify the directory structure using the `--directory` option. For example, this command exported to a directory structure that looks like: `2015/May` (4-digit year / month name):
|
||||
|
||||
`osxphotos export /path/to/export --directory "{created.year}/{created.month}"`
|
||||
|
||||
The string following `--directory` is an `osxphotos template string`. Template strings are widely used throughout osxphotos and it's worth your time to learn more about them. In a template string, the values between the curly braces, e.g. `{created.year}` are replaced with metadata from the photo being exported. In this case, `{created.year}` is the 4-digit year of the photo's creation date and `{created.month}` is the full month name in the user's locale (e.g. `May`, `mai`, etc.). In the osxphotos template system these are referred to as template fields. The text not included between `{}` pairs is interpreted literally, in this case `/`, is a directory separator.
|
||||
|
||||
osxphotos provides access to almost all the metadata known to Photos about your images. For example, Photos performs reverse geolocation lookup on photos that contain GPS coordinates to assign place names to the photo. Using the `--directory` template, you could thus export photos organized by country name:
|
||||
|
||||
`osxphotos export /path/to/export --directory "{created.year}/{place.name.country}"`
|
||||
|
||||
Of course, some photos might not have an associated place name so the template system allows you specify a default value to use if a template field is null (has no value).
|
||||
|
||||
`osxphotos export /path/to/export --directory "{created.year}/{place.name.country,No-Country}"`
|
||||
|
||||
The value after the ',' in the template string is the default value, in this case 'No-Country'. **Note**: If you don't specify a default value and a template field is null, osxphotos will use "_" (underscore character) as the default.
|
||||
|
||||
Some template fields, such as `{keyword}`, may expand to more than one value. For example, if a photo has keywords of "Travel" and "Vacation", `{keyword}` would expand to "Travel", "Vacation". When used with `--directory`, this would result in the photo being exported to more than one directory (thus more than one copy of the photo would be exported). For example, if `IMG_1234.JPG` has keywords `Travel`, and `Vacation` and you run the following command:
|
||||
|
||||
`osxphotos export /path/to/export --directory "{keyword}"`
|
||||
|
||||
the exported files would be:
|
||||
|
||||
/path/to/export/Travel/IMG_1234.JPG
|
||||
/path/to/export/Vacation/IMG_1234.JPG
|
||||
|
||||
### Specify exported filename
|
||||
|
||||
By default, osxphotos will use the original filename of the photo when exporting. That is, the filename the photo had when it was taken or imported into Photos. This is often something like `IMG_1234.JPG` or `DSC05678.dng`. osxphotos allows you to specify a custom filename template using the `--filename` option in the same way as `--directory` allows you to specify a custom directory name. For example, Photos allows you specify a title or caption for a photo and you can use this in place of the original filename:
|
||||
|
||||
`osxphotos export /path/to/export --filename "{title}"`
|
||||
|
||||
The above command will export photos using the title. Note that you don't need to specify the extension as part of the `--filename` template as osxphotos will automatically add the correct file extension. Some photos might not have a title so in this case, you could use the default value feature to specify a different name for these photos. For example, to use the title as the filename, but if no title is specified, use the original filename instead:
|
||||
|
||||
```txt
|
||||
osxphotos export /path/to/export --filename "{title,{original_name}}"
|
||||
│ ││ │
|
||||
│ ││ │
|
||||
Use photo's title as the filename <──────┘ ││ │
|
||||
││ │
|
||||
Value after comma will be used <───────┘│ │
|
||||
if title is blank │ │
|
||||
│ │
|
||||
The default value can be <────┘ │
|
||||
another template field │
|
||||
│
|
||||
Use photo's original name if no title <──────┘
|
||||
```
|
||||
|
||||
The osxphotos template system also allows for limited conditional logic of the type "If a condition is true then do one thing, otherwise, do a different thing". For example, you can use the `--filename` option to name files that are marked as "Favorites" in Photos differently than other files. For example, to add a "#" to the name of every photo that's a favorite:
|
||||
|
||||
```txt
|
||||
osxphotos export /path/to/export --filename "{original_name}{favorite?#,}"
|
||||
│ │ │││
|
||||
│ │ │││
|
||||
Use photo's original name as filename <──┘ │ │││
|
||||
│ │││
|
||||
'favorite' is True if photo is a Favorite, <───────┘ │││
|
||||
otherwise, False │││
|
||||
│││
|
||||
'?' specifies a conditional <─────────────┘││
|
||||
││
|
||||
Value immediately following ? will be used if <──────┘│
|
||||
preceding template field is True or non-blank │
|
||||
│
|
||||
Value immediately following comma will be used if <──────┘
|
||||
template field is False or blank (null); in this case
|
||||
no value is specified so a blank string "" will be used
|
||||
```
|
||||
|
||||
Like with `--directory`, using a multi-valued template field such as `{keyword}` may result in more than one copy of a photo being exported. For example, if `IMG_1234.JPG` has keywords `Travel`, and `Vacation` and you run the following command:
|
||||
|
||||
`osxphotos export /path/to/export --filename "{keyword}-{original_name}"`
|
||||
|
||||
the exported files would be:
|
||||
|
||||
/path/to/export/Travel-IMG_1234.JPG
|
||||
/path/to/export/Vacation-IMG_1234.JPG
|
||||
|
||||
### Edited photos
|
||||
|
||||
If a photo has been edited in Photos (e.g. cropped, adjusted, etc.) there will be both an original image and an edited image in the Photos Library. By default, osxphotos will export both the original and the edited image. To distinguish between them, osxphotos will append "_edited" to the edited image. For example, if the original image was named `IMG_1234.JPG`, osxphotos will export the original as `IMG_1234.JPG` and the edited version as `IMG_1234_edited.jpeg`. **Note:** Photos changes the extension of edited images to ".jpeg" even if the original was named ".JPG". You can change the suffix appended to edited images using the `--edited-suffix` option:
|
||||
|
||||
`osxphotos export /path/to/export --edited-suffix "_EDIT"`
|
||||
|
||||
In this example, the edited image would be named `IMG_1234_EDIT.jpeg`. Like many options in osxphotos, the `--edited-suffix` option can evaluate an osxphotos template string so you could append the modification date (the date the photo was edited) to all edited photos using this command:
|
||||
|
||||
`osxphotos export /path/to/export --edited-suffix "_{modified.year}-{modified.mm}-{modified.dd}"`
|
||||
|
||||
In this example, if the photo was edited on 21 April 2021, the name of the exported file would be: `IMG_1234_2021-04-21.jpeg`.
|
||||
|
||||
You can tell osxphotos to not export edited photos (that is, only export the original unedited photos) using `--skip-edited`:
|
||||
|
||||
`osxphotos export /path/to/export --skip-edited`
|
||||
|
||||
You can also tell osxphotos to export either the original photo (if the photo has not been edited) or the edited photo (if it has been edited), but not both, using the `--skip-original-if-edited` option:
|
||||
|
||||
`osxphotos export /path/to/export --skip-original-if-edited`
|
||||
|
||||
As mentioned above, Photos renames JPEG images that have been edited with the ".jpeg" extension. Some applications use ".JPG" and others use ".jpg" or ".JPEG". You can use the `--jpeg-ext` option to have osxphotos rename all JPEG files with the same extension. Valid values are jpeg, jpg, JPEG, JPG; e.g. `--jpeg-ext jpg` to use '.jpg' for all JPEGs.
|
||||
|
||||
`osxphotos export /path/to/export --jpeg-ext jpg`
|
||||
|
||||
### Specifying the Photos library
|
||||
|
||||
All the above commands operate on the default Photos library. Most users only use a single Photos library which is also known as the System Photo Library. It is possible to use Photos with more than one library. For example, if you hold down the "Option" key while opening Photos, you can select an alternate Photos library. If you don't specify which library to use, osxphotos will try find the last opened library. Occasionally it can't determine this and in that case, it will use the System Photos Library. If you use more than one Photos library and want to explicitly specify which library to use, you can do so with the `--db` option. (db is short for database and is so named because osxphotos operates on the database that Photos uses to manage your Photos library).
|
||||
|
||||
`osxphotos export /path/to/export --db ~/Pictures/MyAlternateLibrary.photoslibrary`
|
||||
|
||||
### Missing photos
|
||||
|
||||
osxphotos works by copying photos out of the Photos library folder to export them. You may see osxphotos report that one or more photos are missing and thus could not be exported. One possible reason for this is that you are using iCloud to synch your Photos library and Photos either hasn't yet synched the cloud library to the local Mac or you have Photos configured to "Optimize Mac Storage" in Photos Preferences. Another reason is that even if you have Photos configured to download originals to the Mac, Photos does not always download photos from shared albums or original screenshots to the Mac.
|
||||
|
||||
If you encounter missing photos you can tell osxphotos to download the missing photos from iCloud using the `--download-missing` option. `--download-missing` uses AppleScript to communicate with Photos and tell it to download the missing photos. Photos' AppleScript interface is somewhat buggy and you may find that Photos crashes. In this case, osxphotos will attempt to restart Photos to resume the download process. There's also an experimental `--use-photokit` option that will communicate with Photos using a different "PhotoKit" interface. This option must be used together with `--download-missing`:
|
||||
|
||||
`osxphotos export /path/to/export --download-missing`
|
||||
|
||||
`osxphotos export /path/to/export --download-missing --use-photokit`
|
||||
|
||||
### Exporting to external disks
|
||||
|
||||
If you are exporting to an external network attached storage (NAS) device, you may encounter errors if the network connection is unreliable. In this case, you can use the `--retry` option so that osxphotos will automatically retry the export. Use `--retry` with a number that specifies the number of times to retry the export:
|
||||
|
||||
`osxphotos export /path/to/export --retry 3`
|
||||
|
||||
In this example, osxphotos will attempt to export a photo up to 3 times if it encounters an error.
|
||||
|
||||
### Exporting metadata with exported photos
|
||||
|
||||
Photos tracks a tremendous amount of metadata associated with photos in the library such as keywords, faces and persons, reverse geolocation data, and image classification labels. Photos' native export capability does not preserve most of this metadata. osxphotos can, however, access and preserve almost all the metadata associated with photos. Using the free [`exiftool`](https://exiftool.org/) app, osxphotos can write metadata to exported photos. Follow the instructions on the exiftool website to install exiftool then you can use the `--exiftool` option to write metadata to exported photos:
|
||||
|
||||
`osxphotos export /path/to/export --exiftool`
|
||||
|
||||
This will write basic metadata such as keywords, persons, and GPS location to the exported files. osxphotos includes several additional options that can be used in conjunction with `--exiftool` to modify the metadata that is written by `exiftool`. For example, you can use the `--keyword-template` option to specify custom keywords (again, via the osxphotos template system). For example, to use the folder and album a photo is in to create hierarchal keywords in the format used by Lightroom Classic:
|
||||
|
||||
```txt
|
||||
osxphotos export /path/to/export --exiftool --keyword-template "{folder_album(>)}"
|
||||
│ │
|
||||
│ │
|
||||
folder_album results in the folder(s) <──┘ │
|
||||
and album a photo is contained in │
|
||||
│
|
||||
The value in () is used as the path separator <───────┘
|
||||
for joining the folders and albums. For example,
|
||||
if photo is in Folder1/Folder2/Album, (>) produces
|
||||
"Folder1>Folder2>Album" which some programs, such as
|
||||
Lightroom Classic, treat as hierarchal keywords
|
||||
```
|
||||
|
||||
The above command will write all the regular metadata that `--exiftool` normally writes to the file upon export but will also add an additional keyword in the exported metadata in the form "Folder1>Folder2>Album". If you did not include the `(>)` in the template string (e.g. `{folder_album}`), folder_album would render in form "Folder1/Folder2/Album".
|
||||
|
||||
A powerful feature of Photos is that it uses machine learning algorithms to automatically classify or label photos. These labels are used when you search for images in Photos but are not otherwise available to the user. osxphotos is able to read all the labels associated with a photo and makes those available through the template system via the `{label}`. Think of these as automatic keywords as opposed to the keywords you assign manually in Photos. One common use case is to use the automatic labels to create new keywords when exporting images so that these labels are embedded in the image's metadata:
|
||||
|
||||
`osxphotos export /path/to/export --exiftool --keyword-template "{label}"`
|
||||
|
||||
**Note**: When evaluating templates for `--directory` and `--filename`, osxphotos inserts the automatic default value "_" for any template field which is null (empty or blank). This is to ensure that there's never a null directory or filename created. For metadata templates such as `--keyword-template`, osxphotos does not provide an automatic default value thus if the template field is null, no keyword would be created. Of course, you can provide a default value if desired and osxphotos will use this. For example, to add "nolabel" as a keyword for any photo that doesn't have labels:
|
||||
|
||||
`osxphotos export /path/to/export --exiftool --keyword-template "{label,nolabel}"`
|
||||
|
||||
### Sidecar files
|
||||
|
||||
Another way to export metadata about your photos is through the use of sidecar files. These are files that have the same name as your photo (but with a different extension) and carry the metadata. Many digital asset management applications (for example, PhotoPrism, Lightroom, Digikam, etc.) can read or write sidecar files. osxphotos can export metadata in exiftool compatible JSON and XMP formats using the `--sidecar` option. For example, to output metadata to XMP sidecars:
|
||||
|
||||
`osxphotos export /path/to/export --sidecar XMP`
|
||||
|
||||
Unlike `--exiftool`, you do not need to install exiftool to use the `--sidecar` feature. Many of the same configuration options that apply to `--exiftool` to modify metadata, for example, `--keyword-template` can also be used with `--sidecar`.
|
||||
|
||||
Sidecar files are named "photoname.ext.sidecar_ext". For example, if the photo is named `IMG_1234.JPG` and the sidecar format is XMP, the sidecar would be named `IMG_1234.JPG.XMP`. Some applications expect the sidecar in this case to be named `IMG_1234.XMP`. You can use the `-sidecar-drop-ext` option to force osxphotos to name the sidecar files in this manner:
|
||||
|
||||
`osxphotos export /path/to/export --sidecar XMP -sidecar-drop-ext`
|
||||
|
||||
### Updating a previous export
|
||||
|
||||
If you want to use osxphotos to perform periodic backups of your Photos library rather than a one-time export, use the `--update` option. When `osxphotos export` is run, it creates a database file named `.osxphotos_export.db` in the export folder. (**Note** Because the filename starts with a ".", you won't see it in Finder which treats "dot-files" like this as hidden. You will see the file in the Terminal.) . If you run osxphotos with the `--update` option, it will look for this database file and, if found, use it to retrieve state information from the last time it was run to only export new or changed files. For example:
|
||||
|
||||
`osxphotos export /path/to/export --update`
|
||||
|
||||
will read the export database located in `/path/to/export/.osxphotos_export.db` and only export photos that have been added or changed since the last time osxphotos was run. You can run osxphotos with the `--update` option even if it's never been run before. If the database isn't found, osxphotos will create it. If you run `osxphotos export` without `--update` in a folder where you had previously exported photos, it will re-export all the photos. If your intent is to keep a periodic backup of your Photos Library up to date with osxphotos, you should always use `--update`.
|
||||
|
||||
If your workflow involves moving files out of the export directory (for example, you move them into a digital asset management app) but you want to use the features of `--update`, you can use the `--only-new` with `--update` to force osxphotos to only export photos that are new (added to the library) since the last update. In this case, osxphotos will ignore the previously exported files that are now missing. Without `--only-new`, osxphotos would see that previously exported files are missing and re-export them.
|
||||
|
||||
`osxphotos export /path/to/export --update --only-new`
|
||||
|
||||
If your workflow involves editing the images you exported from Photos but you still want to maintain a backup with `--update`, you should use the `--ignore-signature` option. `--ignore-signature` instructs osxphotos to ignore the file's signature (for example, size and date modified) when deciding which files should be updated with `--update`. If you edit a file in the export directory and then run `--update` without `--ignore-signature`, osxphotos will see that the file is different than the one in the Photos library and re-export it.
|
||||
|
||||
`osxphotos export /path/to/export --update --ignore-signature`
|
||||
|
||||
### Dry Run
|
||||
|
||||
You can use the `--dry-run` option to have osxphotos "dry run" or test an export without actually exporting any files. When combined with the `--verbose` option, which causes osxphotos to print out details of every file being exported, this can be a useful tool for testing your export options before actually running a full export. For example, if you are learning the template system and want to verify that your `--directory` and `--filename` templates are correct, `--dry-run --verbose` will print out the name of each file being exported.
|
||||
|
||||
`osxphotos export /path/to/export --dry-run --verbose`
|
||||
|
||||
### Creating a report of all exported files
|
||||
|
||||
You can use the `--report` option to create a report, in comma-separated values (CSV) format that will list the details of all files that were exported, skipped, missing, etc. This file format is compatible with programs such as Microsoft Excel. Provide the name of the report after the `--report` option:
|
||||
|
||||
`osxphotos export /path/to/export --report export.csv`
|
||||
|
||||
### Exporting only certain photos
|
||||
|
||||
By default, osxphotos will export your entire Photos library. If you want to export only certain photos, osxphotos provides a rich set of "query options" that allow you to query the Photos database to filter out only certain photos that match your query criteria. The tutorial does not cover all the query options as there are over 50 of them--read the help text (`osxphotos help export`) to better understand the available query options. No matter which subset of photos you would like to export, there is almost certainly a way for osxphotos to filter these. For example, you can filter for only images that contain certain keywords or images without a title, images from a specific time of day or specific date range, images contained in specific albums, etc.
|
||||
|
||||
For example, to export only photos with keyword `Travel`:
|
||||
|
||||
`osxphotos export /path/to/export --keyword "Travel"`
|
||||
|
||||
Like many options in osxphotos, `--keyword` (and most other query options) can be repeated to search for more than one term. For example, to find photos with keyword `Travel` *or* keyword `Vacation`:
|
||||
|
||||
`osxphotos export /path/to/export --keyword "Travel" --keyword "Vacation"`
|
||||
|
||||
To export only photos contained in the album "Summer Vacation":
|
||||
|
||||
`osxphotos export /path/to/export --album "Summer Vacation"`
|
||||
|
||||
There are also a number of query options to export only certain types of photos. For example, to export only photos taken with iPhone "Portrait Mode":
|
||||
|
||||
`osxphotos export /path/to/export --portrait`
|
||||
|
||||
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"`
|
||||
|
||||
### 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:
|
||||
|
||||
`osxphotos export /path/to/export --convert-to-jpeg --jpeg-quality 0.9`
|
||||
|
||||
### Finder attributes
|
||||
|
||||
In addition to using `exiftool` to write metadata directly to the image metadata, osxphotos can write certain metadata that is available to the Finder and Spotlight but does not modify the actual image file. This is done through something called extended attributes which are stored in the filesystem with a file but do not actually modify the file itself. Finder tags and Finder comments are common examples of these.
|
||||
|
||||
osxphotos can, for example, write any keywords in the image to Finder tags so that you can search for images in Spotlight or the Finder using the `tag:tagname` syntax:
|
||||
|
||||
`osxphotos export /path/to/export --finder-tag-keywords`
|
||||
|
||||
`--finder-tag-keywords` also works with `--keyword-template` as described above in the section on `exiftool`:
|
||||
|
||||
`osxphotos export /path/to/export --finder-tag-keywords --keyword-template "{label}"`
|
||||
|
||||
The `--xattr-template` option allows you to set a variety of other extended attributes. It is used in the format `--xattr-template ATTRIBUTE TEMPLATE` where ATTRIBUTE is one of 'authors','comment', 'copyright', 'description', 'findercomment', 'headline', 'keywords'.
|
||||
|
||||
For example, to set Finder comment to the photo's title and description:
|
||||
|
||||
`osxphotos export /path/to/export --xattr-template findercomment "{title}{newline}{descr}"`
|
||||
|
||||
In the template string above, `{newline}` instructs osxphotos to insert a new line character ("\n") between the title and description. In this example, if `{title}` or `{descr}` is empty, you'll get "title\n" or "\ndescription" which may not be desired so you can use more advanced features of the template system to handle these cases:
|
||||
|
||||
`osxphotos export /path/to/export --xattr-template findercomment "{title}{title?{descr?{newline},},}{descr}"`
|
||||
|
||||
Explanation of the template string:
|
||||
|
||||
```txt
|
||||
{title}{title?{descr?{newline},},}{descr}
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ │ │ │ │
|
||||
└──> insert title │ │ │ │ │
|
||||
│ │ │ │ │ │
|
||||
└───> is there a title?
|
||||
│ │ │ │ │
|
||||
└───> if so, is there a description?
|
||||
│ │ │ │
|
||||
└───> if so, insert new line
|
||||
│ │ │
|
||||
└───> if descr is blank, insert nothing
|
||||
│ │
|
||||
└───> if title is blank, insert nothing
|
||||
│
|
||||
└───> finally, insert description
|
||||
```
|
||||
|
||||
In this example, `title?` demonstrates use of the boolean (True/False) feature of the template system. `title?` is read as "Is the title True (or not blank/empty)? If so, then the value immediately following the `?` is used in place of `title`. If `title` is blank, then the value immediately following the comma is used instead. The format for boolean fields is `field?value if true,value if false`. Either `value if true` or `value if false` may be blank, in which case a blank string ("") is used for the value and both may also be an entirely new template string as seen in the above example. Using this format, template strings may be nested inside each other to form complex `if-then-else` statements.
|
||||
|
||||
The above example, while complex to read, shows how flexible the osxphotos template system is. If you invest a little time learning how to use the template system you can easily handle almost any use case you have.
|
||||
|
||||
See Extended Attributes section in the help for `osxphotos export` for additional information about this feature.
|
||||
|
||||
### Saving and loading options
|
||||
|
||||
If you repeatedly run a complex osxphotos export command (for example, to regularly back-up your Photos library), you can save all the options to a configuration file for future use (`--save-config FILE`) and then load them (`--load-config FILE`) instead of repeating each option on the command line.
|
||||
|
||||
To save the configuration:
|
||||
|
||||
`osxphotos export /path/to/export <all your options here> --update --save-config osxphotos.toml`
|
||||
|
||||
Then the next to you run osxphotos, you can simply do this:
|
||||
|
||||
`osxphotos export /path/to/export --load-config osxphotos.toml`
|
||||
|
||||
The configuration file is a plain text file in [TOML](https://toml.io/en/) format so the `.toml` extension is standard but you can name the file anything you like.
|
||||
|
||||
### An example from an actual osxphotos user
|
||||
|
||||
Here's a comprehensive use case from an actual osxphotos user that integrates many of the concepts discussed in this tutorial (thank-you Philippe for contributing this!):
|
||||
|
||||
I usually import my iPhone’s photo roll on a more or less regular basis, and it
|
||||
includes photos and videos. As a result, the size ot my Photos library may rise
|
||||
very quickly. Nevertheless, I will tag and geolocate everything as Photos has a
|
||||
quite good keyword management system.
|
||||
|
||||
After a while, I want to take most of the videos out of the library and move them
|
||||
to a separate "videos" folder on a different folder / volume. As I might want to
|
||||
use them in Final Cut Pro, and since Final Cut is able to import Finder tags into
|
||||
its internal library tagging system, I will use osxphotos to do just this.
|
||||
|
||||
Picking the videos can be left to Photos, using a smart folder for instance. Then
|
||||
just add a keyword to all videos to be processed. Here I chose "Quik" as I wanted
|
||||
to spot all videos created on my iPhone using the Quik application (now part of
|
||||
GoPro).
|
||||
|
||||
I want to retrieve my keywords only and make sure they populate the Finder tags, as
|
||||
well as export all the persons identified in the videos by Photos. I also want to
|
||||
merge any keywords or persons already in the video metadata with the exported
|
||||
metadata.
|
||||
|
||||
Keeping Photo’s edited titles and descriptions and putting both in the Finder
|
||||
comments field in a readable manner is also enabled.
|
||||
|
||||
And I want to keep the file’s creation date (using `--touch-file`).
|
||||
|
||||
Finally, use `--strip` to remove any leading or trailing whitespace from processed
|
||||
template fields.
|
||||
|
||||
`osxphotos export ~/Desktop/folder for exported videos/ --keyword Quik --only-movies --db /path to my.photoslibrary --touch-file --finder-tag-keywords --person-keyword --xattr-template findercomment "{title}{title?{descr?{newline},},}{descr}" --exiftool-merge-keywords --exiftool-merge-persons --exiftool --strip`
|
||||
|
||||
### Conclusion
|
||||
|
||||
osxphotos is very flexible. If you merely want to backup your Photos library, then spending a few minutes to understand the `--directory` option is likely all you need and you can be up and running in minutes. However, if you have a more complex workflow, osxphotos likely provides options to implement your workflow. This tutorial does not attempt to cover every option offered by osxphotos but hopefully it provides a good understanding of what kinds of things are possible and where to explore if you want to learn more.
|
||||
@@ -1,455 +0,0 @@
|
||||
.. role:: raw-html-m2r(raw)
|
||||
:format: html
|
||||
|
||||
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<!-- OSXPHOTOS-TUTORIAL-HEADER:START -->
|
||||
|
||||
|
||||
|
||||
osxphotos Tutorial
|
||||
==================
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<!-- OSXPHOTOS-TUTORIAL-HEADER:END -->
|
||||
|
||||
|
||||
|
||||
The design philosophy for osxphotos is "make the easy things easy and make the hard things possible". To "make the hard things possible", osxphotos is very flexible and has many, many configuration options -- the ``export`` command for example, has over 100 command line options. Thus, osxphotos may seem daunting at first. The purpose of this tutorial is to explain a number of common use cases with examples and, hopefully, make osxphotos less daunting to use. osxphotos includes several commands for retrieving information from your Photos library but the one most users are interested in is the ``export`` command which exports photos from the library so that's the focus of this tutorial.
|
||||
|
||||
Export your photos
|
||||
------------------
|
||||
|
||||
``osxphotos export /path/to/export``
|
||||
|
||||
This command exports all your photos to the ``/path/to/export`` directory.
|
||||
|
||||
**Note**\ : osxphotos uses the term 'photo' to refer to a generic media asset in your Photos Library. A photo may be an image, a video file, a combination of still image and video file (e.g. an Apple "Live Photo" which is an image and an associated "live preview" video file), a JPEG image with an associated RAW image, etc.
|
||||
|
||||
Export by date
|
||||
--------------
|
||||
|
||||
While the previous command will export all your photos (and videos--see note above), it probably doesn't do exactly what you want. In the previous example, all the photos will be exported to a single folder: ``/path/to/export``. If you have a large library with thousands of images and videos, this likely isn't very useful. You can use the ``--export-by-date`` option to export photos to a folder structure organized by year, month, day, e.g. ``2021/04/21``\ :
|
||||
|
||||
``osxphotos export /path/to/export --export-by-date``
|
||||
|
||||
With this command, a photo that was created on 31 May 2015 would be exported to: ``/path/to/export/2015/05/31``
|
||||
|
||||
Specify directory structure
|
||||
---------------------------
|
||||
|
||||
If you prefer a different directory structure for your exported images, osxphotos provides a very flexible :raw-html-m2r:`<!-- OSXPHOTOS-TEMPLATE-SYSTEM-LINK:START -->`\ template system\ :raw-html-m2r:`<!-- OSXPHOTOS-TEMPLATE-SYSTEM-LINK:END -->` that allows you to specify the directory structure using the ``--directory`` option. For example, this command exported to a directory structure that looks like: ``2015/May`` (4-digit year / month name):
|
||||
|
||||
``osxphotos export /path/to/export --directory "{created.year}/{created.month}"``
|
||||
|
||||
The string following ``--directory`` is an ``osxphotos template string``. Template strings are widely used throughout osxphotos and it's worth your time to learn more about them. In a template string, the values between the curly braces, e.g. ``{created.year}`` are replaced with metadata from the photo being exported. In this case, ``{created.year}`` is the 4-digit year of the photo's creation date and ``{created.month}`` is the full month name in the user's locale (e.g. ``May``\ , ``mai``\ , etc.). In the osxphotos template system these are referred to as template fields. The text not included between ``{}`` pairs is interpreted literally, in this case ``/``\ , is a directory separator.
|
||||
|
||||
osxphotos provides access to almost all the metadata known to Photos about your images. For example, Photos performs reverse geolocation lookup on photos that contain GPS coordinates to assign place names to the photo. Using the ``--directory`` template, you could thus export photos organized by country name:
|
||||
|
||||
``osxphotos export /path/to/export --directory "{created.year}/{place.name.country}"``
|
||||
|
||||
Of course, some photos might not have an associated place name so the template system allows you specify a default value to use if a template field is null (has no value).
|
||||
|
||||
``osxphotos export /path/to/export --directory "{created.year}/{place.name.country,No-Country}"``
|
||||
|
||||
The value after the ',' in the template string is the default value, in this case 'No-Country'. **Note**\ : If you don't specify a default value and a template field is null, osxphotos will use "_" (underscore character) as the default.
|
||||
|
||||
Some template fields, such as ``{keyword}``\ , may expand to more than one value. For example, if a photo has keywords of "Travel" and "Vacation", ``{keyword}`` would expand to "Travel", "Vacation". When used with ``--directory``\ , this would result in the photo being exported to more than one directory (thus more than one copy of the photo would be exported). For example, if ``IMG_1234.JPG`` has keywords ``Travel``\ , and ``Vacation`` and you run the following command:
|
||||
|
||||
``osxphotos export /path/to/export --directory "{keyword}"``
|
||||
|
||||
the exported files would be:
|
||||
|
||||
.. code-block::
|
||||
|
||||
/path/to/export/Travel/IMG_1234.JPG
|
||||
/path/to/export/Vacation/IMG_1234.JPG
|
||||
|
||||
|
||||
Specify exported filename
|
||||
-------------------------
|
||||
|
||||
By default, osxphotos will use the original filename of the photo when exporting. That is, the filename the photo had when it was taken or imported into Photos. This is often something like ``IMG_1234.JPG`` or ``DSC05678.dng``. osxphotos allows you to specify a custom filename template using the ``--filename`` option in the same way as ``--directory`` allows you to specify a custom directory name. For example, Photos allows you specify a title or caption for a photo and you can use this in place of the original filename:
|
||||
|
||||
``osxphotos export /path/to/export --filename "{title}"``
|
||||
|
||||
The above command will export photos using the title. Note that you don't need to specify the extension as part of the ``--filename`` template as osxphotos will automatically add the correct file extension. Some photos might not have a title so in this case, you could use the default value feature to specify a different name for these photos. For example, to use the title as the filename, but if no title is specified, use the original filename instead:
|
||||
|
||||
.. code-block::
|
||||
|
||||
osxphotos export /path/to/export --filename "{title,{original_name}}"
|
||||
│ ││ │
|
||||
│ ││ │
|
||||
Use photo's title as the filename <──────┘ ││ │
|
||||
││ │
|
||||
Value after comma will be used <───────┘│ │
|
||||
if title is blank │ │
|
||||
│ │
|
||||
The default value can be <────┘ │
|
||||
another template field │
|
||||
│
|
||||
Use photo's original name if no title <──────┘
|
||||
|
||||
|
||||
The osxphotos template system also allows for limited conditional logic of the type "If a condition is true then do one thing, otherwise, do a different thing". For example, you can use the ``--filename`` option to name files that are marked as "Favorites" in Photos differently than other files. For example, to add a "#" to the name of every photo that's a favorite:
|
||||
|
||||
.. code-block::
|
||||
|
||||
osxphotos export /path/to/export --filename "{original_name}{favorite?#,}"
|
||||
│ │ │││
|
||||
│ │ │││
|
||||
Use photo's original name as filename <──┘ │ │││
|
||||
│ │││
|
||||
'favorite' is True if photo is a Favorite, <───────┘ │││
|
||||
otherwise, False │││
|
||||
│││
|
||||
'?' specifies a conditional <─────────────┘││
|
||||
││
|
||||
Value immediately following ? will be used if <──────┘│
|
||||
preceding template field is True or non-blank │
|
||||
│
|
||||
Value immediately following comma will be used if <──────┘
|
||||
template field is False or blank (null); in this case
|
||||
no value is specified so a blank string "" will be used
|
||||
|
||||
|
||||
Like with ``--directory``\ , using a multi-valued template field such as ``{keyword}`` may result in more than one copy of a photo being exported. For example, if ``IMG_1234.JPG`` has keywords ``Travel``\ , and ``Vacation`` and you run the following command:
|
||||
|
||||
``osxphotos export /path/to/export --filename "{keyword}-{original_name}"``
|
||||
|
||||
the exported files would be:
|
||||
|
||||
.. code-block::
|
||||
|
||||
/path/to/export/Travel-IMG_1234.JPG
|
||||
/path/to/export/Vacation-IMG_1234.JPG
|
||||
|
||||
|
||||
Edited photos
|
||||
-------------
|
||||
|
||||
If a photo has been edited in Photos (e.g. cropped, adjusted, etc.) there will be both an original image and an edited image in the Photos Library. By default, osxphotos will export both the original and the edited image. To distinguish between them, osxphotos will append "_edited" to the edited image. For example, if the original image was named ``IMG_1234.JPG``\ , osxphotos will export the original as ``IMG_1234.JPG`` and the edited version as ``IMG_1234_edited.jpeg``. **Note:** Photos changes the extension of edited images to ".jpeg" even if the original was named ".JPG". You can change the suffix appended to edited images using the ``--edited-suffix`` option:
|
||||
|
||||
``osxphotos export /path/to/export --edited-suffix "_EDIT"``
|
||||
|
||||
In this example, the edited image would be named ``IMG_1234_EDIT.jpeg``. Like many options in osxphotos, the ``--edited-suffix`` option can evaluate an osxphotos template string so you could append the modification date (the date the photo was edited) to all edited photos using this command:
|
||||
|
||||
``osxphotos export /path/to/export --edited-suffix "_{modified.year}-{modified.mm}-{modified.dd}"``
|
||||
|
||||
In this example, if the photo was edited on 21 April 2021, the name of the exported file would be: ``IMG_1234_2021-04-21.jpeg``.
|
||||
|
||||
You can tell osxphotos to not export edited photos (that is, only export the original unedited photos) using ``--skip-edited``\ :
|
||||
|
||||
``osxphotos export /path/to/export --skip-edited``
|
||||
|
||||
You can also tell osxphotos to export either the original photo (if the photo has not been edited) or the edited photo (if it has been edited), but not both, using the ``--skip-original-if-edited`` option:
|
||||
|
||||
``osxphotos export /path/to/export --skip-original-if-edited``
|
||||
|
||||
As mentioned above, Photos renames JPEG images that have been edited with the ".jpeg" extension. Some applications use ".JPG" and others use ".jpg" or ".JPEG". You can use the ``--jpeg-ext`` option to have osxphotos rename all JPEG files with the same extension. Valid values are jpeg, jpg, JPEG, JPG; e.g. ``--jpeg-ext jpg`` to use '.jpg' for all JPEGs.
|
||||
|
||||
``osxphotos export /path/to/export --jpeg-ext jpg``
|
||||
|
||||
Specifying the Photos library
|
||||
-----------------------------
|
||||
|
||||
All the above commands operate on the default Photos library. Most users only use a single Photos library which is also known as the System Photo Library. It is possible to use Photos with more than one library. For example, if you hold down the "Option" key while opening Photos, you can select an alternate Photos library. If you don't specify which library to use, osxphotos will try find the last opened library. Occasionally it can't determine this and in that case, it will use the System Photos Library. If you use more than one Photos library and want to explicitly specify which library to use, you can do so with the ``--db`` option. (db is short for database and is so named because osxphotos operates on the database that Photos uses to manage your Photos library).
|
||||
|
||||
``osxphotos export /path/to/export --db ~/Pictures/MyAlternateLibrary.photoslibrary``
|
||||
|
||||
Missing photos
|
||||
--------------
|
||||
|
||||
osxphotos works by copying photos out of the Photos library folder to export them. You may see osxphotos report that one or more photos are missing and thus could not be exported. One possible reason for this is that you are using iCloud to synch your Photos library and Photos either hasn't yet synched the cloud library to the local Mac or you have Photos configured to "Optimize Mac Storage" in Photos Preferences. Another reason is that even if you have Photos configured to download originals to the Mac, Photos does not always download photos from shared albums or original screenshots to the Mac.
|
||||
|
||||
If you encounter missing photos you can tell osxphotos to download the missing photos from iCloud using the ``--download-missing`` option. ``--download-missing`` uses AppleScript to communicate with Photos and tell it to download the missing photos. Photos' AppleScript interface is somewhat buggy and you may find that Photos crashes. In this case, osxphotos will attempt to restart Photos to resume the download process. There's also an experimental ``--use-photokit`` option that will communicate with Photos using a different "PhotoKit" interface. This option must be used together with ``--download-missing``\ :
|
||||
|
||||
``osxphotos export /path/to/export --download-missing``
|
||||
|
||||
``osxphotos export /path/to/export --download-missing --use-photokit``
|
||||
|
||||
Exporting to external disks
|
||||
---------------------------
|
||||
|
||||
If you are exporting to an external network attached storage (NAS) device, you may encounter errors if the network connection is unreliable. In this case, you can use the ``--retry`` option so that osxphotos will automatically retry the export. Use ``--retry`` with a number that specifies the number of times to retry the export:
|
||||
|
||||
``osxphotos export /path/to/export --retry 3``
|
||||
|
||||
In this example, osxphotos will attempt to export a photo up to 3 times if it encounters an error.
|
||||
|
||||
In addition to ``--retry``\ , the ``--exportdb`` and ``--ramdb`` may improve performance when exporting to an external disk or a NAS. When osxphotos exports photos, it creates an export database file named ``.osxphotos_export.db`` in the export folder which osxphotos uses to keep track of which photos have been exported. This allows you to restart and export and to use ``--update`` to update an existing export. If the connection to the export location is slow or flaky, having the export database located on the export disk may decrease performance. In this case, you can use ``--exportdb DBPATH`` to instruct osxphotos to store the export database at DBPATH. If using this option, I recommend putting the export database on your Mac system disk (for example, in your home directory). If you intend to use ``--update`` to update the export in the future, you must remember where the export database is and use the ``--exportdb`` option every time you update the export.
|
||||
|
||||
Another alternative to using ``--exportdb`` is to use ``--ramdb``. This option instructs osxphotos to use a RAM database instead of a file on disk. The RAM database is much faster than the file on disk and doesn't require osxphotos to access the network drive to query or write to the database. When osxphotos completes the export it will write the RAM database to the export location. This can offer a significant performance boost but you will lose state information if osxphotos crashes or is interrupted during export.
|
||||
|
||||
Exporting metadata with exported photos
|
||||
---------------------------------------
|
||||
|
||||
Photos tracks a tremendous amount of metadata associated with photos in the library such as keywords, faces and persons, reverse geolocation data, and image classification labels. Photos' native export capability does not preserve most of this metadata. osxphotos can, however, access and preserve almost all the metadata associated with photos. Using the free `\ ``exiftool`` <https://exiftool.org/>`_ app, osxphotos can write metadata to exported photos. Follow the instructions on the exiftool website to install exiftool then you can use the ``--exiftool`` option to write metadata to exported photos:
|
||||
|
||||
``osxphotos export /path/to/export --exiftool``
|
||||
|
||||
This will write basic metadata such as keywords, persons, and GPS location to the exported files. osxphotos includes several additional options that can be used in conjunction with ``--exiftool`` to modify the metadata that is written by ``exiftool``. For example, you can use the ``--keyword-template`` option to specify custom keywords (again, via the osxphotos template system). For example, to use the folder and album a photo is in to create hierarchal keywords in the format used by Lightroom Classic:
|
||||
|
||||
.. code-block::
|
||||
|
||||
osxphotos export /path/to/export --exiftool --keyword-template "{folder_album(>)}"
|
||||
│ │
|
||||
│ │
|
||||
folder_album results in the folder(s) <──┘ │
|
||||
and album a photo is contained in │
|
||||
│
|
||||
The value in () is used as the path separator <───────┘
|
||||
for joining the folders and albums. For example,
|
||||
if photo is in Folder1/Folder2/Album, (>) produces
|
||||
"Folder1>Folder2>Album" which some programs, such as
|
||||
Lightroom Classic, treat as hierarchal keywords
|
||||
|
||||
|
||||
The above command will write all the regular metadata that ``--exiftool`` normally writes to the file upon export but will also add an additional keyword in the exported metadata in the form "Folder1>Folder2>Album". If you did not include the ``(>)`` in the template string (e.g. ``{folder_album}``\ ), folder_album would render in form "Folder1/Folder2/Album".
|
||||
|
||||
A powerful feature of Photos is that it uses machine learning algorithms to automatically classify or label photos. These labels are used when you search for images in Photos but are not otherwise available to the user. osxphotos is able to read all the labels associated with a photo and makes those available through the template system via the ``{label}``. Think of these as automatic keywords as opposed to the keywords you assign manually in Photos. One common use case is to use the automatic labels to create new keywords when exporting images so that these labels are embedded in the image's metadata:
|
||||
|
||||
``osxphotos export /path/to/export --exiftool --keyword-template "{label}"``
|
||||
|
||||
**Note**\ : When evaluating templates for ``--directory`` and ``--filename``\ , osxphotos inserts the automatic default value "_" for any template field which is null (empty or blank). This is to ensure that there's never a null directory or filename created. For metadata templates such as ``--keyword-template``\ , osxphotos does not provide an automatic default value thus if the template field is null, no keyword would be created. Of course, you can provide a default value if desired and osxphotos will use this. For example, to add "nolabel" as a keyword for any photo that doesn't have labels:
|
||||
|
||||
``osxphotos export /path/to/export --exiftool --keyword-template "{label,nolabel}"``
|
||||
|
||||
Sidecar files
|
||||
-------------
|
||||
|
||||
Another way to export metadata about your photos is through the use of sidecar files. These are files that have the same name as your photo (but with a different extension) and carry the metadata. Many digital asset management applications (for example, PhotoPrism, Lightroom, Digikam, etc.) can read or write sidecar files. osxphotos can export metadata in exiftool compatible JSON and XMP formats using the ``--sidecar`` option. For example, to output metadata to XMP sidecars:
|
||||
|
||||
``osxphotos export /path/to/export --sidecar XMP``
|
||||
|
||||
Unlike ``--exiftool``\ , you do not need to install exiftool to use the ``--sidecar`` feature. Many of the same configuration options that apply to ``--exiftool`` to modify metadata, for example, ``--keyword-template`` can also be used with ``--sidecar``.
|
||||
|
||||
Sidecar files are named "photoname.ext.sidecar_ext". For example, if the photo is named ``IMG_1234.JPG`` and the sidecar format is XMP, the sidecar would be named ``IMG_1234.JPG.XMP``. Some applications expect the sidecar in this case to be named ``IMG_1234.XMP``. You can use the ``-sidecar-drop-ext`` option to force osxphotos to name the sidecar files in this manner:
|
||||
|
||||
``osxphotos export /path/to/export --sidecar XMP -sidecar-drop-ext``
|
||||
|
||||
Updating a previous export
|
||||
--------------------------
|
||||
|
||||
If you want to use osxphotos to perform periodic backups of your Photos library rather than a one-time export, use the ``--update`` option. When ``osxphotos export`` is run, it creates a database file named ``.osxphotos_export.db`` in the export folder. (\ **Note** Because the filename starts with a ".", you won't see it in Finder which treats "dot-files" like this as hidden. You will see the file in the Terminal.) . If you run osxphotos with the ``--update`` option, it will look for this database file and, if found, use it to retrieve state information from the last time it was run to only export new or changed files. For example:
|
||||
|
||||
``osxphotos export /path/to/export --update``
|
||||
|
||||
will read the export database located in ``/path/to/export/.osxphotos_export.db`` and only export photos that have been added or changed since the last time osxphotos was run. You can run osxphotos with the ``--update`` option even if it's never been run before. If the database isn't found, osxphotos will create it. If you run ``osxphotos export`` without ``--update`` in a folder where you had previously exported photos, it will re-export all the photos. If your intent is to keep a periodic backup of your Photos Library up to date with osxphotos, you should always use ``--update``.
|
||||
|
||||
If your workflow involves moving files out of the export directory (for example, you move them into a digital asset management app) but you want to use the features of ``--update``\ , you can use the ``--only-new`` with ``--update`` to force osxphotos to only export photos that are new (added to the library) since the last update. In this case, osxphotos will ignore the previously exported files that are now missing. Without ``--only-new``\ , osxphotos would see that previously exported files are missing and re-export them.
|
||||
|
||||
``osxphotos export /path/to/export --update --only-new``
|
||||
|
||||
If your workflow involves editing the images you exported from Photos but you still want to maintain a backup with ``--update``\ , you should use the ``--ignore-signature`` option. ``--ignore-signature`` instructs osxphotos to ignore the file's signature (for example, size and date modified) when deciding which files should be updated with ``--update``. If you edit a file in the export directory and then run ``--update`` without ``--ignore-signature``\ , osxphotos will see that the file is different than the one in the Photos library and re-export it.
|
||||
|
||||
``osxphotos export /path/to/export --update --ignore-signature``
|
||||
|
||||
Dry Run
|
||||
-------
|
||||
|
||||
You can use the ``--dry-run`` option to have osxphotos "dry run" or test an export without actually exporting any files. When combined with the ``--verbose`` option, which causes osxphotos to print out details of every file being exported, this can be a useful tool for testing your export options before actually running a full export. For example, if you are learning the template system and want to verify that your ``--directory`` and ``--filename`` templates are correct, ``--dry-run --verbose`` will print out the name of each file being exported.
|
||||
|
||||
``osxphotos export /path/to/export --dry-run --verbose``
|
||||
|
||||
Creating a report of all exported files
|
||||
---------------------------------------
|
||||
|
||||
You can use the ``--report`` option to create a report, in comma-separated values (CSV) format that will list the details of all files that were exported, skipped, missing, etc. This file format is compatible with programs such as Microsoft Excel. Provide the name of the report after the ``--report`` option:
|
||||
|
||||
``osxphotos export /path/to/export --report export.csv``
|
||||
|
||||
Exporting only certain photos
|
||||
-----------------------------
|
||||
|
||||
By default, osxphotos will export your entire Photos library. If you want to export only certain photos, osxphotos provides a rich set of "query options" that allow you to query the Photos database to filter out only certain photos that match your query criteria. The tutorial does not cover all the query options as there are over 50 of them--read the help text (\ ``osxphotos help export``\ ) to better understand the available query options. No matter which subset of photos you would like to export, there is almost certainly a way for osxphotos to filter these. For example, you can filter for only images that contain certain keywords or images without a title, images from a specific time of day or specific date range, images contained in specific albums, etc.
|
||||
|
||||
For example, to export only photos with keyword ``Travel``\ :
|
||||
|
||||
``osxphotos export /path/to/export --keyword "Travel"``
|
||||
|
||||
Like many options in osxphotos, ``--keyword`` (and most other query options) can be repeated to search for more than one term. For example, to find photos with keyword ``Travel`` *or* keyword ``Vacation``\ :
|
||||
|
||||
``osxphotos export /path/to/export --keyword "Travel" --keyword "Vacation"``
|
||||
|
||||
To export only photos contained in the album "Summer Vacation":
|
||||
|
||||
``osxphotos export /path/to/export --album "Summer Vacation"``
|
||||
|
||||
In Photos, it's possible to have multiple albums with the same name. In this case, osxphotos would export photos from all albums matching the value passed to ``--album``. If you wanted to export only one of the albums and this album is in a folder, the ``--regex`` option (short for "regular expression"), which does pattern matching, could be used with the ``{folder_album}`` template to match the specific album. For example, if you had a "Summer Vacation" album inside the folder "2018" and also one with the same name inside the folder "2019", you could export just the album "2018/Summer Vacation" using this command:
|
||||
|
||||
``osxphotos export /path/to/export --regex "2018/Summer Vacation" "{folder_album}"``
|
||||
|
||||
This command matches the pattern "2018/Summer Vacation" against the full folder/album path for every photo.
|
||||
|
||||
There are also a number of query options to export only certain types of photos. For example, to export only photos taken with iPhone "Portrait Mode":
|
||||
|
||||
``osxphotos export /path/to/export --portrait``
|
||||
|
||||
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"``
|
||||
|
||||
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:
|
||||
|
||||
``osxphotos export /path/to/export --convert-to-jpeg --jpeg-quality 0.9``
|
||||
|
||||
Finder attributes
|
||||
-----------------
|
||||
|
||||
In addition to using ``exiftool`` to write metadata directly to the image metadata, osxphotos can write certain metadata that is available to the Finder and Spotlight but does not modify the actual image file. This is done through something called extended attributes which are stored in the filesystem with a file but do not actually modify the file itself. Finder tags and Finder comments are common examples of these.
|
||||
|
||||
osxphotos can, for example, write any keywords in the image to Finder tags so that you can search for images in Spotlight or the Finder using the ``tag:tagname`` syntax:
|
||||
|
||||
``osxphotos export /path/to/export --finder-tag-keywords``
|
||||
|
||||
``--finder-tag-keywords`` also works with ``--keyword-template`` as described above in the section on ``exiftool``\ :
|
||||
|
||||
``osxphotos export /path/to/export --finder-tag-keywords --keyword-template "{label}"``
|
||||
|
||||
The ``--xattr-template`` option allows you to set a variety of other extended attributes. It is used in the format ``--xattr-template ATTRIBUTE TEMPLATE`` where ATTRIBUTE is one of 'authors','comment', 'copyright', 'description', 'findercomment', 'headline', 'keywords'.
|
||||
|
||||
For example, to set Finder comment to the photo's title and description:
|
||||
|
||||
``osxphotos export /path/to/export --xattr-template findercomment "{title}{newline}{descr}"``
|
||||
|
||||
In the template string above, ``{newline}`` instructs osxphotos to insert a new line character ("\n") between the title and description. In this example, if ``{title}`` or ``{descr}`` is empty, you'll get "title\n" or "\ndescription" which may not be desired so you can use more advanced features of the template system to handle these cases:
|
||||
|
||||
``osxphotos export /path/to/export --xattr-template findercomment "{title,}{title?{descr?{newline},},}{descr,}"``
|
||||
|
||||
Explanation of the template string:
|
||||
|
||||
.. code-block::
|
||||
|
||||
{title,}{title?{descr?{newline},},}{descr,}
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ │ │ │ │
|
||||
└──> insert title (or nothing if no title)
|
||||
│ │ │ │ │ │
|
||||
└───> is there a title?
|
||||
│ │ │ │ │
|
||||
└───> if so, is there a description?
|
||||
│ │ │ │
|
||||
└───> if so, insert new line
|
||||
│ │ │
|
||||
└───> if descr is blank, insert nothing
|
||||
│ │
|
||||
└───> if title is blank, insert nothing
|
||||
│
|
||||
└───> finally, insert description
|
||||
(or nothing if no description)
|
||||
|
||||
|
||||
In this example, ``title?`` demonstrates use of the boolean (True/False) feature of the template system. ``title?`` is read as "Is the title True (or not blank/empty)? If so, then the value immediately following the ``?`` is used in place of ``title``. If ``title`` is blank, then the value immediately following the comma is used instead. The format for boolean fields is ``field?value if true,value if false``. Either ``value if true`` or ``value if false`` may be blank, in which case a blank string ("") is used for the value and both may also be an entirely new template string as seen in the above example. Using this format, template strings may be nested inside each other to form complex ``if-then-else`` statements.
|
||||
|
||||
The above example, while complex to read, shows how flexible the osxphotos template system is. If you invest a little time learning how to use the template system you can easily handle almost any use case you have.
|
||||
|
||||
See Extended Attributes section in the help for ``osxphotos export`` for additional information about this feature.
|
||||
|
||||
Saving and loading options
|
||||
--------------------------
|
||||
|
||||
If you repeatedly run a complex osxphotos export command (for example, to regularly back-up your Photos library), you can save all the options to a configuration file for future use (\ ``--save-config FILE``\ ) and then load them (\ ``--load-config FILE``\ ) instead of repeating each option on the command line.
|
||||
|
||||
To save the configuration:
|
||||
|
||||
``osxphotos export /path/to/export <all your options here> --update --save-config osxphotos.toml``
|
||||
|
||||
Then the next to you run osxphotos, you can simply do this:
|
||||
|
||||
``osxphotos export /path/to/export --load-config osxphotos.toml``
|
||||
|
||||
The configuration file is a plain text file in `TOML <https://toml.io/en/>`_ format so the ``.toml`` extension is standard but you can name the file anything you like.
|
||||
|
||||
Run commands on exported photos for post-processing
|
||||
---------------------------------------------------
|
||||
|
||||
You can use the ``--post-command`` option to run one or more commands against exported files. The ``--post-command`` option takes two arguments: CATEGORY and COMMAND. CATEGORY is a string that describes which category of file to run the command against. The available categories are described in the help text available via: ``osxphotos help export``. For example, the ``exported`` category includes all exported photos and the ``skipped`` category includes all photos that were skipped when running export with ``--update``. COMMAND is an osxphotos template string which will be rendered then passed to the shell for execution.
|
||||
|
||||
For example, the following command generates a log of all exported files and their associated keywords:
|
||||
|
||||
``osxphotos export /path/to/export --post-command exported "echo {shell_quote,{filepath}{comma}{,+keyword,}} >> {shell_quote,{export_dir}/exported.txt}"``
|
||||
|
||||
The special template field ``{shell_quote}`` ensures a string is properly quoted for execution in the shell. For example, it's possible that a file path or keyword in this example has a space in the value and if not properly quoted, this would cause an error in the execution of the command. When running commands, the template ``{filepath}`` is set to the full path of the exported file and ``{export_dir}`` is set to the full path of the base export directory.
|
||||
|
||||
Explanation of the template string:
|
||||
|
||||
.. code-block::
|
||||
|
||||
{shell_quote,{filepath}{comma}{,+keyword,}}
|
||||
│ │ │ │ │
|
||||
│ │ │ | │
|
||||
└──> quote everything after comma for proper execution in the shell
|
||||
│ │ │ │
|
||||
└───> filepath of the exported file
|
||||
│ │ │
|
||||
└───> insert a comma
|
||||
│ │
|
||||
└───> join the list of keywords together with a ","
|
||||
│
|
||||
└───> if no keywords, insert nothing (empty string: "")
|
||||
|
||||
|
||||
Another example: if you had ``exiftool`` installed and wanted to wipe all metadata from all exported files, you could use the following:
|
||||
|
||||
``osxphotos export /path/to/export --post-command exported "/usr/local/bin/exiftool -all= {filepath|shell_quote}"``
|
||||
|
||||
This command uses the ``|shell_quote`` template filter instead of the ``{shell_quote}`` template because the only thing that needs to be quoted is the path to the exported file. Template filters filter the value of the rendered template field. A number of other filters are available and are described in the help text.
|
||||
|
||||
An example from an actual osxphotos user
|
||||
----------------------------------------
|
||||
|
||||
Here's a comprehensive use case from an actual osxphotos user that integrates many of the concepts discussed in this tutorial (thank-you Philippe for contributing this!):
|
||||
|
||||
.. code-block::
|
||||
|
||||
I usually import my iPhone’s photo roll on a more or less regular basis, and it
|
||||
includes photos and videos. As a result, the size ot my Photos library may rise
|
||||
very quickly. Nevertheless, I will tag and geolocate everything as Photos has a
|
||||
quite good keyword management system.
|
||||
|
||||
After a while, I want to take most of the videos out of the library and move them
|
||||
to a separate "videos" folder on a different folder / volume. As I might want to
|
||||
use them in Final Cut Pro, and since Final Cut is able to import Finder tags into
|
||||
its internal library tagging system, I will use osxphotos to do just this.
|
||||
|
||||
Picking the videos can be left to Photos, using a smart folder for instance. Then
|
||||
just add a keyword to all videos to be processed. Here I chose "Quik" as I wanted
|
||||
to spot all videos created on my iPhone using the Quik application (now part of
|
||||
GoPro).
|
||||
|
||||
I want to retrieve my keywords only and make sure they populate the Finder tags, as
|
||||
well as export all the persons identified in the videos by Photos. I also want to
|
||||
merge any keywords or persons already in the video metadata with the exported
|
||||
metadata.
|
||||
|
||||
Keeping Photo’s edited titles and descriptions and putting both in the Finder
|
||||
comments field in a readable manner is also enabled.
|
||||
|
||||
And I want to keep the file’s creation date (using `--touch-file`).
|
||||
|
||||
Finally, use `--strip` to remove any leading or trailing whitespace from processed
|
||||
template fields.
|
||||
|
||||
|
||||
``osxphotos export ~/Desktop/folder for exported videos/ --keyword Quik --only-movies --db /path to my.photoslibrary --touch-file --finder-tag-keywords --person-keyword --xattr-template findercomment "{title}{title?{descr?{newline},},}{descr}" --exiftool-merge-keywords --exiftool-merge-persons --exiftool --strip``
|
||||
|
||||
Color Themes
|
||||
------------
|
||||
|
||||
Some osxphotos commands such as export use color themes to colorize the output to make it more legible. The theme may be specified with the ``--theme`` option. For example: ``osxphotos export /path/to/export --verbose --theme dark`` uses a theme suited for dark terminals. If you don't specify the color theme, osxphotos will select a default theme based on the current terminal settings. You can also specify your own default theme. See ``osxphotos help theme`` for more information on themes and for commands to help manage themes. Themes are defined in ``.theme`` files in the ``~/.osxphotos/themes`` directory and use style specifications compatible with the `rich <https://rich.readthedocs.io/en/stable/style.html>`_ library.
|
||||
|
||||
Conclusion
|
||||
----------
|
||||
|
||||
osxphotos is very flexible. If you merely want to backup your Photos library, then spending a few minutes to understand the ``--directory`` option is likely all you need and you can be up and running in minutes. However, if you have a more complex workflow, osxphotos likely provides options to implement your workflow. This tutorial does not attempt to cover every option offered by osxphotos but hopefully it provides a good understanding of what kinds of things are possible and where to explore if you want to learn more.
|
||||
701
osxphotos/docs/_static/alabaster.css
vendored
701
osxphotos/docs/_static/alabaster.css
vendored
@@ -1,701 +0,0 @@
|
||||
@import url("basic.css");
|
||||
|
||||
/* -- page layout ----------------------------------------------------------- */
|
||||
|
||||
body {
|
||||
font-family: Georgia, serif;
|
||||
font-size: 17px;
|
||||
background-color: #fff;
|
||||
color: #000;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
|
||||
div.document {
|
||||
width: 940px;
|
||||
margin: 30px auto 0 auto;
|
||||
}
|
||||
|
||||
div.documentwrapper {
|
||||
float: left;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
div.bodywrapper {
|
||||
margin: 0 0 0 220px;
|
||||
}
|
||||
|
||||
div.sphinxsidebar {
|
||||
width: 220px;
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
hr {
|
||||
border: 1px solid #B1B4B6;
|
||||
}
|
||||
|
||||
div.body {
|
||||
background-color: #fff;
|
||||
color: #3E4349;
|
||||
padding: 0 30px 0 30px;
|
||||
}
|
||||
|
||||
div.body > .section {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
div.footer {
|
||||
width: 940px;
|
||||
margin: 20px auto 30px auto;
|
||||
font-size: 14px;
|
||||
color: #888;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
div.footer a {
|
||||
color: #888;
|
||||
}
|
||||
|
||||
p.caption {
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
|
||||
div.relations {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
div.sphinxsidebar a {
|
||||
color: #444;
|
||||
text-decoration: none;
|
||||
border-bottom: 1px dotted #999;
|
||||
}
|
||||
|
||||
div.sphinxsidebar a:hover {
|
||||
border-bottom: 1px solid #999;
|
||||
}
|
||||
|
||||
div.sphinxsidebarwrapper {
|
||||
padding: 18px 10px;
|
||||
}
|
||||
|
||||
div.sphinxsidebarwrapper p.logo {
|
||||
padding: 0;
|
||||
margin: -10px 0 0 0px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
div.sphinxsidebarwrapper h1.logo {
|
||||
margin-top: -10px;
|
||||
text-align: center;
|
||||
margin-bottom: 5px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
div.sphinxsidebarwrapper h1.logo-name {
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
div.sphinxsidebarwrapper p.blurb {
|
||||
margin-top: 0;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
div.sphinxsidebar h3,
|
||||
div.sphinxsidebar h4 {
|
||||
font-family: Georgia, serif;
|
||||
color: #444;
|
||||
font-size: 24px;
|
||||
font-weight: normal;
|
||||
margin: 0 0 5px 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
div.sphinxsidebar h4 {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
div.sphinxsidebar h3 a {
|
||||
color: #444;
|
||||
}
|
||||
|
||||
div.sphinxsidebar p.logo a,
|
||||
div.sphinxsidebar h3 a,
|
||||
div.sphinxsidebar p.logo a:hover,
|
||||
div.sphinxsidebar h3 a:hover {
|
||||
border: none;
|
||||
}
|
||||
|
||||
div.sphinxsidebar p {
|
||||
color: #555;
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
div.sphinxsidebar ul {
|
||||
margin: 10px 0;
|
||||
padding: 0;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
div.sphinxsidebar ul li.toctree-l1 > a {
|
||||
font-size: 120%;
|
||||
}
|
||||
|
||||
div.sphinxsidebar ul li.toctree-l2 > a {
|
||||
font-size: 110%;
|
||||
}
|
||||
|
||||
div.sphinxsidebar input {
|
||||
border: 1px solid #CCC;
|
||||
font-family: Georgia, serif;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
div.sphinxsidebar hr {
|
||||
border: none;
|
||||
height: 1px;
|
||||
color: #AAA;
|
||||
background: #AAA;
|
||||
|
||||
text-align: left;
|
||||
margin-left: 0;
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
div.sphinxsidebar .badge {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
div.sphinxsidebar .badge:hover {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
/* To address an issue with donation coming after search */
|
||||
div.sphinxsidebar h3.donation {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
/* -- body styles ----------------------------------------------------------- */
|
||||
|
||||
a {
|
||||
color: #004B6B;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #6D4100;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
div.body h1,
|
||||
div.body h2,
|
||||
div.body h3,
|
||||
div.body h4,
|
||||
div.body h5,
|
||||
div.body h6 {
|
||||
font-family: Georgia, serif;
|
||||
font-weight: normal;
|
||||
margin: 30px 0px 10px 0px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
div.body h1 { margin-top: 0; padding-top: 0; font-size: 240%; }
|
||||
div.body h2 { font-size: 180%; }
|
||||
div.body h3 { font-size: 150%; }
|
||||
div.body h4 { font-size: 130%; }
|
||||
div.body h5 { font-size: 100%; }
|
||||
div.body h6 { font-size: 100%; }
|
||||
|
||||
a.headerlink {
|
||||
color: #DDD;
|
||||
padding: 0 4px;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a.headerlink:hover {
|
||||
color: #444;
|
||||
background: #EAEAEA;
|
||||
}
|
||||
|
||||
div.body p, div.body dd, div.body li {
|
||||
line-height: 1.4em;
|
||||
}
|
||||
|
||||
div.admonition {
|
||||
margin: 20px 0px;
|
||||
padding: 10px 30px;
|
||||
background-color: #EEE;
|
||||
border: 1px solid #CCC;
|
||||
}
|
||||
|
||||
div.admonition tt.xref, div.admonition code.xref, div.admonition a tt {
|
||||
background-color: #FBFBFB;
|
||||
border-bottom: 1px solid #fafafa;
|
||||
}
|
||||
|
||||
div.admonition p.admonition-title {
|
||||
font-family: Georgia, serif;
|
||||
font-weight: normal;
|
||||
font-size: 24px;
|
||||
margin: 0 0 10px 0;
|
||||
padding: 0;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
div.admonition p.last {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
div.highlight {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
dt:target, .highlight {
|
||||
background: #FAF3E8;
|
||||
}
|
||||
|
||||
div.warning {
|
||||
background-color: #FCC;
|
||||
border: 1px solid #FAA;
|
||||
}
|
||||
|
||||
div.danger {
|
||||
background-color: #FCC;
|
||||
border: 1px solid #FAA;
|
||||
-moz-box-shadow: 2px 2px 4px #D52C2C;
|
||||
-webkit-box-shadow: 2px 2px 4px #D52C2C;
|
||||
box-shadow: 2px 2px 4px #D52C2C;
|
||||
}
|
||||
|
||||
div.error {
|
||||
background-color: #FCC;
|
||||
border: 1px solid #FAA;
|
||||
-moz-box-shadow: 2px 2px 4px #D52C2C;
|
||||
-webkit-box-shadow: 2px 2px 4px #D52C2C;
|
||||
box-shadow: 2px 2px 4px #D52C2C;
|
||||
}
|
||||
|
||||
div.caution {
|
||||
background-color: #FCC;
|
||||
border: 1px solid #FAA;
|
||||
}
|
||||
|
||||
div.attention {
|
||||
background-color: #FCC;
|
||||
border: 1px solid #FAA;
|
||||
}
|
||||
|
||||
div.important {
|
||||
background-color: #EEE;
|
||||
border: 1px solid #CCC;
|
||||
}
|
||||
|
||||
div.note {
|
||||
background-color: #EEE;
|
||||
border: 1px solid #CCC;
|
||||
}
|
||||
|
||||
div.tip {
|
||||
background-color: #EEE;
|
||||
border: 1px solid #CCC;
|
||||
}
|
||||
|
||||
div.hint {
|
||||
background-color: #EEE;
|
||||
border: 1px solid #CCC;
|
||||
}
|
||||
|
||||
div.seealso {
|
||||
background-color: #EEE;
|
||||
border: 1px solid #CCC;
|
||||
}
|
||||
|
||||
div.topic {
|
||||
background-color: #EEE;
|
||||
}
|
||||
|
||||
p.admonition-title {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
p.admonition-title:after {
|
||||
content: ":";
|
||||
}
|
||||
|
||||
pre, tt, code {
|
||||
font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
.hll {
|
||||
background-color: #FFC;
|
||||
margin: 0 -12px;
|
||||
padding: 0 12px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
img.screenshot {
|
||||
}
|
||||
|
||||
tt.descname, tt.descclassname, code.descname, code.descclassname {
|
||||
font-size: 0.95em;
|
||||
}
|
||||
|
||||
tt.descname, code.descname {
|
||||
padding-right: 0.08em;
|
||||
}
|
||||
|
||||
img.screenshot {
|
||||
-moz-box-shadow: 2px 2px 4px #EEE;
|
||||
-webkit-box-shadow: 2px 2px 4px #EEE;
|
||||
box-shadow: 2px 2px 4px #EEE;
|
||||
}
|
||||
|
||||
table.docutils {
|
||||
border: 1px solid #888;
|
||||
-moz-box-shadow: 2px 2px 4px #EEE;
|
||||
-webkit-box-shadow: 2px 2px 4px #EEE;
|
||||
box-shadow: 2px 2px 4px #EEE;
|
||||
}
|
||||
|
||||
table.docutils td, table.docutils th {
|
||||
border: 1px solid #888;
|
||||
padding: 0.25em 0.7em;
|
||||
}
|
||||
|
||||
table.field-list, table.footnote {
|
||||
border: none;
|
||||
-moz-box-shadow: none;
|
||||
-webkit-box-shadow: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
table.footnote {
|
||||
margin: 15px 0;
|
||||
width: 100%;
|
||||
border: 1px solid #EEE;
|
||||
background: #FDFDFD;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
table.footnote + table.footnote {
|
||||
margin-top: -15px;
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
table.field-list th {
|
||||
padding: 0 0.8em 0 0;
|
||||
}
|
||||
|
||||
table.field-list td {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
table.field-list p {
|
||||
margin-bottom: 0.8em;
|
||||
}
|
||||
|
||||
/* Cloned from
|
||||
* https://github.com/sphinx-doc/sphinx/commit/ef60dbfce09286b20b7385333d63a60321784e68
|
||||
*/
|
||||
.field-name {
|
||||
-moz-hyphens: manual;
|
||||
-ms-hyphens: manual;
|
||||
-webkit-hyphens: manual;
|
||||
hyphens: manual;
|
||||
}
|
||||
|
||||
table.footnote td.label {
|
||||
width: .1px;
|
||||
padding: 0.3em 0 0.3em 0.5em;
|
||||
}
|
||||
|
||||
table.footnote td {
|
||||
padding: 0.3em 0.5em;
|
||||
}
|
||||
|
||||
dl {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
dl dd {
|
||||
margin-left: 30px;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
margin: 0 0 0 30px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
ul, ol {
|
||||
/* Matches the 30px from the narrow-screen "li > ul" selector below */
|
||||
margin: 10px 0 10px 30px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
pre {
|
||||
background: #EEE;
|
||||
padding: 7px 30px;
|
||||
margin: 15px 0px;
|
||||
line-height: 1.3em;
|
||||
}
|
||||
|
||||
div.viewcode-block:target {
|
||||
background: #ffd;
|
||||
}
|
||||
|
||||
dl pre, blockquote pre, li pre {
|
||||
margin-left: 0;
|
||||
padding-left: 30px;
|
||||
}
|
||||
|
||||
tt, code {
|
||||
background-color: #ecf0f3;
|
||||
color: #222;
|
||||
/* padding: 1px 2px; */
|
||||
}
|
||||
|
||||
tt.xref, code.xref, a tt {
|
||||
background-color: #FBFBFB;
|
||||
border-bottom: 1px solid #fff;
|
||||
}
|
||||
|
||||
a.reference {
|
||||
text-decoration: none;
|
||||
border-bottom: 1px dotted #004B6B;
|
||||
}
|
||||
|
||||
/* Don't put an underline on images */
|
||||
a.image-reference, a.image-reference:hover {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
a.reference:hover {
|
||||
border-bottom: 1px solid #6D4100;
|
||||
}
|
||||
|
||||
a.footnote-reference {
|
||||
text-decoration: none;
|
||||
font-size: 0.7em;
|
||||
vertical-align: top;
|
||||
border-bottom: 1px dotted #004B6B;
|
||||
}
|
||||
|
||||
a.footnote-reference:hover {
|
||||
border-bottom: 1px solid #6D4100;
|
||||
}
|
||||
|
||||
a:hover tt, a:hover code {
|
||||
background: #EEE;
|
||||
}
|
||||
|
||||
|
||||
@media screen and (max-width: 870px) {
|
||||
|
||||
div.sphinxsidebar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
div.document {
|
||||
width: 100%;
|
||||
|
||||
}
|
||||
|
||||
div.documentwrapper {
|
||||
margin-left: 0;
|
||||
margin-top: 0;
|
||||
margin-right: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
div.bodywrapper {
|
||||
margin-top: 0;
|
||||
margin-right: 0;
|
||||
margin-bottom: 0;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
li > ul {
|
||||
/* Matches the 30px from the "ul, ol" selector above */
|
||||
margin-left: 30px;
|
||||
}
|
||||
|
||||
.document {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.footer {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.bodywrapper {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.footer {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.github {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@media screen and (max-width: 875px) {
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 20px 30px;
|
||||
}
|
||||
|
||||
div.documentwrapper {
|
||||
float: none;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
div.sphinxsidebar {
|
||||
display: block;
|
||||
float: none;
|
||||
width: 102.5%;
|
||||
margin: 50px -30px -20px -30px;
|
||||
padding: 10px 20px;
|
||||
background: #333;
|
||||
color: #FFF;
|
||||
}
|
||||
|
||||
div.sphinxsidebar h3, div.sphinxsidebar h4, div.sphinxsidebar p,
|
||||
div.sphinxsidebar h3 a {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
div.sphinxsidebar a {
|
||||
color: #AAA;
|
||||
}
|
||||
|
||||
div.sphinxsidebar p.logo {
|
||||
display: none;
|
||||
}
|
||||
|
||||
div.document {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
div.footer {
|
||||
display: none;
|
||||
}
|
||||
|
||||
div.bodywrapper {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
div.body {
|
||||
min-height: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.rtd_doc_footer {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.document {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.footer {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.footer {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.github {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* misc. */
|
||||
|
||||
.revsys-inline {
|
||||
display: none!important;
|
||||
}
|
||||
|
||||
/* Make nested-list/multi-paragraph items look better in Releases changelog
|
||||
* pages. Without this, docutils' magical list fuckery causes inconsistent
|
||||
* formatting between different release sub-lists.
|
||||
*/
|
||||
div#changelog > div.section > ul > li > p:only-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* Hide fugly table cell borders in ..bibliography:: directive output */
|
||||
table.docutils.citation, table.docutils.citation td, table.docutils.citation th {
|
||||
border: none;
|
||||
/* Below needed in some edge cases; if not applied, bottom shadows appear */
|
||||
-moz-box-shadow: none;
|
||||
-webkit-box-shadow: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
|
||||
/* relbar */
|
||||
|
||||
.related {
|
||||
line-height: 30px;
|
||||
width: 100%;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.related.top {
|
||||
border-bottom: 1px solid #EEE;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.related.bottom {
|
||||
border-top: 1px solid #EEE;
|
||||
}
|
||||
|
||||
.related ul {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.related li {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
nav#rellinks {
|
||||
float: right;
|
||||
}
|
||||
|
||||
nav#rellinks li+li:before {
|
||||
content: "|";
|
||||
}
|
||||
|
||||
nav#breadcrumbs li+li:before {
|
||||
content: "\00BB";
|
||||
}
|
||||
|
||||
/* Hide certain items when printing */
|
||||
@media print {
|
||||
div.related {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
906
osxphotos/docs/_static/basic.css
vendored
906
osxphotos/docs/_static/basic.css
vendored
@@ -1,906 +0,0 @@
|
||||
/*
|
||||
* basic.css
|
||||
* ~~~~~~~~~
|
||||
*
|
||||
* Sphinx stylesheet -- basic theme.
|
||||
*
|
||||
* :copyright: Copyright 2007-2022 by the Sphinx team, see AUTHORS.
|
||||
* :license: BSD, see LICENSE for details.
|
||||
*
|
||||
*/
|
||||
|
||||
/* -- main layout ----------------------------------------------------------- */
|
||||
|
||||
div.clearer {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
div.section::after {
|
||||
display: block;
|
||||
content: '';
|
||||
clear: left;
|
||||
}
|
||||
|
||||
/* -- relbar ---------------------------------------------------------------- */
|
||||
|
||||
div.related {
|
||||
width: 100%;
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
div.related h3 {
|
||||
display: none;
|
||||
}
|
||||
|
||||
div.related ul {
|
||||
margin: 0;
|
||||
padding: 0 0 0 10px;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
div.related li {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
div.related li.right {
|
||||
float: right;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
/* -- sidebar --------------------------------------------------------------- */
|
||||
|
||||
div.sphinxsidebarwrapper {
|
||||
padding: 10px 5px 0 10px;
|
||||
}
|
||||
|
||||
div.sphinxsidebar {
|
||||
float: left;
|
||||
width: 230px;
|
||||
margin-left: -100%;
|
||||
font-size: 90%;
|
||||
word-wrap: break-word;
|
||||
overflow-wrap : break-word;
|
||||
}
|
||||
|
||||
div.sphinxsidebar ul {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
div.sphinxsidebar ul ul,
|
||||
div.sphinxsidebar ul.want-points {
|
||||
margin-left: 20px;
|
||||
list-style: square;
|
||||
}
|
||||
|
||||
div.sphinxsidebar ul ul {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
div.sphinxsidebar form {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
div.sphinxsidebar input {
|
||||
border: 1px solid #98dbcc;
|
||||
font-family: sans-serif;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
div.sphinxsidebar #searchbox form.search {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
div.sphinxsidebar #searchbox input[type="text"] {
|
||||
float: left;
|
||||
width: 80%;
|
||||
padding: 0.25em;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
div.sphinxsidebar #searchbox input[type="submit"] {
|
||||
float: left;
|
||||
width: 20%;
|
||||
border-left: none;
|
||||
padding: 0.25em;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
|
||||
img {
|
||||
border: 0;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
/* -- search page ----------------------------------------------------------- */
|
||||
|
||||
ul.search {
|
||||
margin: 10px 0 0 20px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
ul.search li {
|
||||
padding: 5px 0 5px 20px;
|
||||
background-image: url(file.png);
|
||||
background-repeat: no-repeat;
|
||||
background-position: 0 7px;
|
||||
}
|
||||
|
||||
ul.search li a {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
ul.search li p.context {
|
||||
color: #888;
|
||||
margin: 2px 0 0 30px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
ul.keywordmatches li.goodmatch a {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* -- index page ------------------------------------------------------------ */
|
||||
|
||||
table.contentstable {
|
||||
width: 90%;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
table.contentstable p.biglink {
|
||||
line-height: 150%;
|
||||
}
|
||||
|
||||
a.biglink {
|
||||
font-size: 1.3em;
|
||||
}
|
||||
|
||||
span.linkdescr {
|
||||
font-style: italic;
|
||||
padding-top: 5px;
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
/* -- general index --------------------------------------------------------- */
|
||||
|
||||
table.indextable {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
table.indextable td {
|
||||
text-align: left;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
table.indextable ul {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
table.indextable > tbody > tr > td > ul {
|
||||
padding-left: 0em;
|
||||
}
|
||||
|
||||
table.indextable tr.pcap {
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
table.indextable tr.cap {
|
||||
margin-top: 10px;
|
||||
background-color: #f2f2f2;
|
||||
}
|
||||
|
||||
img.toggler {
|
||||
margin-right: 3px;
|
||||
margin-top: 3px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
div.modindex-jumpbox {
|
||||
border-top: 1px solid #ddd;
|
||||
border-bottom: 1px solid #ddd;
|
||||
margin: 1em 0 1em 0;
|
||||
padding: 0.4em;
|
||||
}
|
||||
|
||||
div.genindex-jumpbox {
|
||||
border-top: 1px solid #ddd;
|
||||
border-bottom: 1px solid #ddd;
|
||||
margin: 1em 0 1em 0;
|
||||
padding: 0.4em;
|
||||
}
|
||||
|
||||
/* -- domain module index --------------------------------------------------- */
|
||||
|
||||
table.modindextable td {
|
||||
padding: 2px;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
/* -- general body styles --------------------------------------------------- */
|
||||
|
||||
div.body {
|
||||
min-width: 450px;
|
||||
max-width: 800px;
|
||||
}
|
||||
|
||||
div.body p, div.body dd, div.body li, div.body blockquote {
|
||||
-moz-hyphens: auto;
|
||||
-ms-hyphens: auto;
|
||||
-webkit-hyphens: auto;
|
||||
hyphens: auto;
|
||||
}
|
||||
|
||||
a.headerlink {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
a.brackets:before,
|
||||
span.brackets > a:before{
|
||||
content: "[";
|
||||
}
|
||||
|
||||
a.brackets:after,
|
||||
span.brackets > a:after {
|
||||
content: "]";
|
||||
}
|
||||
|
||||
h1:hover > a.headerlink,
|
||||
h2:hover > a.headerlink,
|
||||
h3:hover > a.headerlink,
|
||||
h4:hover > a.headerlink,
|
||||
h5:hover > a.headerlink,
|
||||
h6:hover > a.headerlink,
|
||||
dt:hover > a.headerlink,
|
||||
caption:hover > a.headerlink,
|
||||
p.caption:hover > a.headerlink,
|
||||
div.code-block-caption:hover > a.headerlink {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
div.body p.caption {
|
||||
text-align: inherit;
|
||||
}
|
||||
|
||||
div.body td {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.first {
|
||||
margin-top: 0 !important;
|
||||
}
|
||||
|
||||
p.rubric {
|
||||
margin-top: 30px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
img.align-left, figure.align-left, .figure.align-left, object.align-left {
|
||||
clear: left;
|
||||
float: left;
|
||||
margin-right: 1em;
|
||||
}
|
||||
|
||||
img.align-right, figure.align-right, .figure.align-right, object.align-right {
|
||||
clear: right;
|
||||
float: right;
|
||||
margin-left: 1em;
|
||||
}
|
||||
|
||||
img.align-center, figure.align-center, .figure.align-center, object.align-center {
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
img.align-default, figure.align-default, .figure.align-default {
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.align-left {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.align-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.align-default {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.align-right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
/* -- sidebars -------------------------------------------------------------- */
|
||||
|
||||
div.sidebar,
|
||||
aside.sidebar {
|
||||
margin: 0 0 0.5em 1em;
|
||||
border: 1px solid #ddb;
|
||||
padding: 7px;
|
||||
background-color: #ffe;
|
||||
width: 40%;
|
||||
float: right;
|
||||
clear: right;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
p.sidebar-title {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
div.admonition, div.topic, blockquote {
|
||||
clear: left;
|
||||
}
|
||||
|
||||
/* -- topics ---------------------------------------------------------------- */
|
||||
|
||||
div.topic {
|
||||
border: 1px solid #ccc;
|
||||
padding: 7px;
|
||||
margin: 10px 0 10px 0;
|
||||
}
|
||||
|
||||
p.topic-title {
|
||||
font-size: 1.1em;
|
||||
font-weight: bold;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
/* -- admonitions ----------------------------------------------------------- */
|
||||
|
||||
div.admonition {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
padding: 7px;
|
||||
}
|
||||
|
||||
div.admonition dt {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
p.admonition-title {
|
||||
margin: 0px 10px 5px 0px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
div.body p.centered {
|
||||
text-align: center;
|
||||
margin-top: 25px;
|
||||
}
|
||||
|
||||
/* -- content of sidebars/topics/admonitions -------------------------------- */
|
||||
|
||||
div.sidebar > :last-child,
|
||||
aside.sidebar > :last-child,
|
||||
div.topic > :last-child,
|
||||
div.admonition > :last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
div.sidebar::after,
|
||||
aside.sidebar::after,
|
||||
div.topic::after,
|
||||
div.admonition::after,
|
||||
blockquote::after {
|
||||
display: block;
|
||||
content: '';
|
||||
clear: both;
|
||||
}
|
||||
|
||||
/* -- tables ---------------------------------------------------------------- */
|
||||
|
||||
table.docutils {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
border: 0;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
table.align-center {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
table.align-default {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
table caption span.caption-number {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
table caption span.caption-text {
|
||||
}
|
||||
|
||||
table.docutils td, table.docutils th {
|
||||
padding: 1px 8px 1px 5px;
|
||||
border-top: 0;
|
||||
border-left: 0;
|
||||
border-right: 0;
|
||||
border-bottom: 1px solid #aaa;
|
||||
}
|
||||
|
||||
table.footnote td, table.footnote th {
|
||||
border: 0 !important;
|
||||
}
|
||||
|
||||
th {
|
||||
text-align: left;
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
table.citation {
|
||||
border-left: solid 1px gray;
|
||||
margin-left: 1px;
|
||||
}
|
||||
|
||||
table.citation td {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
th > :first-child,
|
||||
td > :first-child {
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
th > :last-child,
|
||||
td > :last-child {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
/* -- figures --------------------------------------------------------------- */
|
||||
|
||||
div.figure, figure {
|
||||
margin: 0.5em;
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
div.figure p.caption, figcaption {
|
||||
padding: 0.3em;
|
||||
}
|
||||
|
||||
div.figure p.caption span.caption-number,
|
||||
figcaption span.caption-number {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
div.figure p.caption span.caption-text,
|
||||
figcaption span.caption-text {
|
||||
}
|
||||
|
||||
/* -- field list styles ----------------------------------------------------- */
|
||||
|
||||
table.field-list td, table.field-list th {
|
||||
border: 0 !important;
|
||||
}
|
||||
|
||||
.field-list ul {
|
||||
margin: 0;
|
||||
padding-left: 1em;
|
||||
}
|
||||
|
||||
.field-list p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.field-name {
|
||||
-moz-hyphens: manual;
|
||||
-ms-hyphens: manual;
|
||||
-webkit-hyphens: manual;
|
||||
hyphens: manual;
|
||||
}
|
||||
|
||||
/* -- hlist styles ---------------------------------------------------------- */
|
||||
|
||||
table.hlist {
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
table.hlist td {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
/* -- object description styles --------------------------------------------- */
|
||||
|
||||
.sig {
|
||||
font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
|
||||
}
|
||||
|
||||
.sig-name, code.descname {
|
||||
background-color: transparent;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.sig-name {
|
||||
font-size: 1.1em;
|
||||
}
|
||||
|
||||
code.descname {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
.sig-prename, code.descclassname {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.optional {
|
||||
font-size: 1.3em;
|
||||
}
|
||||
|
||||
.sig-paren {
|
||||
font-size: larger;
|
||||
}
|
||||
|
||||
.sig-param.n {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/* C++ specific styling */
|
||||
|
||||
.sig-inline.c-texpr,
|
||||
.sig-inline.cpp-texpr {
|
||||
font-family: unset;
|
||||
}
|
||||
|
||||
.sig.c .k, .sig.c .kt,
|
||||
.sig.cpp .k, .sig.cpp .kt {
|
||||
color: #0033B3;
|
||||
}
|
||||
|
||||
.sig.c .m,
|
||||
.sig.cpp .m {
|
||||
color: #1750EB;
|
||||
}
|
||||
|
||||
.sig.c .s, .sig.c .sc,
|
||||
.sig.cpp .s, .sig.cpp .sc {
|
||||
color: #067D17;
|
||||
}
|
||||
|
||||
|
||||
/* -- other body styles ----------------------------------------------------- */
|
||||
|
||||
ol.arabic {
|
||||
list-style: decimal;
|
||||
}
|
||||
|
||||
ol.loweralpha {
|
||||
list-style: lower-alpha;
|
||||
}
|
||||
|
||||
ol.upperalpha {
|
||||
list-style: upper-alpha;
|
||||
}
|
||||
|
||||
ol.lowerroman {
|
||||
list-style: lower-roman;
|
||||
}
|
||||
|
||||
ol.upperroman {
|
||||
list-style: upper-roman;
|
||||
}
|
||||
|
||||
:not(li) > ol > li:first-child > :first-child,
|
||||
:not(li) > ul > li:first-child > :first-child {
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
:not(li) > ol > li:last-child > :last-child,
|
||||
:not(li) > ul > li:last-child > :last-child {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
ol.simple ol p,
|
||||
ol.simple ul p,
|
||||
ul.simple ol p,
|
||||
ul.simple ul p {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
ol.simple > li:not(:first-child) > p,
|
||||
ul.simple > li:not(:first-child) > p {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
ol.simple p,
|
||||
ul.simple p {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
dl.footnote > dt,
|
||||
dl.citation > dt {
|
||||
float: left;
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
|
||||
dl.footnote > dd,
|
||||
dl.citation > dd {
|
||||
margin-bottom: 0em;
|
||||
}
|
||||
|
||||
dl.footnote > dd:after,
|
||||
dl.citation > dd:after {
|
||||
content: "";
|
||||
clear: both;
|
||||
}
|
||||
|
||||
dl.field-list {
|
||||
display: grid;
|
||||
grid-template-columns: fit-content(30%) auto;
|
||||
}
|
||||
|
||||
dl.field-list > dt {
|
||||
font-weight: bold;
|
||||
word-break: break-word;
|
||||
padding-left: 0.5em;
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
dl.field-list > dt:after {
|
||||
content: ":";
|
||||
}
|
||||
|
||||
dl.field-list > dd {
|
||||
padding-left: 0.5em;
|
||||
margin-top: 0em;
|
||||
margin-left: 0em;
|
||||
margin-bottom: 0em;
|
||||
}
|
||||
|
||||
dl {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
dd > :first-child {
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
dd ul, dd table {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
dd {
|
||||
margin-top: 3px;
|
||||
margin-bottom: 10px;
|
||||
margin-left: 30px;
|
||||
}
|
||||
|
||||
dl > dd:last-child,
|
||||
dl > dd:last-child > :last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
dt:target, span.highlighted {
|
||||
background-color: #fbe54e;
|
||||
}
|
||||
|
||||
rect.highlighted {
|
||||
fill: #fbe54e;
|
||||
}
|
||||
|
||||
dl.glossary dt {
|
||||
font-weight: bold;
|
||||
font-size: 1.1em;
|
||||
}
|
||||
|
||||
.versionmodified {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.system-message {
|
||||
background-color: #fda;
|
||||
padding: 5px;
|
||||
border: 3px solid red;
|
||||
}
|
||||
|
||||
.footnote:target {
|
||||
background-color: #ffa;
|
||||
}
|
||||
|
||||
.line-block {
|
||||
display: block;
|
||||
margin-top: 1em;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.line-block .line-block {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
margin-left: 1.5em;
|
||||
}
|
||||
|
||||
.guilabel, .menuselection {
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
.accelerator {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.classifier {
|
||||
font-style: oblique;
|
||||
}
|
||||
|
||||
.classifier:before {
|
||||
font-style: normal;
|
||||
margin: 0 0.5em;
|
||||
content: ":";
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
abbr, acronym {
|
||||
border-bottom: dotted 1px;
|
||||
cursor: help;
|
||||
}
|
||||
|
||||
/* -- code displays --------------------------------------------------------- */
|
||||
|
||||
pre {
|
||||
overflow: auto;
|
||||
overflow-y: hidden; /* fixes display issues on Chrome browsers */
|
||||
}
|
||||
|
||||
pre, div[class*="highlight-"] {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
span.pre {
|
||||
-moz-hyphens: none;
|
||||
-ms-hyphens: none;
|
||||
-webkit-hyphens: none;
|
||||
hyphens: none;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
div[class*="highlight-"] {
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
td.linenos pre {
|
||||
border: 0;
|
||||
background-color: transparent;
|
||||
color: #aaa;
|
||||
}
|
||||
|
||||
table.highlighttable {
|
||||
display: block;
|
||||
}
|
||||
|
||||
table.highlighttable tbody {
|
||||
display: block;
|
||||
}
|
||||
|
||||
table.highlighttable tr {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
table.highlighttable td {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
table.highlighttable td.linenos {
|
||||
padding-right: 0.5em;
|
||||
}
|
||||
|
||||
table.highlighttable td.code {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.highlight .hll {
|
||||
display: block;
|
||||
}
|
||||
|
||||
div.highlight pre,
|
||||
table.highlighttable pre {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
div.code-block-caption + div {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
div.code-block-caption {
|
||||
margin-top: 1em;
|
||||
padding: 2px 5px;
|
||||
font-size: small;
|
||||
}
|
||||
|
||||
div.code-block-caption code {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
table.highlighttable td.linenos,
|
||||
span.linenos,
|
||||
div.highlight span.gp { /* gp: Generic.Prompt */
|
||||
user-select: none;
|
||||
-webkit-user-select: text; /* Safari fallback only */
|
||||
-webkit-user-select: none; /* Chrome/Safari */
|
||||
-moz-user-select: none; /* Firefox */
|
||||
-ms-user-select: none; /* IE10+ */
|
||||
}
|
||||
|
||||
div.code-block-caption span.caption-number {
|
||||
padding: 0.1em 0.3em;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
div.code-block-caption span.caption-text {
|
||||
}
|
||||
|
||||
div.literal-block-wrapper {
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
code.xref, a code {
|
||||
background-color: transparent;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h1 code, h2 code, h3 code, h4 code, h5 code, h6 code {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.viewcode-link {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.viewcode-back {
|
||||
float: right;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
div.viewcode-block:target {
|
||||
margin: -1px -10px;
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
/* -- math display ---------------------------------------------------------- */
|
||||
|
||||
img.math {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
div.body div.math p {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
span.eqno {
|
||||
float: right;
|
||||
}
|
||||
|
||||
span.eqno a.headerlink {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
div.math:hover a.headerlink {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
/* -- printout stylesheet --------------------------------------------------- */
|
||||
|
||||
@media print {
|
||||
div.document,
|
||||
div.documentwrapper,
|
||||
div.bodywrapper {
|
||||
margin: 0 !important;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
div.sphinxsidebar,
|
||||
div.related,
|
||||
div.footer,
|
||||
#top-link {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
4
osxphotos/docs/_static/check-solid.svg
vendored
4
osxphotos/docs/_static/check-solid.svg
vendored
@@ -1,4 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-check" width="44" height="44" viewBox="0 0 24 24" stroke-width="2" stroke="#22863a" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"/>
|
||||
<path d="M5 12l5 5l10 -10" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 313 B |
7
osxphotos/docs/_static/clipboard.min.js
vendored
7
osxphotos/docs/_static/clipboard.min.js
vendored
File diff suppressed because one or more lines are too long
5
osxphotos/docs/_static/copy-button.svg
vendored
5
osxphotos/docs/_static/copy-button.svg
vendored
@@ -1,5 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-copy" width="44" height="44" viewBox="0 0 24 24" stroke-width="1.5" stroke="#000000" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"/>
|
||||
<rect x="8" y="8" width="12" height="12" rx="2" />
|
||||
<path d="M16 8v-2a2 2 0 0 0 -2 -2h-8a2 2 0 0 0 -2 2v8a2 2 0 0 0 2 2h2" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 411 B |
93
osxphotos/docs/_static/copybutton.css
vendored
93
osxphotos/docs/_static/copybutton.css
vendored
@@ -1,93 +0,0 @@
|
||||
/* Copy buttons */
|
||||
button.copybtn {
|
||||
position: absolute;
|
||||
display: flex;
|
||||
top: .3em;
|
||||
right: .3em;
|
||||
width: 1.7em;
|
||||
height: 1.7em;
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s, border .3s, background-color .3s;
|
||||
user-select: none;
|
||||
padding: 0;
|
||||
border: none;
|
||||
outline: none;
|
||||
border-radius: 0.4em;
|
||||
/* The colors that GitHub uses */
|
||||
border: #1b1f2426 1px solid;
|
||||
background-color: #f6f8fa;
|
||||
color: #57606a;
|
||||
}
|
||||
|
||||
button.copybtn.success {
|
||||
border-color: #22863a;
|
||||
color: #22863a;
|
||||
}
|
||||
|
||||
button.copybtn svg {
|
||||
stroke: currentColor;
|
||||
width: 1.5em;
|
||||
height: 1.5em;
|
||||
padding: 0.1em;
|
||||
}
|
||||
|
||||
div.highlight {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.highlight:hover button.copybtn {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.highlight button.copybtn:hover {
|
||||
background-color: rgb(235, 235, 235);
|
||||
}
|
||||
|
||||
.highlight button.copybtn:active {
|
||||
background-color: rgb(187, 187, 187);
|
||||
}
|
||||
|
||||
/**
|
||||
* A minimal CSS-only tooltip copied from:
|
||||
* https://codepen.io/mildrenben/pen/rVBrpK
|
||||
*
|
||||
* To use, write HTML like the following:
|
||||
*
|
||||
* <p class="o-tooltip--left" data-tooltip="Hey">Short</p>
|
||||
*/
|
||||
.o-tooltip--left {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.o-tooltip--left:after {
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
position: absolute;
|
||||
content: attr(data-tooltip);
|
||||
padding: .2em;
|
||||
font-size: .8em;
|
||||
left: -.2em;
|
||||
background: grey;
|
||||
color: white;
|
||||
white-space: nowrap;
|
||||
z-index: 2;
|
||||
border-radius: 2px;
|
||||
transform: translateX(-102%) translateY(0);
|
||||
transition: opacity 0.2s cubic-bezier(0.64, 0.09, 0.08, 1), transform 0.2s cubic-bezier(0.64, 0.09, 0.08, 1);
|
||||
}
|
||||
|
||||
.o-tooltip--left:hover:after {
|
||||
display: block;
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
transform: translateX(-100%) translateY(0);
|
||||
transition: opacity 0.2s cubic-bezier(0.64, 0.09, 0.08, 1), transform 0.2s cubic-bezier(0.64, 0.09, 0.08, 1);
|
||||
transition-delay: .5s;
|
||||
}
|
||||
|
||||
/* By default the copy button shouldn't show up when printing a page */
|
||||
@media print {
|
||||
button.copybtn {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
220
osxphotos/docs/_static/copybutton.js
vendored
220
osxphotos/docs/_static/copybutton.js
vendored
@@ -1,220 +0,0 @@
|
||||
// Localization support
|
||||
const messages = {
|
||||
'en': {
|
||||
'copy': 'Copy',
|
||||
'copy_to_clipboard': 'Copy to clipboard',
|
||||
'copy_success': 'Copied!',
|
||||
'copy_failure': 'Failed to copy',
|
||||
},
|
||||
'es' : {
|
||||
'copy': 'Copiar',
|
||||
'copy_to_clipboard': 'Copiar al portapapeles',
|
||||
'copy_success': '¡Copiado!',
|
||||
'copy_failure': 'Error al copiar',
|
||||
},
|
||||
'de' : {
|
||||
'copy': 'Kopieren',
|
||||
'copy_to_clipboard': 'In die Zwischenablage kopieren',
|
||||
'copy_success': 'Kopiert!',
|
||||
'copy_failure': 'Fehler beim Kopieren',
|
||||
},
|
||||
'fr' : {
|
||||
'copy': 'Copier',
|
||||
'copy_to_clipboard': 'Copié dans le presse-papier',
|
||||
'copy_success': 'Copié !',
|
||||
'copy_failure': 'Échec de la copie',
|
||||
},
|
||||
'ru': {
|
||||
'copy': 'Скопировать',
|
||||
'copy_to_clipboard': 'Скопировать в буфер',
|
||||
'copy_success': 'Скопировано!',
|
||||
'copy_failure': 'Не удалось скопировать',
|
||||
},
|
||||
'zh-CN': {
|
||||
'copy': '复制',
|
||||
'copy_to_clipboard': '复制到剪贴板',
|
||||
'copy_success': '复制成功!',
|
||||
'copy_failure': '复制失败',
|
||||
},
|
||||
'it' : {
|
||||
'copy': 'Copiare',
|
||||
'copy_to_clipboard': 'Copiato negli appunti',
|
||||
'copy_success': 'Copiato!',
|
||||
'copy_failure': 'Errore durante la copia',
|
||||
}
|
||||
}
|
||||
|
||||
let locale = 'en'
|
||||
if( document.documentElement.lang !== undefined
|
||||
&& messages[document.documentElement.lang] !== undefined ) {
|
||||
locale = document.documentElement.lang
|
||||
}
|
||||
|
||||
let doc_url_root = DOCUMENTATION_OPTIONS.URL_ROOT;
|
||||
if (doc_url_root == '#') {
|
||||
doc_url_root = '';
|
||||
}
|
||||
|
||||
/**
|
||||
* SVG files for our copy buttons
|
||||
*/
|
||||
let iconCheck = `<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-check" width="44" height="44" viewBox="0 0 24 24" stroke-width="2" stroke="#22863a" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||
<title>${messages[locale]['copy_success']}</title>
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"/>
|
||||
<path d="M5 12l5 5l10 -10" />
|
||||
</svg>`
|
||||
|
||||
// If the user specified their own SVG use that, otherwise use the default
|
||||
let iconCopy = ``;
|
||||
if (!iconCopy) {
|
||||
iconCopy = `<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-copy" width="44" height="44" viewBox="0 0 24 24" stroke-width="1.5" stroke="#000000" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||
<title>${messages[locale]['copy_to_clipboard']}</title>
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"/>
|
||||
<rect x="8" y="8" width="12" height="12" rx="2" />
|
||||
<path d="M16 8v-2a2 2 0 0 0 -2 -2h-8a2 2 0 0 0 -2 2v8a2 2 0 0 0 2 2h2" />
|
||||
</svg>`
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up copy/paste for code blocks
|
||||
*/
|
||||
|
||||
const runWhenDOMLoaded = cb => {
|
||||
if (document.readyState != 'loading') {
|
||||
cb()
|
||||
} else if (document.addEventListener) {
|
||||
document.addEventListener('DOMContentLoaded', cb)
|
||||
} else {
|
||||
document.attachEvent('onreadystatechange', function() {
|
||||
if (document.readyState == 'complete') cb()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const codeCellId = index => `codecell${index}`
|
||||
|
||||
// Clears selected text since ClipboardJS will select the text when copying
|
||||
const clearSelection = () => {
|
||||
if (window.getSelection) {
|
||||
window.getSelection().removeAllRanges()
|
||||
} else if (document.selection) {
|
||||
document.selection.empty()
|
||||
}
|
||||
}
|
||||
|
||||
// Changes tooltip text for two seconds, then changes it back
|
||||
const temporarilyChangeTooltip = (el, oldText, newText) => {
|
||||
el.setAttribute('data-tooltip', newText)
|
||||
el.classList.add('success')
|
||||
setTimeout(() => el.setAttribute('data-tooltip', oldText), 2000)
|
||||
setTimeout(() => el.classList.remove('success'), 2000)
|
||||
}
|
||||
|
||||
// Changes the copy button icon for two seconds, then changes it back
|
||||
const temporarilyChangeIcon = (el) => {
|
||||
el.innerHTML = iconCheck;
|
||||
setTimeout(() => {el.innerHTML = iconCopy}, 2000)
|
||||
}
|
||||
|
||||
const addCopyButtonToCodeCells = () => {
|
||||
// If ClipboardJS hasn't loaded, wait a bit and try again. This
|
||||
// happens because we load ClipboardJS asynchronously.
|
||||
if (window.ClipboardJS === undefined) {
|
||||
setTimeout(addCopyButtonToCodeCells, 250)
|
||||
return
|
||||
}
|
||||
|
||||
// Add copybuttons to all of our code cells
|
||||
const codeCells = document.querySelectorAll('div.highlight pre')
|
||||
codeCells.forEach((codeCell, index) => {
|
||||
const id = codeCellId(index)
|
||||
codeCell.setAttribute('id', id)
|
||||
|
||||
const clipboardButton = id =>
|
||||
`<button class="copybtn o-tooltip--left" data-tooltip="${messages[locale]['copy']}" data-clipboard-target="#${id}">
|
||||
${iconCopy}
|
||||
</button>`
|
||||
codeCell.insertAdjacentHTML('afterend', clipboardButton(id))
|
||||
})
|
||||
|
||||
function escapeRegExp(string) {
|
||||
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
|
||||
}
|
||||
|
||||
// Callback when a copy button is clicked. Will be passed the node that was clicked
|
||||
// should then grab the text and replace pieces of text that shouldn't be used in output
|
||||
function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true, copyEmptyLines = true, lineContinuationChar = "", hereDocDelim = "") {
|
||||
|
||||
var regexp;
|
||||
var match;
|
||||
|
||||
// Do we check for line continuation characters and "HERE-documents"?
|
||||
var useLineCont = !!lineContinuationChar
|
||||
var useHereDoc = !!hereDocDelim
|
||||
|
||||
// create regexp to capture prompt and remaining line
|
||||
if (isRegexp) {
|
||||
regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)')
|
||||
} else {
|
||||
regexp = new RegExp('^(' + escapeRegExp(copybuttonPromptText) + ')(.*)')
|
||||
}
|
||||
|
||||
const outputLines = [];
|
||||
var promptFound = false;
|
||||
var gotLineCont = false;
|
||||
var gotHereDoc = false;
|
||||
const lineGotPrompt = [];
|
||||
for (const line of textContent.split('\n')) {
|
||||
match = line.match(regexp)
|
||||
if (match || gotLineCont || gotHereDoc) {
|
||||
promptFound = regexp.test(line)
|
||||
lineGotPrompt.push(promptFound)
|
||||
if (removePrompts && promptFound) {
|
||||
outputLines.push(match[2])
|
||||
} else {
|
||||
outputLines.push(line)
|
||||
}
|
||||
gotLineCont = line.endsWith(lineContinuationChar) & useLineCont
|
||||
if (line.includes(hereDocDelim) & useHereDoc)
|
||||
gotHereDoc = !gotHereDoc
|
||||
} else if (!onlyCopyPromptLines) {
|
||||
outputLines.push(line)
|
||||
} else if (copyEmptyLines && line.trim() === '') {
|
||||
outputLines.push(line)
|
||||
}
|
||||
}
|
||||
|
||||
// If no lines with the prompt were found then just use original lines
|
||||
if (lineGotPrompt.some(v => v === true)) {
|
||||
textContent = outputLines.join('\n');
|
||||
}
|
||||
|
||||
// Remove a trailing newline to avoid auto-running when pasting
|
||||
if (textContent.endsWith("\n")) {
|
||||
textContent = textContent.slice(0, -1)
|
||||
}
|
||||
return textContent
|
||||
}
|
||||
|
||||
|
||||
var copyTargetText = (trigger) => {
|
||||
var target = document.querySelector(trigger.attributes['data-clipboard-target'].value);
|
||||
return formatCopyText(target.innerText, '', false, true, true, true, '', '')
|
||||
}
|
||||
|
||||
// Initialize with a callback so we can modify the text before copy
|
||||
const clipboard = new ClipboardJS('.copybtn', {text: copyTargetText})
|
||||
|
||||
// Update UI with error/success messages
|
||||
clipboard.on('success', event => {
|
||||
clearSelection()
|
||||
temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_success'])
|
||||
temporarilyChangeIcon(event.trigger)
|
||||
})
|
||||
|
||||
clipboard.on('error', event => {
|
||||
temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_failure'])
|
||||
})
|
||||
}
|
||||
|
||||
runWhenDOMLoaded(addCopyButtonToCodeCells)
|
||||
58
osxphotos/docs/_static/copybutton_funcs.js
vendored
58
osxphotos/docs/_static/copybutton_funcs.js
vendored
@@ -1,58 +0,0 @@
|
||||
function escapeRegExp(string) {
|
||||
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
|
||||
}
|
||||
|
||||
// Callback when a copy button is clicked. Will be passed the node that was clicked
|
||||
// should then grab the text and replace pieces of text that shouldn't be used in output
|
||||
export function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true, copyEmptyLines = true, lineContinuationChar = "", hereDocDelim = "") {
|
||||
|
||||
var regexp;
|
||||
var match;
|
||||
|
||||
// Do we check for line continuation characters and "HERE-documents"?
|
||||
var useLineCont = !!lineContinuationChar
|
||||
var useHereDoc = !!hereDocDelim
|
||||
|
||||
// create regexp to capture prompt and remaining line
|
||||
if (isRegexp) {
|
||||
regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)')
|
||||
} else {
|
||||
regexp = new RegExp('^(' + escapeRegExp(copybuttonPromptText) + ')(.*)')
|
||||
}
|
||||
|
||||
const outputLines = [];
|
||||
var promptFound = false;
|
||||
var gotLineCont = false;
|
||||
var gotHereDoc = false;
|
||||
const lineGotPrompt = [];
|
||||
for (const line of textContent.split('\n')) {
|
||||
match = line.match(regexp)
|
||||
if (match || gotLineCont || gotHereDoc) {
|
||||
promptFound = regexp.test(line)
|
||||
lineGotPrompt.push(promptFound)
|
||||
if (removePrompts && promptFound) {
|
||||
outputLines.push(match[2])
|
||||
} else {
|
||||
outputLines.push(line)
|
||||
}
|
||||
gotLineCont = line.endsWith(lineContinuationChar) & useLineCont
|
||||
if (line.includes(hereDocDelim) & useHereDoc)
|
||||
gotHereDoc = !gotHereDoc
|
||||
} else if (!onlyCopyPromptLines) {
|
||||
outputLines.push(line)
|
||||
} else if (copyEmptyLines && line.trim() === '') {
|
||||
outputLines.push(line)
|
||||
}
|
||||
}
|
||||
|
||||
// If no lines with the prompt were found then just use original lines
|
||||
if (lineGotPrompt.some(v => v === true)) {
|
||||
textContent = outputLines.join('\n');
|
||||
}
|
||||
|
||||
// Remove a trailing newline to avoid auto-running when pasting
|
||||
if (textContent.endsWith("\n")) {
|
||||
textContent = textContent.slice(0, -1)
|
||||
}
|
||||
return textContent
|
||||
}
|
||||
1
osxphotos/docs/_static/custom.css
vendored
1
osxphotos/docs/_static/custom.css
vendored
@@ -1 +0,0 @@
|
||||
/* This file intentionally left blank. */
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user