Added debug output to exiftool
This commit is contained in:
@@ -1741,7 +1741,7 @@ Substitution Description
|
|||||||
{lf} A line feed: '\n', alias for {newline}
|
{lf} A line feed: '\n', alias for {newline}
|
||||||
{cr} A carriage return: '\r'
|
{cr} A carriage return: '\r'
|
||||||
{crlf} a carriage return + line feed: '\r\n'
|
{crlf} a carriage return + line feed: '\r\n'
|
||||||
{osxphotos_version} The osxphotos version, e.g. '0.46.1'
|
{osxphotos_version} The osxphotos version, e.g. '0.46.2'
|
||||||
{osxphotos_cmd_line} The full command line used to run osxphotos
|
{osxphotos_cmd_line} The full command line used to run osxphotos
|
||||||
|
|
||||||
The following substitutions may result in multiple values. Thus if specified for
|
The following substitutions may result in multiple values. Thus if specified for
|
||||||
@@ -3645,7 +3645,7 @@ The following template field substitutions are availabe for use the templating s
|
|||||||
|{lf}|A line feed: '\n', alias for {newline}|
|
|{lf}|A line feed: '\n', alias for {newline}|
|
||||||
|{cr}|A carriage return: '\r'|
|
|{cr}|A carriage return: '\r'|
|
||||||
|{crlf}|a carriage return + line feed: '\r\n'|
|
|{crlf}|a carriage return + line feed: '\r\n'|
|
||||||
|{osxphotos_version}|The osxphotos version, e.g. '0.46.1'|
|
|{osxphotos_version}|The osxphotos version, e.g. '0.46.2'|
|
||||||
|{osxphotos_cmd_line}|The full command line used to run osxphotos|
|
|{osxphotos_cmd_line}|The full command line used to run osxphotos|
|
||||||
|{album}|Album(s) photo is contained in|
|
|{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|
|
|{folder_album}|Folder path + album photo is contained in. e.g. 'Folder/Subfolder/Album' or just 'Album' if no enclosing folder|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Sphinx build info version 1
|
# 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.
|
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
|
||||||
config: d6da9902a4771e5081ae73c361960af8
|
config: 3bdc7daae06c46fa0e6357e497a27088
|
||||||
tags: 645f666f9bcd5a90fca523b33c5a78b7
|
tags: 645f666f9bcd5a90fca523b33c5a78b7
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Overview: module code — osxphotos 0.46.1 documentation</title>
|
<title>Overview: module code — osxphotos 0.46.2 documentation</title>
|
||||||
<link rel="stylesheet" type="text/css" href="../_static/pygments.css" />
|
<link rel="stylesheet" type="text/css" href="../_static/pygments.css" />
|
||||||
<link rel="stylesheet" type="text/css" href="../_static/alabaster.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 data-url_root="../" id="documentation_options" src="../_static/documentation_options.js"></script>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>osxphotos.photosdb.photosdb — osxphotos 0.46.0 documentation</title>
|
<title>osxphotos.photosdb.photosdb — osxphotos 0.46.2 documentation</title>
|
||||||
<link rel="stylesheet" type="text/css" href="../../../_static/pygments.css" />
|
<link rel="stylesheet" type="text/css" href="../../../_static/pygments.css" />
|
||||||
<link rel="stylesheet" type="text/css" href="../../../_static/alabaster.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 data-url_root="../../../" id="documentation_options" src="../../../_static/documentation_options.js"></script>
|
||||||
@@ -3312,27 +3312,6 @@
|
|||||||
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">to_time</span><span class="p">:</span>
|
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">to_time</span><span class="p">:</span>
|
||||||
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="n">p</span><span class="o">.</span><span class="n">date</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o"><=</span> <span class="n">options</span><span class="o">.</span><span class="n">to_time</span><span class="p">]</span>
|
<span class="n">photos</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="n">p</span><span class="o">.</span><span class="n">date</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o"><=</span> <span class="n">options</span><span class="o">.</span><span class="n">to_time</span><span class="p">]</span>
|
||||||
|
|
||||||
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">burst_photos</span><span class="p">:</span>
|
|
||||||
<span class="c1"># add the burst_photos to the export set</span>
|
|
||||||
<span class="n">photos_burst</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="n">p</span><span class="o">.</span><span class="n">burst</span><span class="p">]</span>
|
|
||||||
<span class="k">for</span> <span class="n">burst</span> <span class="ow">in</span> <span class="n">photos_burst</span><span class="p">:</span>
|
|
||||||
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">missing_bursts</span><span class="p">:</span>
|
|
||||||
<span class="c1"># include burst photos that are missing</span>
|
|
||||||
<span class="n">photos</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">burst</span><span class="o">.</span><span class="n">burst_photos</span><span class="p">)</span>
|
|
||||||
<span class="k">else</span><span class="p">:</span>
|
|
||||||
<span class="c1"># don't include missing burst images (these can't be downloaded with AppleScript)</span>
|
|
||||||
<span class="n">photos</span><span class="o">.</span><span class="n">extend</span><span class="p">([</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">burst</span><span class="o">.</span><span class="n">burst_photos</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">p</span><span class="o">.</span><span class="n">ismissing</span><span class="p">])</span>
|
|
||||||
|
|
||||||
<span class="c1"># remove duplicates as each burst photo in the set that's selected would</span>
|
|
||||||
<span class="c1"># result in the entire set being added above</span>
|
|
||||||
<span class="c1"># can't use set() because PhotoInfo not hashable</span>
|
|
||||||
<span class="n">seen_uuids</span> <span class="o">=</span> <span class="p">{}</span>
|
|
||||||
<span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span><span class="p">:</span>
|
|
||||||
<span class="k">if</span> <span class="n">p</span><span class="o">.</span><span class="n">uuid</span> <span class="ow">in</span> <span class="n">seen_uuids</span><span class="p">:</span>
|
|
||||||
<span class="k">continue</span>
|
|
||||||
<span class="n">seen_uuids</span><span class="p">[</span><span class="n">p</span><span class="o">.</span><span class="n">uuid</span><span class="p">]</span> <span class="o">=</span> <span class="n">p</span>
|
|
||||||
<span class="n">photos</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">seen_uuids</span><span class="o">.</span><span class="n">values</span><span class="p">())</span>
|
|
||||||
|
|
||||||
<span class="k">if</span> <span class="n">name</span><span class="p">:</span>
|
<span class="k">if</span> <span class="n">name</span><span class="p">:</span>
|
||||||
<span class="c1"># search filename fields for text</span>
|
<span class="c1"># search filename fields for text</span>
|
||||||
<span class="c1"># if more than one, find photos with all title values in filename</span>
|
<span class="c1"># if more than one, find photos with all title values in filename</span>
|
||||||
@@ -3483,6 +3462,28 @@
|
|||||||
<span class="k">for</span> <span class="n">function</span> <span class="ow">in</span> <span class="n">options</span><span class="o">.</span><span class="n">function</span><span class="p">:</span>
|
<span class="k">for</span> <span class="n">function</span> <span class="ow">in</span> <span class="n">options</span><span class="o">.</span><span class="n">function</span><span class="p">:</span>
|
||||||
<span class="n">photos</span> <span class="o">=</span> <span class="n">function</span><span class="p">[</span><span class="mi">0</span><span class="p">](</span><span class="n">photos</span><span class="p">)</span>
|
<span class="n">photos</span> <span class="o">=</span> <span class="n">function</span><span class="p">[</span><span class="mi">0</span><span class="p">](</span><span class="n">photos</span><span class="p">)</span>
|
||||||
|
|
||||||
|
<span class="c1"># burst should be checked last, ref #640</span>
|
||||||
|
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">burst_photos</span><span class="p">:</span>
|
||||||
|
<span class="c1"># add the burst_photos to the export set</span>
|
||||||
|
<span class="n">photos_burst</span> <span class="o">=</span> <span class="p">[</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span> <span class="k">if</span> <span class="n">p</span><span class="o">.</span><span class="n">burst</span><span class="p">]</span>
|
||||||
|
<span class="k">for</span> <span class="n">burst</span> <span class="ow">in</span> <span class="n">photos_burst</span><span class="p">:</span>
|
||||||
|
<span class="k">if</span> <span class="n">options</span><span class="o">.</span><span class="n">missing_bursts</span><span class="p">:</span>
|
||||||
|
<span class="c1"># include burst photos that are missing</span>
|
||||||
|
<span class="n">photos</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">burst</span><span class="o">.</span><span class="n">burst_photos</span><span class="p">)</span>
|
||||||
|
<span class="k">else</span><span class="p">:</span>
|
||||||
|
<span class="c1"># don't include missing burst images (these can't be downloaded with AppleScript)</span>
|
||||||
|
<span class="n">photos</span><span class="o">.</span><span class="n">extend</span><span class="p">([</span><span class="n">p</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">burst</span><span class="o">.</span><span class="n">burst_photos</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">p</span><span class="o">.</span><span class="n">ismissing</span><span class="p">])</span>
|
||||||
|
|
||||||
|
<span class="c1"># remove duplicates as each burst photo in the set that's selected would</span>
|
||||||
|
<span class="c1"># result in the entire set being added above</span>
|
||||||
|
<span class="c1"># can't use set() because PhotoInfo not hashable</span>
|
||||||
|
<span class="n">seen_uuids</span> <span class="o">=</span> <span class="p">{}</span>
|
||||||
|
<span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">photos</span><span class="p">:</span>
|
||||||
|
<span class="k">if</span> <span class="n">p</span><span class="o">.</span><span class="n">uuid</span> <span class="ow">in</span> <span class="n">seen_uuids</span><span class="p">:</span>
|
||||||
|
<span class="k">continue</span>
|
||||||
|
<span class="n">seen_uuids</span><span class="p">[</span><span class="n">p</span><span class="o">.</span><span class="n">uuid</span><span class="p">]</span> <span class="o">=</span> <span class="n">p</span>
|
||||||
|
<span class="n">photos</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">seen_uuids</span><span class="o">.</span><span class="n">values</span><span class="p">())</span>
|
||||||
|
|
||||||
<span class="k">return</span> <span class="n">photos</span></div>
|
<span class="k">return</span> <span class="n">photos</span></div>
|
||||||
|
|
||||||
<div class="viewcode-block" id="PhotosDB.execute"><a class="viewcode-back" href="../../../reference.html#osxphotos.PhotosDB.execute">[docs]</a> <span class="k">def</span> <span class="nf">execute</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">sql</span><span class="p">):</span>
|
<div class="viewcode-block" id="PhotosDB.execute"><a class="viewcode-back" href="../../../reference.html#osxphotos.PhotosDB.execute">[docs]</a> <span class="k">def</span> <span class="nf">execute</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">sql</span><span class="p">):</span>
|
||||||
@@ -3568,7 +3569,6 @@
|
|||||||
<h3>Navigation</h3>
|
<h3>Navigation</h3>
|
||||||
<ul>
|
<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="../../../cli.html">osxphotos command line interface (CLI)</a></li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../../modules.html">osxphotos</a></li>
|
|
||||||
<li class="toctree-l1"><a class="reference internal" href="../../../reference.html">osxphotos package</a></li>
|
<li class="toctree-l1"><a class="reference internal" href="../../../reference.html">osxphotos package</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
|||||||
2
docs/_static/documentation_options.js
vendored
2
docs/_static/documentation_options.js
vendored
@@ -1,6 +1,6 @@
|
|||||||
var DOCUMENTATION_OPTIONS = {
|
var DOCUMENTATION_OPTIONS = {
|
||||||
URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'),
|
URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'),
|
||||||
VERSION: '0.46.1',
|
VERSION: '0.46.2',
|
||||||
LANGUAGE: 'None',
|
LANGUAGE: 'None',
|
||||||
COLLAPSE_INDEX: false,
|
COLLAPSE_INDEX: false,
|
||||||
BUILDER: 'html',
|
BUILDER: 'html',
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
||||||
|
|
||||||
<title>osxphotos command line interface (CLI) — osxphotos 0.46.1 documentation</title>
|
<title>osxphotos command line interface (CLI) — osxphotos 0.46.2 documentation</title>
|
||||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
||||||
<link rel="stylesheet" type="text/css" href="_static/alabaster.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 data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Index — osxphotos 0.46.1 documentation</title>
|
<title>Index — osxphotos 0.46.2 documentation</title>
|
||||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
||||||
<link rel="stylesheet" type="text/css" href="_static/alabaster.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 data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
||||||
|
|
||||||
<title>Welcome to osxphotos’s documentation! — osxphotos 0.46.1 documentation</title>
|
<title>Welcome to osxphotos’s documentation! — osxphotos 0.46.2 documentation</title>
|
||||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
||||||
<link rel="stylesheet" type="text/css" href="_static/alabaster.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 data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
||||||
|
|
||||||
<title>osxphotos — osxphotos 0.46.1 documentation</title>
|
<title>osxphotos — osxphotos 0.46.2 documentation</title>
|
||||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
||||||
<link rel="stylesheet" type="text/css" href="_static/alabaster.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 data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
|
||||||
|
|
||||||
<title>osxphotos package — osxphotos 0.46.1 documentation</title>
|
<title>osxphotos package — osxphotos 0.46.2 documentation</title>
|
||||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
||||||
<link rel="stylesheet" type="text/css" href="_static/alabaster.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 data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Search — osxphotos 0.46.1 documentation</title>
|
<title>Search — osxphotos 0.46.2 documentation</title>
|
||||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
||||||
<link rel="stylesheet" type="text/css" href="_static/alabaster.css" />
|
<link rel="stylesheet" type="text/css" href="_static/alabaster.css" />
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
""" version info """
|
""" version info """
|
||||||
|
|
||||||
__version__ = "0.46.2"
|
__version__ = "0.46.3"
|
||||||
|
|||||||
@@ -2298,6 +2298,9 @@ def help(ctx, topic, **kw):
|
|||||||
"This only works if the Photos library being queried is the last-opened (default) library in Photos. "
|
"This only works if the Photos library being queried is the last-opened (default) library in Photos. "
|
||||||
"This feature is currently experimental. I don't know how well it will work on large query sets.",
|
"This feature is currently experimental. I don't know how well it will work on large query sets.",
|
||||||
)
|
)
|
||||||
|
@click.option(
|
||||||
|
"--debug", required=False, is_flag=True, default=False, hidden=OSXPHOTOS_HIDDEN
|
||||||
|
)
|
||||||
@DB_ARGUMENT
|
@DB_ARGUMENT
|
||||||
@click.pass_obj
|
@click.pass_obj
|
||||||
@click.pass_context
|
@click.pass_context
|
||||||
@@ -2382,12 +2385,18 @@ def query(
|
|||||||
query_eval,
|
query_eval,
|
||||||
query_function,
|
query_function,
|
||||||
add_to_album,
|
add_to_album,
|
||||||
|
debug,
|
||||||
):
|
):
|
||||||
"""Query the Photos database using 1 or more search options;
|
"""Query the Photos database using 1 or more search options;
|
||||||
if more than one option is provided, they are treated as "AND"
|
if more than one option is provided, they are treated as "AND"
|
||||||
(e.g. search for photos matching all options).
|
(e.g. search for photos matching all options).
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
global DEBUG
|
||||||
|
if debug:
|
||||||
|
DEBUG = True
|
||||||
|
osxphotos._set_debug(True)
|
||||||
|
|
||||||
# if no query terms, show help and return
|
# if no query terms, show help and return
|
||||||
# sanity check input args
|
# sanity check input args
|
||||||
nonexclusive = [
|
nonexclusive = [
|
||||||
|
|||||||
@@ -103,9 +103,11 @@ class _ExifToolProc:
|
|||||||
|
|
||||||
return cls.instance
|
return cls.instance
|
||||||
|
|
||||||
def __init__(self, exiftool=None):
|
def __init__(self, exiftool=None, debug=False):
|
||||||
"""construct _ExifToolProc singleton object or return instance of already created object
|
"""construct _ExifToolProc singleton object or return instance of already created object
|
||||||
exiftool: optional path to exiftool binary (if not provided, will search path to find it)"""
|
exiftool: optional path to exiftool binary (if not provided, will search path to find it)
|
||||||
|
debug: optional bool to enable debugging output
|
||||||
|
"""
|
||||||
|
|
||||||
if hasattr(self, "_process_running") and self._process_running:
|
if hasattr(self, "_process_running") and self._process_running:
|
||||||
# already running
|
# already running
|
||||||
@@ -115,9 +117,11 @@ class _ExifToolProc:
|
|||||||
f"ignoring exiftool={exiftool}"
|
f"ignoring exiftool={exiftool}"
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
self.debug = debug
|
||||||
self._process_running = False
|
self._process_running = False
|
||||||
self._exiftool = exiftool or get_exiftool_path()
|
self._exiftool = exiftool or get_exiftool_path()
|
||||||
|
if self.debug:
|
||||||
|
logging.debug(f"exiftool={self._exiftool}")
|
||||||
self._start_proc()
|
self._start_proc()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@@ -167,10 +171,17 @@ class _ExifToolProc:
|
|||||||
self._process_running = True
|
self._process_running = True
|
||||||
|
|
||||||
EXIFTOOL_PROCESSES.append(self)
|
EXIFTOOL_PROCESSES.append(self)
|
||||||
|
if self.debug:
|
||||||
|
logging.debug(
|
||||||
|
"exiftool process started: {self._process} {self._process_running}"
|
||||||
|
)
|
||||||
|
|
||||||
def _stop_proc(self):
|
def _stop_proc(self):
|
||||||
"""stop the exiftool process if it's running, otherwise, do nothing"""
|
"""stop the exiftool process if it's running, otherwise, do nothing"""
|
||||||
|
|
||||||
|
if self.debug:
|
||||||
|
logging.debug(f"exiftool process stopping: {self._process}")
|
||||||
|
|
||||||
if not self._process_running:
|
if not self._process_running:
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -190,11 +201,16 @@ class _ExifToolProc:
|
|||||||
del self._process
|
del self._process
|
||||||
self._process_running = False
|
self._process_running = False
|
||||||
|
|
||||||
|
if self.debug:
|
||||||
|
logging.debug(f"exiftool process stopped: {self._process}")
|
||||||
|
|
||||||
|
|
||||||
class ExifTool:
|
class ExifTool:
|
||||||
"""Basic exiftool interface for reading and writing EXIF tags"""
|
"""Basic exiftool interface for reading and writing EXIF tags"""
|
||||||
|
|
||||||
def __init__(self, filepath, exiftool=None, overwrite=True, flags=None):
|
def __init__(
|
||||||
|
self, filepath, exiftool=None, overwrite=True, flags=None, debug=False
|
||||||
|
):
|
||||||
"""Create ExifTool object
|
"""Create ExifTool object
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@@ -202,6 +218,7 @@ class ExifTool:
|
|||||||
exiftool: path to exiftool, if not specified will look in path
|
exiftool: path to exiftool, if not specified will look in path
|
||||||
overwrite: if True, will overwrite image file without creating backup, default=False
|
overwrite: if True, will overwrite image file without creating backup, default=False
|
||||||
flags: optional list of exiftool flags to prepend to exiftool command when writing metadata (e.g. -m or -F)
|
flags: optional list of exiftool flags to prepend to exiftool command when writing metadata (e.g. -m or -F)
|
||||||
|
debug: if True, enables debug output
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
ExifTool instance
|
ExifTool instance
|
||||||
@@ -209,6 +226,7 @@ class ExifTool:
|
|||||||
self.file = filepath
|
self.file = filepath
|
||||||
self.overwrite = overwrite
|
self.overwrite = overwrite
|
||||||
self.flags = flags or []
|
self.flags = flags or []
|
||||||
|
self.debug = debug
|
||||||
self.data = {}
|
self.data = {}
|
||||||
self.warning = None
|
self.warning = None
|
||||||
self.error = None
|
self.error = None
|
||||||
@@ -342,6 +360,9 @@ class ExifTool:
|
|||||||
+ b"-execute\n"
|
+ b"-execute\n"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if self.debug:
|
||||||
|
logging.debug(f"running exiftool command: {command_str}")
|
||||||
|
|
||||||
# send the command
|
# send the command
|
||||||
self._process.stdin.write(command_str)
|
self._process.stdin.write(command_str)
|
||||||
self._process.stdin.flush()
|
self._process.stdin.flush()
|
||||||
@@ -362,6 +383,11 @@ class ExifTool:
|
|||||||
error = "" if error == b"" else error.decode("utf-8")
|
error = "" if error == b"" else error.decode("utf-8")
|
||||||
self.warning = warning
|
self.warning = warning
|
||||||
self.error = error
|
self.error = error
|
||||||
|
if self.debug:
|
||||||
|
logging.debug(
|
||||||
|
f"run_commands: output={output[:-EXIFTOOL_STAYOPEN_EOF_LEN]}, warning={warning}, error={error}"
|
||||||
|
)
|
||||||
|
|
||||||
return output[:-EXIFTOOL_STAYOPEN_EOF_LEN], warning, error
|
return output[:-EXIFTOOL_STAYOPEN_EOF_LEN], warning, error
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@@ -406,18 +432,25 @@ class ExifTool:
|
|||||||
if normalized:
|
if normalized:
|
||||||
exifdict = {k.lower(): v for (k, v) in exifdict.items()}
|
exifdict = {k.lower(): v for (k, v) in exifdict.items()}
|
||||||
|
|
||||||
|
if self.debug:
|
||||||
|
logging.debug(f"asdict: {exifdict}")
|
||||||
|
|
||||||
return exifdict
|
return exifdict
|
||||||
|
|
||||||
def json(self):
|
def json(self):
|
||||||
"""returns JSON string containing all EXIF tags and values from exiftool"""
|
"""returns JSON string containing all EXIF tags and values from exiftool"""
|
||||||
json, _, _ = self.run_commands("-json")
|
json, _, _ = self.run_commands("-json")
|
||||||
json = unescape_str(json.decode("utf-8"))
|
json = unescape_str(json.decode("utf-8"))
|
||||||
|
if self.debug:
|
||||||
|
logging.debug(f"json: {json}")
|
||||||
return json
|
return json
|
||||||
|
|
||||||
def _read_exif(self):
|
def _read_exif(self):
|
||||||
"""read exif data from file"""
|
"""read exif data from file"""
|
||||||
data = self.asdict()
|
data = self.asdict()
|
||||||
self.data = {k: v for k, v in data.items()}
|
self.data = {k: v for k, v in data.items()}
|
||||||
|
if self.debug:
|
||||||
|
logging.debug(f"_read_exif: {self.data}")
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"file: {self.file}\nexiftool: {self._exiftoolproc._exiftool}"
|
return f"file: {self.file}\nexiftool: {self._exiftoolproc._exiftool}"
|
||||||
@@ -443,15 +476,17 @@ class ExifToolCaching(ExifTool):
|
|||||||
|
|
||||||
_singletons = {}
|
_singletons = {}
|
||||||
|
|
||||||
def __new__(cls, filepath, exiftool=None):
|
def __new__(cls, filepath, exiftool=None, debug=False):
|
||||||
"""create new object or return instance of already created singleton"""
|
"""create new object or return instance of already created singleton"""
|
||||||
if filepath not in cls._singletons:
|
if filepath not in cls._singletons:
|
||||||
cls._singletons[filepath] = _ExifToolCaching(filepath, exiftool=exiftool)
|
cls._singletons[filepath] = _ExifToolCaching(
|
||||||
|
filepath, exiftool=exiftool, debug=debug
|
||||||
|
)
|
||||||
return cls._singletons[filepath]
|
return cls._singletons[filepath]
|
||||||
|
|
||||||
|
|
||||||
class _ExifToolCaching(ExifTool):
|
class _ExifToolCaching(ExifTool):
|
||||||
def __init__(self, filepath, exiftool=None):
|
def __init__(self, filepath, exiftool=None, debug=False):
|
||||||
"""Create read-only ExifTool object that caches values
|
"""Create read-only ExifTool object that caches values
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@@ -461,9 +496,12 @@ class _ExifToolCaching(ExifTool):
|
|||||||
Returns:
|
Returns:
|
||||||
ExifTool instance
|
ExifTool instance
|
||||||
"""
|
"""
|
||||||
|
self.debug = debug
|
||||||
self._json_cache = None
|
self._json_cache = None
|
||||||
self._asdict_cache = {}
|
self._asdict_cache = {}
|
||||||
super().__init__(filepath, exiftool=exiftool, overwrite=False, flags=None)
|
super().__init__(
|
||||||
|
filepath, exiftool=exiftool, overwrite=False, flags=None, debug=debug
|
||||||
|
)
|
||||||
|
|
||||||
def run_commands(self, *commands, no_file=False):
|
def run_commands(self, *commands, no_file=False):
|
||||||
if commands[0] not in ["-json", "-ver"]:
|
if commands[0] not in ["-json", "-ver"]:
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ from .scoreinfo import ScoreInfo
|
|||||||
from .searchinfo import SearchInfo
|
from .searchinfo import SearchInfo
|
||||||
from .text_detection import detect_text
|
from .text_detection import detect_text
|
||||||
from .uti import get_preferred_uti_extension, get_uti_for_extension
|
from .uti import get_preferred_uti_extension, get_uti_for_extension
|
||||||
from .utils import _debug, _get_resource_loc, list_directory
|
from .utils import _debug, _get_resource_loc, list_directory, _debug
|
||||||
|
|
||||||
__all__ = ["PhotoInfo", "PhotoInfoNone"]
|
__all__ = ["PhotoInfo", "PhotoInfoNone"]
|
||||||
|
|
||||||
@@ -1343,7 +1343,7 @@ class PhotoInfo:
|
|||||||
try:
|
try:
|
||||||
exiftool_path = self._db._exiftool_path or get_exiftool_path()
|
exiftool_path = self._db._exiftool_path or get_exiftool_path()
|
||||||
if self.path is not None and os.path.isfile(self.path):
|
if self.path is not None and os.path.isfile(self.path):
|
||||||
exiftool = ExifToolCaching(self.path, exiftool=exiftool_path)
|
exiftool = ExifToolCaching(self.path, exiftool=exiftool_path, debug=_debug())
|
||||||
else:
|
else:
|
||||||
exiftool = None
|
exiftool = None
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
|
|||||||
Reference in New Issue
Block a user