Added --min-size, --max-size query options, #425
This commit is contained in:
parent
2e189d771e
commit
7ae5b8aae7
16
README.md
16
README.md
@ -315,6 +315,22 @@ Options:
|
||||
albums.
|
||||
|
||||
--not-in-album Search for photos that are not in any albums.
|
||||
--min-size SIZE Search for photos with size >= SIZE bytes. The
|
||||
size evaluated is the photo's original size
|
||||
(when imported to Photos). Size may be
|
||||
specified as integer bytes or using SI or NIST
|
||||
units. For example, the following are all
|
||||
valid and equivalent sizes: '1048576'
|
||||
'1.048576MB', '1 MiB'.
|
||||
|
||||
--max-size SIZE Search for photos with size <= SIZE bytes. The
|
||||
size evaluated is the photo's original size
|
||||
(when imported to Photos). Size may be
|
||||
specified as integer bytes or using SI or NIST
|
||||
units. For example, the following are all
|
||||
valid and equivalent sizes: '1048576'
|
||||
'1.048576MB', '1 MiB'.
|
||||
|
||||
--query-eval CRITERIA Evaluate CRITERIA to filter photos. CRITERIA
|
||||
will be evaluated in context of the following
|
||||
python list comprehension: `photos = [photo
|
||||
|
||||
@ -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: 2de28792352636d51e876bb33a863f93
|
||||
config: 041dede95604f7f8f5de01377fc1b414
|
||||
tags: 645f666f9bcd5a90fca523b33c5a78b7
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Overview: module code — osxphotos 0.42.3 documentation</title>
|
||||
<title>Overview: module code — osxphotos 0.42.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>
|
||||
|
||||
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.42.3',
|
||||
VERSION: '0.42.4',
|
||||
LANGUAGE: 'None',
|
||||
COLLAPSE_INDEX: false,
|
||||
BUILDER: 'html',
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>osxphotos command line interface (CLI) — osxphotos 0.42.3 documentation</title>
|
||||
<title>osxphotos command line interface (CLI) — osxphotos 0.42.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>
|
||||
@ -495,6 +495,18 @@ to modify this behavior.</p>
|
||||
<dd><p>Search for photos that are not in any albums.</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="std option">
|
||||
<dt id="cmdoption-osxphotos-export-min-size">
|
||||
<code class="sig-name descname"><span class="pre">--min-size</span></code><code class="sig-prename descclassname"> <span class="pre"><SIZE></span></code><a class="headerlink" href="#cmdoption-osxphotos-export-min-size" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>Search for photos with size >= SIZE bytes. The size evaluated is the photo’s original size (when imported to Photos). Size may be specified as integer bytes or using SI or NIST units. For example, the following are all valid and equivalent sizes: ‘1048576’ ‘1.048576MB’, ‘1 MiB’.</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="std option">
|
||||
<dt id="cmdoption-osxphotos-export-max-size">
|
||||
<code class="sig-name descname"><span class="pre">--max-size</span></code><code class="sig-prename descclassname"> <span class="pre"><SIZE></span></code><a class="headerlink" href="#cmdoption-osxphotos-export-max-size" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>Search for photos with size <= SIZE bytes. The size evaluated is the photo’s original size (when imported to Photos). Size may be specified as integer bytes or using SI or NIST units. For example, the following are all valid and equivalent sizes: ‘1048576’ ‘1.048576MB’, ‘1 MiB’.</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="std option">
|
||||
<dt id="cmdoption-osxphotos-export-query-eval">
|
||||
<code class="sig-name descname"><span class="pre">--query-eval</span></code><code class="sig-prename descclassname"> <span class="pre"><CRITERIA></span></code><a class="headerlink" href="#cmdoption-osxphotos-export-query-eval" title="Permalink to this definition">¶</a></dt>
|
||||
@ -1347,6 +1359,18 @@ if more than one option is provided, they are treated as “AND”
|
||||
<dd><p>Search for photos that are not in any albums.</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="std option">
|
||||
<dt id="cmdoption-osxphotos-query-min-size">
|
||||
<code class="sig-name descname"><span class="pre">--min-size</span></code><code class="sig-prename descclassname"> <span class="pre"><SIZE></span></code><a class="headerlink" href="#cmdoption-osxphotos-query-min-size" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>Search for photos with size >= SIZE bytes. The size evaluated is the photo’s original size (when imported to Photos). Size may be specified as integer bytes or using SI or NIST units. For example, the following are all valid and equivalent sizes: ‘1048576’ ‘1.048576MB’, ‘1 MiB’.</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="std option">
|
||||
<dt id="cmdoption-osxphotos-query-max-size">
|
||||
<code class="sig-name descname"><span class="pre">--max-size</span></code><code class="sig-prename descclassname"> <span class="pre"><SIZE></span></code><a class="headerlink" href="#cmdoption-osxphotos-query-max-size" title="Permalink to this definition">¶</a></dt>
|
||||
<dd><p>Search for photos with size <= SIZE bytes. The size evaluated is the photo’s original size (when imported to Photos). Size may be specified as integer bytes or using SI or NIST units. For example, the following are all valid and equivalent sizes: ‘1048576’ ‘1.048576MB’, ‘1 MiB’.</p>
|
||||
</dd></dl>
|
||||
|
||||
<dl class="std option">
|
||||
<dt id="cmdoption-osxphotos-query-query-eval">
|
||||
<code class="sig-name descname"><span class="pre">--query-eval</span></code><code class="sig-prename descclassname"> <span class="pre"><CRITERIA></span></code><a class="headerlink" href="#cmdoption-osxphotos-query-query-eval" title="Permalink to this definition">¶</a></dt>
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Index — osxphotos 0.42.3 documentation</title>
|
||||
<title>Index — osxphotos 0.42.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>
|
||||
@ -509,6 +509,24 @@
|
||||
|
||||
<ul>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-export-load-config">osxphotos-export command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
--max-size <SIZE>
|
||||
|
||||
<ul>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-export-max-size">osxphotos-export command line option</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-query-max-size">osxphotos-query command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
--min-size <SIZE>
|
||||
|
||||
<ul>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-export-min-size">osxphotos-export command line option</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-query-min-size">osxphotos-query command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
<li>
|
||||
@ -547,6 +565,8 @@
|
||||
<li><a href="cli.html#cmdoption-osxphotos-query-no-description">osxphotos-query command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
</ul></td>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li>
|
||||
--no-likes
|
||||
|
||||
@ -556,8 +576,6 @@
|
||||
<li><a href="cli.html#cmdoption-osxphotos-query-no-likes">osxphotos-query command line option</a>
|
||||
</li>
|
||||
</ul></li>
|
||||
</ul></td>
|
||||
<td style="width: 33%; vertical-align: top;"><ul>
|
||||
<li>
|
||||
--no-place
|
||||
|
||||
@ -1555,6 +1573,10 @@
|
||||
<li><a href="cli.html#cmdoption-osxphotos-export-live">--live</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-export-load-config">--load-config <config file path></a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-export-max-size">--max-size <SIZE></a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-export-min-size">--min-size <SIZE></a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-export-missing">--missing</a>
|
||||
</li>
|
||||
@ -1811,6 +1833,10 @@
|
||||
<li><a href="cli.html#cmdoption-osxphotos-query-label">--label <LABEL></a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-query-live">--live</a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-query-max-size">--max-size <SIZE></a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-query-min-size">--min-size <SIZE></a>
|
||||
</li>
|
||||
<li><a href="cli.html#cmdoption-osxphotos-query-missing">--missing</a>
|
||||
</li>
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Welcome to osxphotos’s documentation! — osxphotos 0.42.3 documentation</title>
|
||||
<title>Welcome to osxphotos’s documentation! — osxphotos 0.42.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>
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>osxphotos — osxphotos 0.42.3 documentation</title>
|
||||
<title>osxphotos — osxphotos 0.42.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>
|
||||
|
||||
BIN
docs/objects.inv
BIN
docs/objects.inv
Binary file not shown.
Binary file not shown.
@ -5,7 +5,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>osxphotos package — osxphotos 0.42.3 documentation</title>
|
||||
<title>osxphotos package — osxphotos 0.42.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>
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Search — osxphotos 0.42.3 documentation</title>
|
||||
<title>Search — osxphotos 0.42.4 documentation</title>
|
||||
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
|
||||
<link rel="stylesheet" href="_static/alabaster.css" type="text/css" />
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
@ -1,3 +1,3 @@
|
||||
""" version info """
|
||||
|
||||
__version__ = "0.42.3"
|
||||
__version__ = "0.42.4"
|
||||
|
||||
@ -11,6 +11,7 @@ import sys
|
||||
import time
|
||||
import unicodedata
|
||||
|
||||
import bitmath
|
||||
import click
|
||||
import osxmetadata
|
||||
import yaml
|
||||
@ -131,6 +132,26 @@ class DateTimeISO8601(click.ParamType):
|
||||
)
|
||||
|
||||
|
||||
class BitMathSize(click.ParamType):
|
||||
|
||||
name = "BITMATH"
|
||||
|
||||
def convert(self, value, param, ctx):
|
||||
try:
|
||||
value = bitmath.parse_string(value)
|
||||
except ValueError:
|
||||
# no units specified
|
||||
try:
|
||||
value = int(value)
|
||||
value = bitmath.Byte(value)
|
||||
except ValueError as e:
|
||||
self.fail(
|
||||
f"{value} must be specified as bytes or using SI/NIST units. "
|
||||
+ "For example, the following are all valid and equivalent sizes: '1048576' '1.048576MB', '1 MiB'."
|
||||
)
|
||||
return value
|
||||
|
||||
|
||||
class TimeISO8601(click.ParamType):
|
||||
|
||||
name = "TIME"
|
||||
@ -447,6 +468,24 @@ def query_options(f):
|
||||
is_flag=True,
|
||||
help="Search for photos that are not in any albums.",
|
||||
),
|
||||
o(
|
||||
"--min-size",
|
||||
metavar="SIZE",
|
||||
type=BitMathSize(),
|
||||
help="Search for photos with size >= SIZE bytes. "
|
||||
"The size evaluated is the photo's original size (when imported to Photos). "
|
||||
"Size may be specified as integer bytes or using SI or NIST units. "
|
||||
"For example, the following are all valid and equivalent sizes: '1048576' '1.048576MB', '1 MiB'.",
|
||||
),
|
||||
o(
|
||||
"--max-size",
|
||||
metavar="SIZE",
|
||||
type=BitMathSize(),
|
||||
help="Search for photos with size <= SIZE bytes. "
|
||||
"The size evaluated is the photo's original size (when imported to Photos). "
|
||||
"Size may be specified as integer bytes or using SI or NIST units. "
|
||||
"For example, the following are all valid and equivalent sizes: '1048576' '1.048576MB', '1 MiB'.",
|
||||
),
|
||||
o(
|
||||
"--query-eval",
|
||||
metavar="CRITERIA",
|
||||
@ -998,6 +1037,8 @@ def export(
|
||||
beta,
|
||||
in_album,
|
||||
not_in_album,
|
||||
min_size,
|
||||
max_size,
|
||||
query_eval,
|
||||
):
|
||||
"""Export photos from the Photos database.
|
||||
@ -1146,6 +1187,8 @@ def export(
|
||||
only_new = cfg.only_new
|
||||
in_album = cfg.in_album
|
||||
not_in_album = cfg.not_in_album
|
||||
min_size = cfg.min_size
|
||||
max_size = cfg.max_size
|
||||
query_eval = cfg.query_eval
|
||||
|
||||
# config file might have changed verbose
|
||||
@ -1449,6 +1492,8 @@ def export(
|
||||
# skip missing bursts if using --download-missing by itself as AppleScript otherwise causes errors
|
||||
missing_bursts=(download_missing and use_photokit) or not download_missing,
|
||||
name=name,
|
||||
min_size=min_size,
|
||||
max_size=max_size,
|
||||
query_eval=query_eval,
|
||||
)
|
||||
|
||||
@ -1735,6 +1780,8 @@ def query(
|
||||
is_reference,
|
||||
in_album,
|
||||
not_in_album,
|
||||
min_size,
|
||||
max_size,
|
||||
query_eval,
|
||||
):
|
||||
"""Query the Photos database using 1 or more search options;
|
||||
@ -1763,6 +1810,8 @@ def query(
|
||||
label,
|
||||
is_reference,
|
||||
query_eval,
|
||||
min_size,
|
||||
max_size,
|
||||
]
|
||||
exclusive = [
|
||||
(favorite, not_favorite),
|
||||
@ -1885,6 +1934,8 @@ def query(
|
||||
in_album=in_album,
|
||||
not_in_album=not_in_album,
|
||||
name=name,
|
||||
min_size=min_size,
|
||||
max_size=max_size,
|
||||
query_eval=query_eval,
|
||||
)
|
||||
|
||||
@ -2064,6 +2115,8 @@ def _query(
|
||||
burst_photos=None,
|
||||
missing_bursts=None,
|
||||
name=None,
|
||||
min_size=None,
|
||||
max_size=None,
|
||||
query_eval=None,
|
||||
):
|
||||
"""Run a query against PhotosDB to extract the photos based on user supply criteria used by query and export commands
|
||||
@ -2359,6 +2412,12 @@ def _query(
|
||||
)
|
||||
photos = photo_list
|
||||
|
||||
if min_size:
|
||||
photos = [p for p in photos if bitmath.Byte(p.original_filesize) >= min_size]
|
||||
|
||||
if max_size:
|
||||
photos = [p for p in photos if bitmath.Byte(p.original_filesize) <= max_size]
|
||||
|
||||
if query_eval:
|
||||
for q in query_eval:
|
||||
query_string = f"[photo for photo in photos if {q}]"
|
||||
|
||||
@ -9,6 +9,7 @@ atomicwrites==1.3.0
|
||||
attrs==19.1.0
|
||||
backcall==0.1.0
|
||||
better-exceptions-fork==0.2.1.post6
|
||||
bitmath==1.3.3.1
|
||||
bleach==3.3.0
|
||||
bpylist2==3.0.2
|
||||
certifi==2020.4.5.1
|
||||
|
||||
1
setup.py
1
setup.py
@ -86,6 +86,7 @@ setup(
|
||||
"osxmetadata>=0.99.13",
|
||||
"textx==2.3.0",
|
||||
"rich>=9.11.1",
|
||||
"bitmath==bitmath 1.3.3.1",
|
||||
],
|
||||
entry_points={"console_scripts": ["osxphotos=osxphotos.__main__:cli"]},
|
||||
include_package_data=True,
|
||||
|
||||
@ -5861,3 +5861,135 @@ def test_bad_query_eval():
|
||||
)
|
||||
assert result.exit_code != 0
|
||||
assert "Error: Invalid query-eval CRITERIA" in result.output
|
||||
|
||||
|
||||
def test_query_min_size_1():
|
||||
""" test query --min-size """
|
||||
import json
|
||||
import os
|
||||
import os.path
|
||||
import osxphotos
|
||||
from osxphotos.cli import query
|
||||
|
||||
runner = CliRunner()
|
||||
cwd = os.getcwd()
|
||||
result = runner.invoke(
|
||||
query,
|
||||
["--json", "--db", os.path.join(cwd, PHOTOS_DB_15_7), "--min-size", "10MB"],
|
||||
)
|
||||
assert result.exit_code == 0
|
||||
json_got = json.loads(result.output)
|
||||
|
||||
assert len(json_got) == 2
|
||||
|
||||
|
||||
def test_query_min_size_2():
|
||||
""" test query --min-size """
|
||||
import json
|
||||
import os
|
||||
import os.path
|
||||
import osxphotos
|
||||
from osxphotos.cli import query
|
||||
|
||||
runner = CliRunner()
|
||||
cwd = os.getcwd()
|
||||
result = runner.invoke(
|
||||
query,
|
||||
[
|
||||
"--json",
|
||||
"--db",
|
||||
os.path.join(cwd, PHOTOS_DB_15_7),
|
||||
"--min-size",
|
||||
"10_000_000",
|
||||
],
|
||||
)
|
||||
assert result.exit_code == 0
|
||||
json_got = json.loads(result.output)
|
||||
|
||||
assert len(json_got) == 2
|
||||
|
||||
|
||||
def test_query_max_size_1():
|
||||
""" test query --max-size """
|
||||
import json
|
||||
import os
|
||||
import os.path
|
||||
import osxphotos
|
||||
from osxphotos.cli import query
|
||||
|
||||
runner = CliRunner()
|
||||
cwd = os.getcwd()
|
||||
result = runner.invoke(
|
||||
query,
|
||||
["--json", "--db", os.path.join(cwd, PHOTOS_DB_15_7), "--max-size", "500 kB"],
|
||||
)
|
||||
assert result.exit_code == 0
|
||||
json_got = json.loads(result.output)
|
||||
|
||||
assert len(json_got) == 1
|
||||
|
||||
|
||||
def test_query_max_size_2():
|
||||
""" test query --max-size """
|
||||
import json
|
||||
import os
|
||||
import os.path
|
||||
import osxphotos
|
||||
from osxphotos.cli import query
|
||||
|
||||
runner = CliRunner()
|
||||
cwd = os.getcwd()
|
||||
result = runner.invoke(
|
||||
query,
|
||||
["--json", "--db", os.path.join(cwd, PHOTOS_DB_15_7), "--max-size", "500_000"],
|
||||
)
|
||||
assert result.exit_code == 0
|
||||
json_got = json.loads(result.output)
|
||||
|
||||
assert len(json_got) == 1
|
||||
|
||||
|
||||
def test_query_min_max_size():
|
||||
""" test query --max-size with --min-size"""
|
||||
import json
|
||||
import os
|
||||
import os.path
|
||||
import osxphotos
|
||||
from osxphotos.cli import query
|
||||
|
||||
runner = CliRunner()
|
||||
cwd = os.getcwd()
|
||||
result = runner.invoke(
|
||||
query,
|
||||
[
|
||||
"--json",
|
||||
"--db",
|
||||
os.path.join(cwd, PHOTOS_DB_15_7),
|
||||
"--min-size",
|
||||
"48MB",
|
||||
"--max-size",
|
||||
"49MB",
|
||||
],
|
||||
)
|
||||
assert result.exit_code == 0
|
||||
json_got = json.loads(result.output)
|
||||
|
||||
assert len(json_got) == 1
|
||||
|
||||
|
||||
def test_query_min_size_error():
|
||||
""" test query --max-size with invalid size """
|
||||
import json
|
||||
import os
|
||||
import os.path
|
||||
import osxphotos
|
||||
from osxphotos.cli import query
|
||||
|
||||
runner = CliRunner()
|
||||
cwd = os.getcwd()
|
||||
result = runner.invoke(
|
||||
query,
|
||||
["--json", "--db", os.path.join(cwd, PHOTOS_DB_15_7), "--min-size", "500 foo"],
|
||||
)
|
||||
assert result.exit_code != 0
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user