@@ -380,6 +380,31 @@ def QUERY_OPTIONS(f):
|
|||||||
multiple=True,
|
multiple=True,
|
||||||
type=int,
|
type=int,
|
||||||
),
|
),
|
||||||
|
o(
|
||||||
|
"--added-before",
|
||||||
|
metavar="DATE",
|
||||||
|
help="Search for items added to the library before a specific date/time, "
|
||||||
|
"e.g. --added-before e.g. 2000-01-12T12:00:00, 2001-01-12T12:00:00-07:00, or 2000-12-31 (ISO 8601 with/without timezone).",
|
||||||
|
type=DateTimeISO8601(),
|
||||||
|
),
|
||||||
|
o(
|
||||||
|
"--added-after",
|
||||||
|
metavar="DATE",
|
||||||
|
help="Search for items added to the libray after a specific date/time, "
|
||||||
|
"e.g. --added-after e.g. 2000-01-12T12:00:00, 2001-01-12T12:00:00-07:00, or 2000-12-31 (ISO 8601 with/without timezone).",
|
||||||
|
type=DateTimeISO8601(),
|
||||||
|
),
|
||||||
|
o(
|
||||||
|
"--added-in-last",
|
||||||
|
metavar="TIME_DELTA",
|
||||||
|
help="Search for items added to the library in the last TIME_DELTA, "
|
||||||
|
"where TIME_DELTA is a string like "
|
||||||
|
"'12 hrs', '1 day', '1d', '1 week', '2weeks', '1 month', '1 year'. "
|
||||||
|
"for example, `--added-in-last 7d` and `--added-in-last '1 week'` are equivalent. "
|
||||||
|
"months are assumed to be 30 days and years are assumed to be 365 days. "
|
||||||
|
"Common English abbreviations are accepted, e.g. d, day, days or m, min, minutes.",
|
||||||
|
type=TimeOffset(),
|
||||||
|
),
|
||||||
o("--has-comment", is_flag=True, help="Search for photos that have comments."),
|
o("--has-comment", is_flag=True, help="Search for photos that have comments."),
|
||||||
o("--no-comment", is_flag=True, help="Search for photos with no comments."),
|
o("--no-comment", is_flag=True, help="Search for photos with no comments."),
|
||||||
o("--has-likes", is_flag=True, help="Search for photos that have likes."),
|
o("--has-likes", is_flag=True, help="Search for photos that have likes."),
|
||||||
@@ -569,4 +594,3 @@ def check_version():
|
|||||||
"to suppress this message and prevent osxphotos from checking for latest version.",
|
"to suppress this message and prevent osxphotos from checking for latest version.",
|
||||||
err=True,
|
err=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -672,145 +672,148 @@ def export(
|
|||||||
cli_obj,
|
cli_obj,
|
||||||
db,
|
db,
|
||||||
photos_library,
|
photos_library,
|
||||||
keyword,
|
add_exported_to_album,
|
||||||
person,
|
add_missing_to_album,
|
||||||
album,
|
add_skipped_to_album,
|
||||||
folder,
|
added_after,
|
||||||
uuid,
|
added_before,
|
||||||
name,
|
added_in_last,
|
||||||
uuid_from_file,
|
|
||||||
title,
|
|
||||||
no_title,
|
|
||||||
description,
|
|
||||||
no_description,
|
|
||||||
uti,
|
|
||||||
ignore_case,
|
|
||||||
edited,
|
|
||||||
external_edit,
|
|
||||||
favorite,
|
|
||||||
not_favorite,
|
|
||||||
hidden,
|
|
||||||
not_hidden,
|
|
||||||
shared,
|
|
||||||
not_shared,
|
|
||||||
from_date,
|
|
||||||
to_date,
|
|
||||||
from_time,
|
|
||||||
to_time,
|
|
||||||
year,
|
|
||||||
verbose,
|
|
||||||
timestamp,
|
|
||||||
no_progress,
|
|
||||||
missing,
|
|
||||||
update,
|
|
||||||
force_update,
|
|
||||||
ignore_signature,
|
|
||||||
only_new,
|
|
||||||
dry_run,
|
|
||||||
export_as_hardlink,
|
|
||||||
touch_file,
|
|
||||||
overwrite,
|
|
||||||
retry,
|
|
||||||
export_by_date,
|
|
||||||
skip_edited,
|
|
||||||
skip_original_if_edited,
|
|
||||||
skip_bursts,
|
|
||||||
skip_live,
|
|
||||||
skip_raw,
|
|
||||||
skip_uuid,
|
|
||||||
skip_uuid_from_file,
|
|
||||||
person_keyword,
|
|
||||||
album_keyword,
|
album_keyword,
|
||||||
keyword_template,
|
album,
|
||||||
replace_keywords,
|
beta,
|
||||||
description_template,
|
|
||||||
finder_tag_template,
|
|
||||||
finder_tag_keywords,
|
|
||||||
xattr_template,
|
|
||||||
current_name,
|
|
||||||
convert_to_jpeg,
|
|
||||||
jpeg_quality,
|
|
||||||
sidecar,
|
|
||||||
sidecar_drop_ext,
|
|
||||||
only_photos,
|
|
||||||
only_movies,
|
|
||||||
burst,
|
burst,
|
||||||
not_burst,
|
cleanup,
|
||||||
live,
|
config_only,
|
||||||
not_live,
|
convert_to_jpeg,
|
||||||
download_missing,
|
current_name,
|
||||||
|
deleted_only,
|
||||||
|
deleted,
|
||||||
|
description_template,
|
||||||
|
description,
|
||||||
dest,
|
dest,
|
||||||
exiftool,
|
directory,
|
||||||
exiftool_path,
|
download_missing,
|
||||||
exiftool_option,
|
dry_run,
|
||||||
|
duplicate,
|
||||||
|
edited_suffix,
|
||||||
|
edited,
|
||||||
|
exif,
|
||||||
exiftool_merge_keywords,
|
exiftool_merge_keywords,
|
||||||
exiftool_merge_persons,
|
exiftool_merge_persons,
|
||||||
ignore_date_modified,
|
exiftool_option,
|
||||||
portrait,
|
exiftool_path,
|
||||||
not_portrait,
|
exiftool,
|
||||||
screenshot,
|
export_as_hardlink,
|
||||||
not_screenshot,
|
export_by_date,
|
||||||
slow_mo,
|
|
||||||
not_slow_mo,
|
|
||||||
time_lapse,
|
|
||||||
not_time_lapse,
|
|
||||||
hdr,
|
|
||||||
not_hdr,
|
|
||||||
selfie,
|
|
||||||
not_selfie,
|
|
||||||
panorama,
|
|
||||||
not_panorama,
|
|
||||||
has_raw,
|
|
||||||
directory,
|
|
||||||
filename_template,
|
|
||||||
jpeg_ext,
|
|
||||||
strip,
|
|
||||||
edited_suffix,
|
|
||||||
original_suffix,
|
|
||||||
place,
|
|
||||||
no_place,
|
|
||||||
location,
|
|
||||||
no_location,
|
|
||||||
has_comment,
|
|
||||||
no_comment,
|
|
||||||
has_likes,
|
|
||||||
no_likes,
|
|
||||||
label,
|
|
||||||
deleted,
|
|
||||||
deleted_only,
|
|
||||||
use_photos_export,
|
|
||||||
use_photokit,
|
|
||||||
report,
|
|
||||||
cleanup,
|
|
||||||
add_exported_to_album,
|
|
||||||
add_skipped_to_album,
|
|
||||||
add_missing_to_album,
|
|
||||||
exportdb,
|
exportdb,
|
||||||
ramdb,
|
external_edit,
|
||||||
tmpdir,
|
favorite,
|
||||||
load_config,
|
filename_template,
|
||||||
save_config,
|
finder_tag_keywords,
|
||||||
config_only,
|
finder_tag_template,
|
||||||
is_reference,
|
folder,
|
||||||
beta,
|
force_update,
|
||||||
|
from_date,
|
||||||
|
from_time,
|
||||||
|
has_comment,
|
||||||
|
has_likes,
|
||||||
|
has_raw,
|
||||||
|
hdr,
|
||||||
|
hidden,
|
||||||
|
ignore_case,
|
||||||
|
ignore_date_modified,
|
||||||
|
ignore_signature,
|
||||||
in_album,
|
in_album,
|
||||||
not_in_album,
|
is_reference,
|
||||||
min_size,
|
jpeg_ext,
|
||||||
|
jpeg_quality,
|
||||||
|
keyword_template,
|
||||||
|
keyword,
|
||||||
|
label,
|
||||||
|
live,
|
||||||
|
load_config,
|
||||||
|
location,
|
||||||
max_size,
|
max_size,
|
||||||
regex,
|
min_size,
|
||||||
selected,
|
missing,
|
||||||
exif,
|
name,
|
||||||
query_eval,
|
no_comment,
|
||||||
query_function,
|
no_description,
|
||||||
duplicate,
|
no_likes,
|
||||||
|
no_location,
|
||||||
|
no_place,
|
||||||
|
no_progress,
|
||||||
|
no_title,
|
||||||
|
not_burst,
|
||||||
|
not_favorite,
|
||||||
|
not_hdr,
|
||||||
|
not_hidden,
|
||||||
|
not_in_album,
|
||||||
|
not_live,
|
||||||
|
not_panorama,
|
||||||
|
not_portrait,
|
||||||
|
not_screenshot,
|
||||||
|
not_selfie,
|
||||||
|
not_shared,
|
||||||
|
not_slow_mo,
|
||||||
|
not_time_lapse,
|
||||||
|
only_movies,
|
||||||
|
only_new,
|
||||||
|
only_photos,
|
||||||
|
original_suffix,
|
||||||
|
overwrite,
|
||||||
|
panorama,
|
||||||
|
person_keyword,
|
||||||
|
person,
|
||||||
|
place,
|
||||||
|
portrait,
|
||||||
post_command,
|
post_command,
|
||||||
post_function,
|
post_function,
|
||||||
preview,
|
|
||||||
preview_suffix,
|
|
||||||
preview_if_missing,
|
preview_if_missing,
|
||||||
profile,
|
preview_suffix,
|
||||||
|
preview,
|
||||||
profile_sort,
|
profile_sort,
|
||||||
|
profile,
|
||||||
|
query_eval,
|
||||||
|
query_function,
|
||||||
|
ramdb,
|
||||||
|
regex,
|
||||||
|
replace_keywords,
|
||||||
|
report,
|
||||||
|
retry,
|
||||||
|
save_config,
|
||||||
|
screenshot,
|
||||||
|
selected,
|
||||||
|
selfie,
|
||||||
|
shared,
|
||||||
|
sidecar_drop_ext,
|
||||||
|
sidecar,
|
||||||
|
skip_bursts,
|
||||||
|
skip_edited,
|
||||||
|
skip_live,
|
||||||
|
skip_original_if_edited,
|
||||||
|
skip_raw,
|
||||||
|
skip_uuid_from_file,
|
||||||
|
skip_uuid,
|
||||||
|
slow_mo,
|
||||||
|
strip,
|
||||||
theme,
|
theme,
|
||||||
|
time_lapse,
|
||||||
|
timestamp,
|
||||||
|
title,
|
||||||
|
tmpdir,
|
||||||
|
to_date,
|
||||||
|
to_time,
|
||||||
|
touch_file,
|
||||||
|
update,
|
||||||
|
use_photokit,
|
||||||
|
use_photos_export,
|
||||||
|
uti,
|
||||||
|
uuid_from_file,
|
||||||
|
uuid,
|
||||||
|
verbose,
|
||||||
|
xattr_template,
|
||||||
|
year,
|
||||||
debug, # debug, watch, breakpoint handled in cli/__init__.py
|
debug, # debug, watch, breakpoint handled in cli/__init__.py
|
||||||
watch,
|
watch,
|
||||||
breakpoint,
|
breakpoint,
|
||||||
@@ -886,6 +889,9 @@ def export(
|
|||||||
|
|
||||||
# re-set the local vars to the corresponding config value
|
# re-set the local vars to the corresponding config value
|
||||||
# this isn't elegant but avoids having to rewrite this function to use cfg.varname for every parameter
|
# this isn't elegant but avoids having to rewrite this function to use cfg.varname for every parameter
|
||||||
|
added_after = cfg.added_after
|
||||||
|
added_before = cfg.added_before
|
||||||
|
added_in_last = cfg.added_in_last
|
||||||
add_exported_to_album = cfg.add_exported_to_album
|
add_exported_to_album = cfg.add_exported_to_album
|
||||||
add_missing_to_album = cfg.add_missing_to_album
|
add_missing_to_album = cfg.add_missing_to_album
|
||||||
add_skipped_to_album = cfg.add_skipped_to_album
|
add_skipped_to_album = cfg.add_skipped_to_album
|
||||||
@@ -1038,41 +1044,41 @@ def export(
|
|||||||
|
|
||||||
# validate options
|
# validate options
|
||||||
exclusive_options = [
|
exclusive_options = [
|
||||||
("favorite", "not_favorite"),
|
|
||||||
("hidden", "not_hidden"),
|
|
||||||
("title", "no_title"),
|
|
||||||
("description", "no_description"),
|
|
||||||
("only_photos", "only_movies"),
|
|
||||||
("burst", "not_burst"),
|
("burst", "not_burst"),
|
||||||
("live", "not_live"),
|
|
||||||
("portrait", "not_portrait"),
|
|
||||||
("screenshot", "not_screenshot"),
|
|
||||||
("slow_mo", "not_slow_mo"),
|
|
||||||
("time_lapse", "not_time_lapse"),
|
|
||||||
("hdr", "not_hdr"),
|
|
||||||
("selfie", "not_selfie"),
|
|
||||||
("panorama", "not_panorama"),
|
|
||||||
("export_by_date", "directory"),
|
|
||||||
("export_as_hardlink", "exiftool"),
|
|
||||||
("place", "no_place"),
|
|
||||||
("deleted", "deleted_only"),
|
("deleted", "deleted_only"),
|
||||||
("skip_edited", "skip_original_if_edited"),
|
("description", "no_description"),
|
||||||
("export_as_hardlink", "convert_to_jpeg"),
|
("export_as_hardlink", "convert_to_jpeg"),
|
||||||
("export_as_hardlink", "download_missing"),
|
("export_as_hardlink", "download_missing"),
|
||||||
("shared", "not_shared"),
|
("export_as_hardlink", "exiftool"),
|
||||||
|
("export_by_date", "directory"),
|
||||||
|
("favorite", "not_favorite"),
|
||||||
("has_comment", "no_comment"),
|
("has_comment", "no_comment"),
|
||||||
("has_likes", "no_likes"),
|
("has_likes", "no_likes"),
|
||||||
|
("hdr", "not_hdr"),
|
||||||
|
("hidden", "not_hidden"),
|
||||||
("in_album", "not_in_album"),
|
("in_album", "not_in_album"),
|
||||||
|
("live", "not_live"),
|
||||||
("location", "no_location"),
|
("location", "no_location"),
|
||||||
|
("only_photos", "only_movies"),
|
||||||
|
("panorama", "not_panorama"),
|
||||||
|
("place", "no_place"),
|
||||||
|
("portrait", "not_portrait"),
|
||||||
|
("screenshot", "not_screenshot"),
|
||||||
|
("selfie", "not_selfie"),
|
||||||
|
("shared", "not_shared"),
|
||||||
|
("skip_edited", "skip_original_if_edited"),
|
||||||
|
("slow_mo", "not_slow_mo"),
|
||||||
|
("time_lapse", "not_time_lapse"),
|
||||||
|
("title", "no_title"),
|
||||||
]
|
]
|
||||||
dependent_options = [
|
dependent_options = [
|
||||||
("missing", ("download_missing", "use_photos_export")),
|
|
||||||
("jpeg_quality", ("convert_to_jpeg")),
|
|
||||||
("ignore_signature", ("update", "force_update")),
|
|
||||||
("only_new", ("update", "force_update")),
|
|
||||||
("exiftool_option", ("exiftool")),
|
|
||||||
("exiftool_merge_keywords", ("exiftool", "sidecar")),
|
("exiftool_merge_keywords", ("exiftool", "sidecar")),
|
||||||
("exiftool_merge_persons", ("exiftool", "sidecar")),
|
("exiftool_merge_persons", ("exiftool", "sidecar")),
|
||||||
|
("exiftool_option", ("exiftool")),
|
||||||
|
("ignore_signature", ("update", "force_update")),
|
||||||
|
("jpeg_quality", ("convert_to_jpeg")),
|
||||||
|
("missing", ("download_missing", "use_photos_export")),
|
||||||
|
("only_new", ("update", "force_update")),
|
||||||
]
|
]
|
||||||
try:
|
try:
|
||||||
cfg.validate(exclusive=exclusive_options, dependent=dependent_options, cli=True)
|
cfg.validate(exclusive=exclusive_options, dependent=dependent_options, cli=True)
|
||||||
@@ -1267,83 +1273,86 @@ def export(
|
|||||||
photosdb._beta = beta
|
photosdb._beta = beta
|
||||||
|
|
||||||
query_options = QueryOptions(
|
query_options = QueryOptions(
|
||||||
keyword=keyword,
|
added_after=added_after,
|
||||||
person=person,
|
added_before=added_before,
|
||||||
|
added_in_last=added_in_last,
|
||||||
album=album,
|
album=album,
|
||||||
folder=folder,
|
burst_photos=export_bursts,
|
||||||
uuid=uuid,
|
burst=burst,
|
||||||
title=title,
|
cloudasset=False,
|
||||||
no_title=no_title,
|
deleted_only=deleted_only,
|
||||||
|
deleted=deleted,
|
||||||
description=description,
|
description=description,
|
||||||
no_description=no_description,
|
duplicate=duplicate,
|
||||||
ignore_case=ignore_case,
|
|
||||||
edited=edited,
|
edited=edited,
|
||||||
|
exif=exif,
|
||||||
external_edit=external_edit,
|
external_edit=external_edit,
|
||||||
favorite=favorite,
|
favorite=favorite,
|
||||||
not_favorite=not_favorite,
|
folder=folder,
|
||||||
hidden=hidden,
|
|
||||||
not_hidden=not_hidden,
|
|
||||||
missing=missing,
|
|
||||||
not_missing=None,
|
|
||||||
shared=shared,
|
|
||||||
not_shared=not_shared,
|
|
||||||
photos=photos,
|
|
||||||
movies=movies,
|
|
||||||
uti=uti,
|
|
||||||
burst=burst,
|
|
||||||
not_burst=not_burst,
|
|
||||||
live=live,
|
|
||||||
not_live=not_live,
|
|
||||||
cloudasset=False,
|
|
||||||
not_cloudasset=False,
|
|
||||||
incloud=False,
|
|
||||||
not_incloud=False,
|
|
||||||
from_date=from_date,
|
from_date=from_date,
|
||||||
to_date=to_date,
|
|
||||||
from_time=from_time,
|
from_time=from_time,
|
||||||
to_time=to_time,
|
function=query_function,
|
||||||
year=year,
|
|
||||||
portrait=portrait,
|
|
||||||
not_portrait=not_portrait,
|
|
||||||
screenshot=screenshot,
|
|
||||||
not_screenshot=not_screenshot,
|
|
||||||
slow_mo=slow_mo,
|
|
||||||
not_slow_mo=not_slow_mo,
|
|
||||||
time_lapse=time_lapse,
|
|
||||||
not_time_lapse=not_time_lapse,
|
|
||||||
hdr=hdr,
|
|
||||||
not_hdr=not_hdr,
|
|
||||||
selfie=selfie,
|
|
||||||
not_selfie=not_selfie,
|
|
||||||
panorama=panorama,
|
|
||||||
not_panorama=not_panorama,
|
|
||||||
has_raw=has_raw,
|
|
||||||
place=place,
|
|
||||||
no_place=no_place,
|
|
||||||
location=location,
|
|
||||||
no_location=no_location,
|
|
||||||
label=label,
|
|
||||||
deleted=deleted,
|
|
||||||
deleted_only=deleted_only,
|
|
||||||
has_comment=has_comment,
|
has_comment=has_comment,
|
||||||
no_comment=no_comment,
|
|
||||||
has_likes=has_likes,
|
has_likes=has_likes,
|
||||||
no_likes=no_likes,
|
has_raw=has_raw,
|
||||||
is_reference=is_reference,
|
hdr=hdr,
|
||||||
|
hidden=hidden,
|
||||||
|
ignore_case=ignore_case,
|
||||||
in_album=in_album,
|
in_album=in_album,
|
||||||
not_in_album=not_in_album,
|
incloud=False,
|
||||||
burst_photos=export_bursts,
|
is_reference=is_reference,
|
||||||
|
keyword=keyword,
|
||||||
|
label=label,
|
||||||
|
live=live,
|
||||||
|
location=location,
|
||||||
|
max_size=max_size,
|
||||||
|
min_size=min_size,
|
||||||
# skip missing bursts if using --download-missing by itself as AppleScript otherwise causes errors
|
# skip missing bursts if using --download-missing by itself as AppleScript otherwise causes errors
|
||||||
missing_bursts=(download_missing and use_photokit) or not download_missing,
|
missing_bursts=(download_missing and use_photokit) or not download_missing,
|
||||||
|
missing=missing,
|
||||||
|
movies=movies,
|
||||||
name=name,
|
name=name,
|
||||||
min_size=min_size,
|
no_comment=no_comment,
|
||||||
max_size=max_size,
|
no_description=no_description,
|
||||||
regex=regex,
|
no_likes=no_likes,
|
||||||
selected=selected,
|
no_location=no_location,
|
||||||
exif=exif,
|
no_place=no_place,
|
||||||
|
no_title=no_title,
|
||||||
|
not_burst=not_burst,
|
||||||
|
not_cloudasset=False,
|
||||||
|
not_favorite=not_favorite,
|
||||||
|
not_hdr=not_hdr,
|
||||||
|
not_hidden=not_hidden,
|
||||||
|
not_in_album=not_in_album,
|
||||||
|
not_incloud=False,
|
||||||
|
not_live=not_live,
|
||||||
|
not_missing=None,
|
||||||
|
not_panorama=not_panorama,
|
||||||
|
not_portrait=not_portrait,
|
||||||
|
not_screenshot=not_screenshot,
|
||||||
|
not_selfie=not_selfie,
|
||||||
|
not_shared=not_shared,
|
||||||
|
not_slow_mo=not_slow_mo,
|
||||||
|
not_time_lapse=not_time_lapse,
|
||||||
|
panorama=panorama,
|
||||||
|
person=person,
|
||||||
|
photos=photos,
|
||||||
|
place=place,
|
||||||
|
portrait=portrait,
|
||||||
query_eval=query_eval,
|
query_eval=query_eval,
|
||||||
function=query_function,
|
regex=regex,
|
||||||
duplicate=duplicate,
|
screenshot=screenshot,
|
||||||
|
selected=selected,
|
||||||
|
selfie=selfie,
|
||||||
|
shared=shared,
|
||||||
|
slow_mo=slow_mo,
|
||||||
|
time_lapse=time_lapse,
|
||||||
|
title=title,
|
||||||
|
to_date=to_date,
|
||||||
|
to_time=to_time,
|
||||||
|
uti=uti,
|
||||||
|
uuid=uuid,
|
||||||
|
year=year,
|
||||||
)
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -73,83 +73,86 @@ def query(
|
|||||||
cli_obj,
|
cli_obj,
|
||||||
db,
|
db,
|
||||||
photos_library,
|
photos_library,
|
||||||
keyword,
|
add_to_album,
|
||||||
person,
|
added_after,
|
||||||
|
added_before,
|
||||||
|
added_in_last,
|
||||||
album,
|
album,
|
||||||
folder,
|
burst,
|
||||||
name,
|
cloudasset,
|
||||||
uuid,
|
deleted_only,
|
||||||
uuid_from_file,
|
deleted,
|
||||||
title,
|
|
||||||
no_title,
|
|
||||||
description,
|
description,
|
||||||
no_description,
|
duplicate,
|
||||||
ignore_case,
|
|
||||||
json_,
|
|
||||||
edited,
|
edited,
|
||||||
|
exif,
|
||||||
external_edit,
|
external_edit,
|
||||||
favorite,
|
favorite,
|
||||||
not_favorite,
|
folder,
|
||||||
|
from_date,
|
||||||
|
from_time,
|
||||||
|
has_comment,
|
||||||
|
has_likes,
|
||||||
|
has_raw,
|
||||||
|
hdr,
|
||||||
hidden,
|
hidden,
|
||||||
not_hidden,
|
ignore_case,
|
||||||
|
in_album,
|
||||||
|
incloud,
|
||||||
|
is_reference,
|
||||||
|
json_,
|
||||||
|
keyword,
|
||||||
|
label,
|
||||||
|
live,
|
||||||
|
location,
|
||||||
|
max_size,
|
||||||
|
min_size,
|
||||||
missing,
|
missing,
|
||||||
|
name,
|
||||||
|
no_comment,
|
||||||
|
no_description,
|
||||||
|
no_likes,
|
||||||
|
no_location,
|
||||||
|
no_place,
|
||||||
|
no_title,
|
||||||
|
not_burst,
|
||||||
|
not_cloudasset,
|
||||||
|
not_favorite,
|
||||||
|
not_hdr,
|
||||||
|
not_hidden,
|
||||||
|
not_in_album,
|
||||||
|
not_incloud,
|
||||||
|
not_live,
|
||||||
not_missing,
|
not_missing,
|
||||||
shared,
|
not_panorama,
|
||||||
|
not_portrait,
|
||||||
|
not_screenshot,
|
||||||
|
not_selfie,
|
||||||
not_shared,
|
not_shared,
|
||||||
|
not_slow_mo,
|
||||||
|
not_time_lapse,
|
||||||
only_movies,
|
only_movies,
|
||||||
only_photos,
|
only_photos,
|
||||||
uti,
|
|
||||||
burst,
|
|
||||||
not_burst,
|
|
||||||
live,
|
|
||||||
not_live,
|
|
||||||
cloudasset,
|
|
||||||
not_cloudasset,
|
|
||||||
incloud,
|
|
||||||
not_incloud,
|
|
||||||
from_date,
|
|
||||||
to_date,
|
|
||||||
from_time,
|
|
||||||
to_time,
|
|
||||||
year,
|
|
||||||
portrait,
|
|
||||||
not_portrait,
|
|
||||||
screenshot,
|
|
||||||
not_screenshot,
|
|
||||||
slow_mo,
|
|
||||||
not_slow_mo,
|
|
||||||
time_lapse,
|
|
||||||
not_time_lapse,
|
|
||||||
hdr,
|
|
||||||
not_hdr,
|
|
||||||
selfie,
|
|
||||||
not_selfie,
|
|
||||||
panorama,
|
panorama,
|
||||||
not_panorama,
|
person,
|
||||||
has_raw,
|
|
||||||
place,
|
place,
|
||||||
no_place,
|
portrait,
|
||||||
location,
|
|
||||||
no_location,
|
|
||||||
label,
|
|
||||||
deleted,
|
|
||||||
deleted_only,
|
|
||||||
has_comment,
|
|
||||||
no_comment,
|
|
||||||
has_likes,
|
|
||||||
no_likes,
|
|
||||||
is_reference,
|
|
||||||
in_album,
|
|
||||||
not_in_album,
|
|
||||||
duplicate,
|
|
||||||
min_size,
|
|
||||||
max_size,
|
|
||||||
regex,
|
|
||||||
selected,
|
|
||||||
exif,
|
|
||||||
query_eval,
|
query_eval,
|
||||||
query_function,
|
query_function,
|
||||||
add_to_album,
|
regex,
|
||||||
|
screenshot,
|
||||||
|
selected,
|
||||||
|
selfie,
|
||||||
|
shared,
|
||||||
|
slow_mo,
|
||||||
|
time_lapse,
|
||||||
|
title,
|
||||||
|
to_date,
|
||||||
|
to_time,
|
||||||
|
uti,
|
||||||
|
uuid_from_file,
|
||||||
|
uuid,
|
||||||
|
year,
|
||||||
debug, # handled in cli/__init__.py
|
debug, # handled in cli/__init__.py
|
||||||
):
|
):
|
||||||
"""Query the Photos database using 1 or more search options;
|
"""Query the Photos database using 1 or more search options;
|
||||||
@@ -160,58 +163,61 @@ def query(
|
|||||||
# 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 = [
|
||||||
keyword,
|
added_after,
|
||||||
person,
|
added_before,
|
||||||
|
added_in_last,
|
||||||
album,
|
album,
|
||||||
folder,
|
duplicate,
|
||||||
name,
|
|
||||||
uuid,
|
|
||||||
uuid_from_file,
|
|
||||||
edited,
|
edited,
|
||||||
|
exif,
|
||||||
external_edit,
|
external_edit,
|
||||||
uti,
|
folder,
|
||||||
has_raw,
|
|
||||||
from_date,
|
from_date,
|
||||||
to_date,
|
|
||||||
from_time,
|
from_time,
|
||||||
to_time,
|
has_raw,
|
||||||
year,
|
|
||||||
label,
|
|
||||||
is_reference,
|
is_reference,
|
||||||
|
keyword,
|
||||||
|
label,
|
||||||
|
max_size,
|
||||||
|
min_size,
|
||||||
|
name,
|
||||||
|
person,
|
||||||
query_eval,
|
query_eval,
|
||||||
query_function,
|
query_function,
|
||||||
min_size,
|
|
||||||
max_size,
|
|
||||||
regex,
|
regex,
|
||||||
selected,
|
selected,
|
||||||
exif,
|
to_date,
|
||||||
duplicate,
|
to_time,
|
||||||
|
uti,
|
||||||
|
uuid_from_file,
|
||||||
|
uuid,
|
||||||
|
year,
|
||||||
]
|
]
|
||||||
exclusive = [
|
exclusive = [
|
||||||
(favorite, not_favorite),
|
|
||||||
(hidden, not_hidden),
|
|
||||||
(missing, not_missing),
|
|
||||||
(any(title), no_title),
|
|
||||||
(any(description), no_description),
|
(any(description), no_description),
|
||||||
(only_photos, only_movies),
|
|
||||||
(burst, not_burst),
|
|
||||||
(live, not_live),
|
|
||||||
(cloudasset, not_cloudasset),
|
|
||||||
(incloud, not_incloud),
|
|
||||||
(portrait, not_portrait),
|
|
||||||
(screenshot, not_screenshot),
|
|
||||||
(slow_mo, not_slow_mo),
|
|
||||||
(time_lapse, not_time_lapse),
|
|
||||||
(hdr, not_hdr),
|
|
||||||
(selfie, not_selfie),
|
|
||||||
(panorama, not_panorama),
|
|
||||||
(any(place), no_place),
|
(any(place), no_place),
|
||||||
|
(any(title), no_title),
|
||||||
|
(burst, not_burst),
|
||||||
|
(cloudasset, not_cloudasset),
|
||||||
(deleted, deleted_only),
|
(deleted, deleted_only),
|
||||||
(shared, not_shared),
|
(favorite, not_favorite),
|
||||||
(has_comment, no_comment),
|
(has_comment, no_comment),
|
||||||
(has_likes, no_likes),
|
(has_likes, no_likes),
|
||||||
|
(hdr, not_hdr),
|
||||||
|
(hidden, not_hidden),
|
||||||
(in_album, not_in_album),
|
(in_album, not_in_album),
|
||||||
|
(incloud, not_incloud),
|
||||||
|
(live, not_live),
|
||||||
(location, no_location),
|
(location, no_location),
|
||||||
|
(missing, not_missing),
|
||||||
|
(only_photos, only_movies),
|
||||||
|
(panorama, not_panorama),
|
||||||
|
(portrait, not_portrait),
|
||||||
|
(screenshot, not_screenshot),
|
||||||
|
(selfie, not_selfie),
|
||||||
|
(shared, not_shared),
|
||||||
|
(slow_mo, not_slow_mo),
|
||||||
|
(time_lapse, not_time_lapse),
|
||||||
]
|
]
|
||||||
# print help if no non-exclusive term or a double exclusive term is given
|
# print help if no non-exclusive term or a double exclusive term is given
|
||||||
if any(all(bb) for bb in exclusive) or not any(
|
if any(all(bb) for bb in exclusive) or not any(
|
||||||
@@ -247,80 +253,83 @@ def query(
|
|||||||
|
|
||||||
photosdb = osxphotos.PhotosDB(dbfile=db)
|
photosdb = osxphotos.PhotosDB(dbfile=db)
|
||||||
query_options = QueryOptions(
|
query_options = QueryOptions(
|
||||||
keyword=keyword,
|
added_after=added_after,
|
||||||
person=person,
|
added_before=added_before,
|
||||||
|
added_in_last=added_in_last,
|
||||||
album=album,
|
album=album,
|
||||||
folder=folder,
|
burst=burst,
|
||||||
uuid=uuid,
|
cloudasset=cloudasset,
|
||||||
title=title,
|
deleted_only=deleted_only,
|
||||||
no_title=no_title,
|
deleted=deleted,
|
||||||
description=description,
|
description=description,
|
||||||
no_description=no_description,
|
duplicate=duplicate,
|
||||||
ignore_case=ignore_case,
|
|
||||||
edited=edited,
|
edited=edited,
|
||||||
|
exif=exif,
|
||||||
external_edit=external_edit,
|
external_edit=external_edit,
|
||||||
favorite=favorite,
|
favorite=favorite,
|
||||||
not_favorite=not_favorite,
|
folder=folder,
|
||||||
hidden=hidden,
|
|
||||||
not_hidden=not_hidden,
|
|
||||||
missing=missing,
|
|
||||||
not_missing=not_missing,
|
|
||||||
shared=shared,
|
|
||||||
not_shared=not_shared,
|
|
||||||
photos=photos,
|
|
||||||
movies=movies,
|
|
||||||
uti=uti,
|
|
||||||
burst=burst,
|
|
||||||
not_burst=not_burst,
|
|
||||||
live=live,
|
|
||||||
not_live=not_live,
|
|
||||||
cloudasset=cloudasset,
|
|
||||||
not_cloudasset=not_cloudasset,
|
|
||||||
incloud=incloud,
|
|
||||||
not_incloud=not_incloud,
|
|
||||||
from_date=from_date,
|
from_date=from_date,
|
||||||
to_date=to_date,
|
|
||||||
from_time=from_time,
|
from_time=from_time,
|
||||||
to_time=to_time,
|
|
||||||
year=year,
|
|
||||||
portrait=portrait,
|
|
||||||
not_portrait=not_portrait,
|
|
||||||
screenshot=screenshot,
|
|
||||||
not_screenshot=not_screenshot,
|
|
||||||
slow_mo=slow_mo,
|
|
||||||
not_slow_mo=not_slow_mo,
|
|
||||||
time_lapse=time_lapse,
|
|
||||||
not_time_lapse=not_time_lapse,
|
|
||||||
hdr=hdr,
|
|
||||||
not_hdr=not_hdr,
|
|
||||||
selfie=selfie,
|
|
||||||
not_selfie=not_selfie,
|
|
||||||
panorama=panorama,
|
|
||||||
not_panorama=not_panorama,
|
|
||||||
has_raw=has_raw,
|
|
||||||
place=place,
|
|
||||||
no_place=no_place,
|
|
||||||
location=location,
|
|
||||||
no_location=no_location,
|
|
||||||
label=label,
|
|
||||||
deleted=deleted,
|
|
||||||
deleted_only=deleted_only,
|
|
||||||
has_comment=has_comment,
|
|
||||||
no_comment=no_comment,
|
|
||||||
has_likes=has_likes,
|
|
||||||
no_likes=no_likes,
|
|
||||||
is_reference=is_reference,
|
|
||||||
in_album=in_album,
|
|
||||||
not_in_album=not_in_album,
|
|
||||||
name=name,
|
|
||||||
min_size=min_size,
|
|
||||||
max_size=max_size,
|
|
||||||
query_eval=query_eval,
|
|
||||||
function=query_function,
|
function=query_function,
|
||||||
|
has_comment=has_comment,
|
||||||
|
has_likes=has_likes,
|
||||||
|
has_raw=has_raw,
|
||||||
|
hdr=hdr,
|
||||||
|
hidden=hidden,
|
||||||
|
ignore_case=ignore_case,
|
||||||
|
in_album=in_album,
|
||||||
|
incloud=incloud,
|
||||||
|
is_reference=is_reference,
|
||||||
|
keyword=keyword,
|
||||||
|
label=label,
|
||||||
|
live=live,
|
||||||
|
location=location,
|
||||||
|
max_size=max_size,
|
||||||
|
min_size=min_size,
|
||||||
|
missing=missing,
|
||||||
|
movies=movies,
|
||||||
|
name=name,
|
||||||
|
no_comment=no_comment,
|
||||||
|
no_description=no_description,
|
||||||
|
no_likes=no_likes,
|
||||||
|
no_location=no_location,
|
||||||
|
no_place=no_place,
|
||||||
|
no_title=no_title,
|
||||||
|
not_burst=not_burst,
|
||||||
|
not_cloudasset=not_cloudasset,
|
||||||
|
not_favorite=not_favorite,
|
||||||
|
not_hdr=not_hdr,
|
||||||
|
not_hidden=not_hidden,
|
||||||
|
not_in_album=not_in_album,
|
||||||
|
not_incloud=not_incloud,
|
||||||
|
not_live=not_live,
|
||||||
|
not_missing=not_missing,
|
||||||
|
not_panorama=not_panorama,
|
||||||
|
not_portrait=not_portrait,
|
||||||
|
not_screenshot=not_screenshot,
|
||||||
|
not_selfie=not_selfie,
|
||||||
|
not_shared=not_shared,
|
||||||
|
not_slow_mo=not_slow_mo,
|
||||||
|
not_time_lapse=not_time_lapse,
|
||||||
|
panorama=panorama,
|
||||||
|
person=person,
|
||||||
|
photos=photos,
|
||||||
|
place=place,
|
||||||
|
portrait=portrait,
|
||||||
|
query_eval=query_eval,
|
||||||
regex=regex,
|
regex=regex,
|
||||||
|
screenshot=screenshot,
|
||||||
selected=selected,
|
selected=selected,
|
||||||
exif=exif,
|
selfie=selfie,
|
||||||
duplicate=duplicate,
|
shared=shared,
|
||||||
|
slow_mo=slow_mo,
|
||||||
|
time_lapse=time_lapse,
|
||||||
|
title=title,
|
||||||
|
to_date=to_date,
|
||||||
|
to_time=to_time,
|
||||||
|
uti=uti,
|
||||||
|
uuid=uuid,
|
||||||
|
year=year,
|
||||||
)
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -241,55 +241,58 @@ def _query_options_from_kwargs(**kwargs) -> QueryOptions:
|
|||||||
"""Validate query options and create a QueryOptions instance"""
|
"""Validate query options and create a QueryOptions instance"""
|
||||||
# sanity check input args
|
# sanity check input args
|
||||||
nonexclusive = [
|
nonexclusive = [
|
||||||
"keyword",
|
"added_after",
|
||||||
"person",
|
"added_before",
|
||||||
|
"added_in_last",
|
||||||
"album",
|
"album",
|
||||||
"folder",
|
"duplicate",
|
||||||
"name",
|
|
||||||
"uuid",
|
|
||||||
"uuid_from_file",
|
|
||||||
"edited",
|
"edited",
|
||||||
|
"exif",
|
||||||
"external_edit",
|
"external_edit",
|
||||||
"uti",
|
"folder",
|
||||||
"has_raw",
|
|
||||||
"from_date",
|
"from_date",
|
||||||
"to_date",
|
|
||||||
"from_time",
|
"from_time",
|
||||||
"to_time",
|
"has_raw",
|
||||||
"year",
|
|
||||||
"label",
|
|
||||||
"is_reference",
|
"is_reference",
|
||||||
|
"keyword",
|
||||||
|
"label",
|
||||||
|
"max_size",
|
||||||
|
"min_size",
|
||||||
|
"name",
|
||||||
|
"person",
|
||||||
"query_eval",
|
"query_eval",
|
||||||
"query_function",
|
"query_function",
|
||||||
"min_size",
|
|
||||||
"max_size",
|
|
||||||
"regex",
|
"regex",
|
||||||
"selected",
|
"selected",
|
||||||
"exif",
|
"to_date",
|
||||||
"duplicate",
|
"to_time",
|
||||||
|
"uti",
|
||||||
|
"uuid_from_file",
|
||||||
|
"uuid",
|
||||||
|
"year",
|
||||||
]
|
]
|
||||||
exclusive = [
|
exclusive = [
|
||||||
("favorite", "not_favorite"),
|
|
||||||
("hidden", "not_hidden"),
|
|
||||||
("missing", "not_missing"),
|
|
||||||
("only_photos", "only_movies"),
|
|
||||||
("burst", "not_burst"),
|
("burst", "not_burst"),
|
||||||
("live", "not_live"),
|
|
||||||
("cloudasset", "not_cloudasset"),
|
("cloudasset", "not_cloudasset"),
|
||||||
("incloud", "not_incloud"),
|
|
||||||
("portrait", "not_portrait"),
|
|
||||||
("screenshot", "not_screenshot"),
|
|
||||||
("slow_mo", "not_slow_mo"),
|
|
||||||
("time_lapse", "not_time_lapse"),
|
|
||||||
("hdr", "not_hdr"),
|
|
||||||
("selfie", "not_selfie"),
|
|
||||||
("panorama", "not_panorama"),
|
|
||||||
("deleted", "deleted_only"),
|
("deleted", "deleted_only"),
|
||||||
("shared", "not_shared"),
|
("favorite", "not_favorite"),
|
||||||
("has_comment", "no_comment"),
|
("has_comment", "no_comment"),
|
||||||
("has_likes", "no_likes"),
|
("has_likes", "no_likes"),
|
||||||
|
("hdr", "not_hdr"),
|
||||||
|
("hidden", "not_hidden"),
|
||||||
("in_album", "not_in_album"),
|
("in_album", "not_in_album"),
|
||||||
|
("incloud", "not_incloud"),
|
||||||
|
("live", "not_live"),
|
||||||
("location", "no_location"),
|
("location", "no_location"),
|
||||||
|
("missing", "not_missing"),
|
||||||
|
("only_photos", "only_movies"),
|
||||||
|
("panorama", "not_panorama"),
|
||||||
|
("portrait", "not_portrait"),
|
||||||
|
("screenshot", "not_screenshot"),
|
||||||
|
("selfie", "not_selfie"),
|
||||||
|
("shared", "not_shared"),
|
||||||
|
("slow_mo", "not_slow_mo"),
|
||||||
|
("time_lapse", "not_time_lapse"),
|
||||||
]
|
]
|
||||||
# print help if no non-exclusive term or a double exclusive term is given
|
# print help if no non-exclusive term or a double exclusive term is given
|
||||||
# TODO: add option to validate requiring at least one query arg
|
# TODO: add option to validate requiring at least one query arg
|
||||||
|
|||||||
@@ -3446,6 +3446,23 @@ class PhotosDB:
|
|||||||
matching_photos.append(p)
|
matching_photos.append(p)
|
||||||
photos = matching_photos
|
photos = matching_photos
|
||||||
|
|
||||||
|
if options.added_after:
|
||||||
|
added_after = options.added_after
|
||||||
|
if not datetime_has_tz(added_after):
|
||||||
|
added_after = datetime_naive_to_local(added_after)
|
||||||
|
photos = [p for p in photos if p.date_added and p.date_added > added_after]
|
||||||
|
|
||||||
|
if options.added_before:
|
||||||
|
added_before = options.added_before
|
||||||
|
if not datetime_has_tz(added_before):
|
||||||
|
added_before = datetime_naive_to_local(added_before)
|
||||||
|
photos = [p for p in photos if p.date_added and p.date_added < added_before]
|
||||||
|
|
||||||
|
if options.added_in_last:
|
||||||
|
added_after = datetime.now() - options.added_in_last
|
||||||
|
added_after = datetime_naive_to_local(added_after)
|
||||||
|
photos = [p for p in photos if p.date_added and p.date_added > added_after]
|
||||||
|
|
||||||
if options.function:
|
if options.function:
|
||||||
for function in options.function:
|
for function in options.function:
|
||||||
photos = function[0](photos)
|
photos = function[0](photos)
|
||||||
|
|||||||
@@ -15,158 +15,163 @@ class QueryOptions:
|
|||||||
"""QueryOptions class for PhotosDB.query
|
"""QueryOptions class for PhotosDB.query
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
keyword: list of keywords to search for
|
added_after: search for photos added after a given date
|
||||||
person: list of person names to search for
|
added_before: search for photos added before a given date
|
||||||
|
added_in_last: search for photos added in last X datetime.timedelta
|
||||||
album: list of album names to search for
|
album: list of album names to search for
|
||||||
folder: list of folder names to search for
|
burst_photos: search for burst photos
|
||||||
uuid: list of uuids to search for
|
burst: search for burst photos
|
||||||
title: list of titles to search for
|
cloudasset: search for photos that are managed by iCloud
|
||||||
no_title: search for photos with no title
|
deleted_only: search only for deleted photos
|
||||||
|
deleted: also include deleted photos
|
||||||
description: list of descriptions to search for
|
description: list of descriptions to search for
|
||||||
no_description: search for photos with no description
|
duplicate: search for duplicate photos
|
||||||
ignore_case: ignore case when searching
|
|
||||||
edited: search for edited photos
|
edited: search for edited photos
|
||||||
|
exif: search for photos with EXIF tags that matches the given data
|
||||||
external_edit: search for photos edited in external apps
|
external_edit: search for photos edited in external apps
|
||||||
favorite: search for favorite photos
|
favorite: search for favorite photos
|
||||||
not_favorite: search for non-favorite photos
|
folder: list of folder names to search for
|
||||||
hidden: search for hidden photos
|
|
||||||
not_hidden: search for non-hidden photos
|
|
||||||
missing: search for missing photos
|
|
||||||
not_missing: search for non-missing photos
|
|
||||||
shared: search for shared photos
|
|
||||||
not_shared: search for non-shared photos
|
|
||||||
photos: search for photos
|
|
||||||
movies: search for movies
|
|
||||||
uti: list of UTIs to search for
|
|
||||||
burst: search for burst photos
|
|
||||||
not_burst: search for non-burst photos
|
|
||||||
live: search for live photos
|
|
||||||
not_live: search for non-live photos
|
|
||||||
cloudasset: search for photos that are managed by iCloud
|
|
||||||
not_cloudasset: search for photos that are not managed by iCloud
|
|
||||||
incloud: search for cloud assets that are synched to iCloud
|
|
||||||
not_incloud: search for cloud asset photos that are not yet synched to iCloud
|
|
||||||
from_date: search for photos taken on or after this date
|
from_date: search for photos taken on or after this date
|
||||||
to_date: search for photos taken on or before this date
|
|
||||||
portrait: search for portrait photos
|
|
||||||
not_portrait: search for non-portrait photos
|
|
||||||
screenshot: search for screenshot photos
|
|
||||||
not_screenshot: search for non-screenshot photos
|
|
||||||
slow_mo: search for slow-mo photos
|
|
||||||
not_slow_mo: search for non-slow-mo photos
|
|
||||||
time_lapse: search for time-lapse photos
|
|
||||||
not_time_lapse: search for non-time-lapse photos
|
|
||||||
hdr: search for HDR photos
|
|
||||||
not_hdr: search for non-HDR photos
|
|
||||||
selfie: search for selfie photos
|
|
||||||
not_selfie: search for non-selfie photos
|
|
||||||
panorama: search for panorama photos
|
|
||||||
not_panorama: search for non-panorama photos
|
|
||||||
has_raw: search for photos with associated raw files
|
|
||||||
place: list of place names to search for
|
|
||||||
no_place: search for photos with no place
|
|
||||||
label: list of labels to search for
|
|
||||||
deleted: also include deleted photos
|
|
||||||
deleted_only: search only for deleted photos
|
|
||||||
has_comment: search for photos with comments
|
|
||||||
no_comment: search for photos with no comments
|
|
||||||
has_likes: search for shared photos with likes
|
|
||||||
no_likes: search for shared photos with no likes
|
|
||||||
is_reference: search for photos stored by reference (that is, they are not managed by Photos)
|
|
||||||
in_album: search for photos in an album
|
|
||||||
not_in_album: search for photos not in an album
|
|
||||||
burst_photos: search for burst photos
|
|
||||||
missing_bursts: for burst photos, also include burst photos that are missing
|
|
||||||
name: list of names to search for
|
|
||||||
min_size: minimum size of photos to search for
|
|
||||||
max_size: maximum size of photos to search for
|
|
||||||
regex: list of regular expressions to search for
|
|
||||||
query_eval: list of query expressions to evaluate
|
|
||||||
duplicate: search for duplicate photos
|
|
||||||
location: search for photos with a location
|
|
||||||
no_location: search for photos with no location
|
|
||||||
function: list of query functions to evaluate
|
function: list of query functions to evaluate
|
||||||
|
has_comment: search for photos with comments
|
||||||
|
has_likes: search for shared photos with likes
|
||||||
|
has_raw: search for photos with associated raw files
|
||||||
|
hdr: search for HDR photos
|
||||||
|
hidden: search for hidden photos
|
||||||
|
ignore_case: ignore case when searching
|
||||||
|
in_album: search for photos in an album
|
||||||
|
incloud: search for cloud assets that are synched to iCloud
|
||||||
|
is_reference: search for photos stored by reference (that is, they are not managed by Photos)
|
||||||
|
keyword: list of keywords to search for
|
||||||
|
label: list of labels to search for
|
||||||
|
live: search for live photos
|
||||||
|
location: search for photos with a location
|
||||||
|
max_size: maximum size of photos to search for
|
||||||
|
min_size: minimum size of photos to search for
|
||||||
|
missing_bursts: for burst photos, also include burst photos that are missing
|
||||||
|
missing: search for missing photos
|
||||||
|
movies: search for movies
|
||||||
|
name: list of names to search for
|
||||||
|
no_comment: search for photos with no comments
|
||||||
|
no_description: search for photos with no description
|
||||||
|
no_likes: search for shared photos with no likes
|
||||||
|
no_location: search for photos with no location
|
||||||
|
no_place: search for photos with no place
|
||||||
|
no_title: search for photos with no title
|
||||||
|
not_burst: search for non-burst photos
|
||||||
|
not_cloudasset: search for photos that are not managed by iCloud
|
||||||
|
not_favorite: search for non-favorite photos
|
||||||
|
not_hdr: search for non-HDR photos
|
||||||
|
not_hidden: search for non-hidden photos
|
||||||
|
not_in_album: search for photos not in an album
|
||||||
|
not_incloud: search for cloud asset photos that are not yet synched to iCloud
|
||||||
|
not_live: search for non-live photos
|
||||||
|
not_missing: search for non-missing photos
|
||||||
|
not_panorama: search for non-panorama photos
|
||||||
|
not_portrait: search for non-portrait photos
|
||||||
|
not_screenshot: search for non-screenshot photos
|
||||||
|
not_selfie: search for non-selfie photos
|
||||||
|
not_shared: search for non-shared photos
|
||||||
|
not_slow_mo: search for non-slow-mo photos
|
||||||
|
not_time_lapse: search for non-time-lapse photos
|
||||||
|
panorama: search for panorama photos
|
||||||
|
person: list of person names to search for
|
||||||
|
photos: search for photos
|
||||||
|
place: list of place names to search for
|
||||||
|
portrait: search for portrait photos
|
||||||
|
query_eval: list of query expressions to evaluate
|
||||||
|
regex: list of regular expressions to search for
|
||||||
|
screenshot: search for screenshot photos
|
||||||
selected: search for selected photos
|
selected: search for selected photos
|
||||||
exif: search for photos with EXIF tags that matches the given data
|
selfie: search for selfie photos
|
||||||
|
shared: search for shared photos
|
||||||
|
slow_mo: search for slow-mo photos
|
||||||
|
time_lapse: search for time-lapse photos
|
||||||
|
title: list of titles to search for
|
||||||
|
to_date: search for photos taken on or before this date
|
||||||
|
uti: list of UTIs to search for
|
||||||
|
uuid: list of uuids to search for
|
||||||
year: search for photos taken in a given year
|
year: search for photos taken in a given year
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
keyword: Optional[Iterable[str]] = None
|
added_after: Optional[datetime.datetime] = None
|
||||||
person: Optional[Iterable[str]] = None
|
added_before: Optional[datetime.datetime] = None
|
||||||
|
added_in_last: Optional[datetime.timedelta] = None
|
||||||
album: Optional[Iterable[str]] = None
|
album: Optional[Iterable[str]] = None
|
||||||
folder: Optional[Iterable[str]] = None
|
burst_photos: Optional[bool] = None
|
||||||
uuid: Optional[Iterable[str]] = None
|
burst: Optional[bool] = None
|
||||||
title: Optional[Iterable[str]] = None
|
cloudasset: Optional[bool] = None
|
||||||
no_title: Optional[bool] = None
|
deleted_only: Optional[bool] = None
|
||||||
|
deleted: Optional[bool] = None
|
||||||
description: Optional[Iterable[str]] = None
|
description: Optional[Iterable[str]] = None
|
||||||
no_description: Optional[bool] = None
|
duplicate: Optional[bool] = None
|
||||||
ignore_case: Optional[bool] = None
|
|
||||||
edited: Optional[bool] = None
|
edited: Optional[bool] = None
|
||||||
|
exif: Optional[Iterable[Tuple[str, str]]] = None
|
||||||
external_edit: Optional[bool] = None
|
external_edit: Optional[bool] = None
|
||||||
favorite: Optional[bool] = None
|
favorite: Optional[bool] = None
|
||||||
not_favorite: Optional[bool] = None
|
folder: Optional[Iterable[str]] = None
|
||||||
hidden: Optional[bool] = None
|
|
||||||
not_hidden: Optional[bool] = None
|
|
||||||
missing: Optional[bool] = None
|
|
||||||
not_missing: Optional[bool] = None
|
|
||||||
shared: Optional[bool] = None
|
|
||||||
not_shared: Optional[bool] = None
|
|
||||||
photos: Optional[bool] = True
|
|
||||||
movies: Optional[bool] = True
|
|
||||||
uti: Optional[Iterable[str]] = None
|
|
||||||
burst: Optional[bool] = None
|
|
||||||
not_burst: Optional[bool] = None
|
|
||||||
live: Optional[bool] = None
|
|
||||||
not_live: Optional[bool] = None
|
|
||||||
cloudasset: Optional[bool] = None
|
|
||||||
not_cloudasset: Optional[bool] = None
|
|
||||||
incloud: Optional[bool] = None
|
|
||||||
not_incloud: Optional[bool] = None
|
|
||||||
from_date: Optional[datetime.datetime] = None
|
from_date: Optional[datetime.datetime] = None
|
||||||
to_date: Optional[datetime.datetime] = None
|
|
||||||
from_time: Optional[datetime.time] = None
|
from_time: Optional[datetime.time] = None
|
||||||
to_time: Optional[datetime.time] = None
|
|
||||||
portrait: Optional[bool] = None
|
|
||||||
not_portrait: Optional[bool] = None
|
|
||||||
screenshot: Optional[bool] = None
|
|
||||||
not_screenshot: Optional[bool] = None
|
|
||||||
slow_mo: Optional[bool] = None
|
|
||||||
not_slow_mo: Optional[bool] = None
|
|
||||||
time_lapse: Optional[bool] = None
|
|
||||||
not_time_lapse: Optional[bool] = None
|
|
||||||
hdr: Optional[bool] = None
|
|
||||||
not_hdr: Optional[bool] = None
|
|
||||||
selfie: Optional[bool] = None
|
|
||||||
not_selfie: Optional[bool] = None
|
|
||||||
panorama: Optional[bool] = None
|
|
||||||
not_panorama: Optional[bool] = None
|
|
||||||
has_raw: Optional[bool] = None
|
|
||||||
place: Optional[Iterable[str]] = None
|
|
||||||
no_place: Optional[bool] = None
|
|
||||||
label: Optional[Iterable[str]] = None
|
|
||||||
deleted: Optional[bool] = None
|
|
||||||
deleted_only: Optional[bool] = None
|
|
||||||
has_comment: Optional[bool] = None
|
|
||||||
no_comment: Optional[bool] = None
|
|
||||||
has_likes: Optional[bool] = None
|
|
||||||
no_likes: Optional[bool] = None
|
|
||||||
is_reference: Optional[bool] = None
|
|
||||||
in_album: Optional[bool] = None
|
|
||||||
not_in_album: Optional[bool] = None
|
|
||||||
burst_photos: Optional[bool] = None
|
|
||||||
missing_bursts: Optional[bool] = None
|
|
||||||
name: Optional[Iterable[str]] = None
|
|
||||||
min_size: Optional[bitmath.Byte] = None
|
|
||||||
max_size: Optional[bitmath.Byte] = None
|
|
||||||
regex: Optional[Iterable[Tuple[str, str]]] = None
|
|
||||||
query_eval: Optional[Iterable[str]] = None
|
|
||||||
duplicate: Optional[bool] = None
|
|
||||||
location: Optional[bool] = None
|
|
||||||
no_location: Optional[bool] = None
|
|
||||||
function: Optional[List[Tuple[callable, str]]] = None
|
function: Optional[List[Tuple[callable, str]]] = None
|
||||||
|
has_comment: Optional[bool] = None
|
||||||
|
has_likes: Optional[bool] = None
|
||||||
|
has_raw: Optional[bool] = None
|
||||||
|
hdr: Optional[bool] = None
|
||||||
|
hidden: Optional[bool] = None
|
||||||
|
ignore_case: Optional[bool] = None
|
||||||
|
in_album: Optional[bool] = None
|
||||||
|
incloud: Optional[bool] = None
|
||||||
|
is_reference: Optional[bool] = None
|
||||||
|
keyword: Optional[Iterable[str]] = None
|
||||||
|
label: Optional[Iterable[str]] = None
|
||||||
|
live: Optional[bool] = None
|
||||||
|
location: Optional[bool] = None
|
||||||
|
max_size: Optional[bitmath.Byte] = None
|
||||||
|
min_size: Optional[bitmath.Byte] = None
|
||||||
|
missing_bursts: Optional[bool] = None
|
||||||
|
missing: Optional[bool] = None
|
||||||
|
movies: Optional[bool] = True
|
||||||
|
name: Optional[Iterable[str]] = None
|
||||||
|
no_comment: Optional[bool] = None
|
||||||
|
no_description: Optional[bool] = None
|
||||||
|
no_likes: Optional[bool] = None
|
||||||
|
no_location: Optional[bool] = None
|
||||||
|
no_place: Optional[bool] = None
|
||||||
|
no_title: Optional[bool] = None
|
||||||
|
not_burst: Optional[bool] = None
|
||||||
|
not_cloudasset: Optional[bool] = None
|
||||||
|
not_favorite: Optional[bool] = None
|
||||||
|
not_hdr: Optional[bool] = None
|
||||||
|
not_hidden: Optional[bool] = None
|
||||||
|
not_in_album: Optional[bool] = None
|
||||||
|
not_incloud: Optional[bool] = None
|
||||||
|
not_live: Optional[bool] = None
|
||||||
|
not_missing: Optional[bool] = None
|
||||||
|
not_panorama: Optional[bool] = None
|
||||||
|
not_portrait: Optional[bool] = None
|
||||||
|
not_screenshot: Optional[bool] = None
|
||||||
|
not_selfie: Optional[bool] = None
|
||||||
|
not_shared: Optional[bool] = None
|
||||||
|
not_slow_mo: Optional[bool] = None
|
||||||
|
not_time_lapse: Optional[bool] = None
|
||||||
|
panorama: Optional[bool] = None
|
||||||
|
person: Optional[Iterable[str]] = None
|
||||||
|
photos: Optional[bool] = True
|
||||||
|
place: Optional[Iterable[str]] = None
|
||||||
|
portrait: Optional[bool] = None
|
||||||
|
query_eval: Optional[Iterable[str]] = None
|
||||||
|
regex: Optional[Iterable[Tuple[str, str]]] = None
|
||||||
|
screenshot: Optional[bool] = None
|
||||||
selected: Optional[bool] = None
|
selected: Optional[bool] = None
|
||||||
exif: Optional[Iterable[Tuple[str, str]]] = None
|
selfie: Optional[bool] = None
|
||||||
|
shared: Optional[bool] = None
|
||||||
|
slow_mo: Optional[bool] = None
|
||||||
|
time_lapse: Optional[bool] = None
|
||||||
|
title: Optional[Iterable[str]] = None
|
||||||
|
to_date: Optional[datetime.datetime] = None
|
||||||
|
to_time: Optional[datetime.time] = None
|
||||||
|
uti: Optional[Iterable[str]] = None
|
||||||
|
uuid: Optional[Iterable[str]] = None
|
||||||
year: Optional[Iterable[int]] = None
|
year: Optional[Iterable[int]] = None
|
||||||
|
|
||||||
def asdict(self):
|
def asdict(self):
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
""" Test the command line interface (CLI) """
|
""" Test the command line interface (CLI) """
|
||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
import glob
|
import glob
|
||||||
import json
|
import json
|
||||||
@@ -7079,6 +7078,46 @@ def test_query_function():
|
|||||||
assert json_got[0]["original_filename"] == "DSC03584.dng"
|
assert json_got[0]["original_filename"] == "DSC03584.dng"
|
||||||
|
|
||||||
|
|
||||||
|
def test_query_added_after():
|
||||||
|
"""test query --added-after"""
|
||||||
|
|
||||||
|
runner = CliRunner()
|
||||||
|
cwd = os.getcwd()
|
||||||
|
# pylint: disable=not-context-manager
|
||||||
|
results = runner.invoke(
|
||||||
|
query,
|
||||||
|
[
|
||||||
|
os.path.join(cwd, PHOTOS_DB_15_7),
|
||||||
|
"--json",
|
||||||
|
"--added-after",
|
||||||
|
"2022-02-03",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
assert results.exit_code == 0
|
||||||
|
json_got = json.loads(results.output)
|
||||||
|
assert len(json_got) == 4
|
||||||
|
|
||||||
|
|
||||||
|
def test_query_added_before():
|
||||||
|
"""test query --added-before"""
|
||||||
|
|
||||||
|
runner = CliRunner()
|
||||||
|
cwd = os.getcwd()
|
||||||
|
# pylint: disable=not-context-manager
|
||||||
|
results = runner.invoke(
|
||||||
|
query,
|
||||||
|
[
|
||||||
|
os.path.join(cwd, PHOTOS_DB_15_7),
|
||||||
|
"--json",
|
||||||
|
"--added-before",
|
||||||
|
"2019-07-28",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
assert results.exit_code == 0
|
||||||
|
json_got = json.loads(results.output)
|
||||||
|
assert len(json_got) == 7
|
||||||
|
|
||||||
|
|
||||||
def test_export_export_dir_template():
|
def test_export_export_dir_template():
|
||||||
"""Test {export_dir} template"""
|
"""Test {export_dir} template"""
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user