Added --regex query option, closes #433
This commit is contained in:
@@ -1,3 +1,3 @@
|
||||
""" version info """
|
||||
|
||||
__version__ = "0.42.8"
|
||||
__version__ = "0.42.9"
|
||||
|
||||
@@ -474,6 +474,15 @@ def QUERY_OPTIONS(f):
|
||||
"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(
|
||||
"--regex",
|
||||
metavar="REGEX TEMPLATE",
|
||||
nargs=2,
|
||||
multiple=True,
|
||||
help="Search for photos where TEMPLATE matches regular expression REGEX. "
|
||||
"For example, to find photos in an album that begins with 'Beach': '--regex \"^Beach\" \"{album}\"'. "
|
||||
"You may specify more than one regular expression match by repeating '--regex' with different arguments.",
|
||||
),
|
||||
o(
|
||||
"--query-eval",
|
||||
metavar="CRITERIA",
|
||||
@@ -1027,6 +1036,7 @@ def export(
|
||||
not_in_album,
|
||||
min_size,
|
||||
max_size,
|
||||
regex,
|
||||
query_eval,
|
||||
):
|
||||
"""Export photos from the Photos database.
|
||||
@@ -1177,6 +1187,7 @@ def export(
|
||||
not_in_album = cfg.not_in_album
|
||||
min_size = cfg.min_size
|
||||
max_size = cfg.max_size
|
||||
regex = cfg.regex
|
||||
query_eval = cfg.query_eval
|
||||
|
||||
# config file might have changed verbose
|
||||
@@ -1481,6 +1492,7 @@ def export(
|
||||
name=name,
|
||||
min_size=min_size,
|
||||
max_size=max_size,
|
||||
regex=regex,
|
||||
query_eval=query_eval,
|
||||
)
|
||||
|
||||
@@ -1780,6 +1792,7 @@ def query(
|
||||
not_in_album,
|
||||
min_size,
|
||||
max_size,
|
||||
regex,
|
||||
query_eval,
|
||||
):
|
||||
"""Query the Photos database using 1 or more search options;
|
||||
@@ -1810,6 +1823,7 @@ def query(
|
||||
query_eval,
|
||||
min_size,
|
||||
max_size,
|
||||
regex,
|
||||
]
|
||||
exclusive = [
|
||||
(favorite, not_favorite),
|
||||
@@ -1934,6 +1948,7 @@ def query(
|
||||
min_size=min_size,
|
||||
max_size=max_size,
|
||||
query_eval=query_eval,
|
||||
regex=regex,
|
||||
)
|
||||
|
||||
try:
|
||||
|
||||
@@ -3168,6 +3168,19 @@ class PhotosDB:
|
||||
if bitmath.Byte(p.original_filesize) <= options.max_size
|
||||
]
|
||||
|
||||
if options.regex:
|
||||
flags = re.IGNORECASE if options.ignore_case else 0
|
||||
for regex, template in options.regex:
|
||||
regex = re.compile(regex, flags)
|
||||
photo_list = []
|
||||
for p in photos:
|
||||
rendered, _ = p.render_template(template, none_str="")
|
||||
for value in rendered:
|
||||
if regex.search(value):
|
||||
photo_list.append(p)
|
||||
break
|
||||
photos = photo_list
|
||||
|
||||
if options.query_eval:
|
||||
for q in options.query_eval:
|
||||
query_string = f"[photo for photo in photos if {q}]"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
""" QueryOptions class for PhotosDB.query """
|
||||
|
||||
from dataclasses import dataclass
|
||||
from typing import Optional, Iterable
|
||||
from typing import Optional, Iterable, Tuple
|
||||
import datetime
|
||||
import bitmath
|
||||
|
||||
@@ -76,6 +76,7 @@ class QueryOptions:
|
||||
name: Optional[Iterable[str]] = None
|
||||
min_size: Optional[bitmath.Byte] = None
|
||||
max_size: Optional[bitmath.Byte] = None
|
||||
regex: Optional[Iterable[Tuple[str, str]]] = None
|
||||
query_eval: Optional[Iterable[str]] = None
|
||||
|
||||
def asdict(self):
|
||||
|
||||
Reference in New Issue
Block a user