Added --location, --no-location, #474

This commit is contained in:
Rhet Turnbull
2021-06-20 15:33:03 -07:00
parent 500cf71f7e
commit 870a59a2fa
6 changed files with 85 additions and 3 deletions

View File

@@ -616,6 +616,10 @@ Options:
geolocation info geolocation info
--no-place Search for photos with no associated place --no-place Search for photos with no associated place
name info (no reverse geolocation info) name info (no reverse geolocation info)
--location Search for photos with associated location
info (e.g. GPS coordinates)
--no-location Search for photos with no associated location
info (e.g. no GPS coordinates)
--label LABEL Search for photos with image classification --label LABEL Search for photos with image classification
label LABEL (Photos 5 only). If more than one label LABEL (Photos 5 only). If more than one
label, treated as "OR", e.g. find photos label, treated as "OR", e.g. find photos
@@ -1583,7 +1587,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.42.43' {osxphotos_version} The osxphotos version, e.g. '0.42.44'
{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
@@ -3382,7 +3386,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.42.43'| |{osxphotos_version}|The osxphotos version, e.g. '0.42.44'|
|{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|

View File

@@ -1,3 +1,3 @@
""" version info """ """ version info """
__version__ = "0.42.43" __version__ = "0.42.44"

View File

@@ -332,6 +332,16 @@ def QUERY_OPTIONS(f):
is_flag=True, is_flag=True,
help="Search for photos with no associated place name info (no reverse geolocation info)", help="Search for photos with no associated place name info (no reverse geolocation info)",
), ),
o(
"--location",
is_flag=True,
help="Search for photos with associated location info (e.g. GPS coordinates)",
),
o(
"--no-location",
is_flag=True,
help="Search for photos with no associated location info (e.g. no GPS coordinates)",
),
o( o(
"--label", "--label",
metavar="LABEL", metavar="LABEL",
@@ -1104,6 +1114,8 @@ def export(
original_suffix, original_suffix,
place, place,
no_place, no_place,
location,
no_location,
has_comment, has_comment,
no_comment, no_comment,
has_likes, has_likes,
@@ -1263,6 +1275,8 @@ def export(
original_suffix = cfg.original_suffix original_suffix = cfg.original_suffix
place = cfg.place place = cfg.place
no_place = cfg.no_place no_place = cfg.no_place
location = cfg.location
no_location = cfg.no_location
has_comment = cfg.has_comment has_comment = cfg.has_comment
no_comment = cfg.no_comment no_comment = cfg.no_comment
has_likes = cfg.has_likes has_likes = cfg.has_likes
@@ -1323,6 +1337,7 @@ def export(
("has_comment", "no_comment"), ("has_comment", "no_comment"),
("has_likes", "no_likes"), ("has_likes", "no_likes"),
("in_album", "not_in_album"), ("in_album", "not_in_album"),
("location", "no_location"),
] ]
dependent_options = [ dependent_options = [
("missing", ("download_missing", "use_photos_export")), ("missing", ("download_missing", "use_photos_export")),
@@ -1576,6 +1591,8 @@ def export(
has_raw=has_raw, has_raw=has_raw,
place=place, place=place,
no_place=no_place, no_place=no_place,
location=location,
no_location=no_location,
label=label, label=label,
deleted=deleted, deleted=deleted,
deleted_only=deleted_only, deleted_only=deleted_only,
@@ -1979,6 +1996,8 @@ def query(
has_raw, has_raw,
place, place,
no_place, no_place,
location,
no_location,
label, label,
deleted, deleted,
deleted_only, deleted_only,
@@ -2051,6 +2070,7 @@ def query(
(has_comment, no_comment), (has_comment, no_comment),
(has_likes, no_likes), (has_likes, no_likes),
(in_album, not_in_album), (in_album, not_in_album),
(location, no_location),
] ]
# 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(
@@ -2136,6 +2156,8 @@ def query(
has_raw=has_raw, has_raw=has_raw,
place=place, place=place,
no_place=no_place, no_place=no_place,
location=location,
no_location=no_location,
label=label, label=label,
deleted=deleted, deleted=deleted,
deleted_only=deleted_only, deleted_only=deleted_only,

View File

@@ -3254,6 +3254,11 @@ class PhotosDB:
if options.deleted_only: if options.deleted_only:
photos = [p for p in photos if p.intrash] photos = [p for p in photos if p.intrash]
if options.location:
photos = [p for p in photos if p.location != (None, None)]
elif options.no_location:
photos = [p for p in photos if p.location == (None, None)]
return photos return photos
def _duplicate_signature(self, uuid): def _duplicate_signature(self, uuid):

View File

@@ -79,6 +79,8 @@ class QueryOptions:
regex: Optional[Iterable[Tuple[str, str]]] = None regex: Optional[Iterable[Tuple[str, str]]] = None
query_eval: Optional[Iterable[str]] = None query_eval: Optional[Iterable[str]] = None
duplicate: Optional[bool] = None duplicate: Optional[bool] = None
location: Optional[bool] = None
no_location: Optional[bool] = None
def asdict(self): def asdict(self):
return asdict(self) return asdict(self)

View File

@@ -771,6 +771,9 @@ UUID_DUPLICATES = [
"52083079-73D5-4921-AC1B-FE76F279133F", "52083079-73D5-4921-AC1B-FE76F279133F",
] ]
UUID_LOCATION = "D79B8D77-BFFC-460B-9312-034F2877D35B" # Pumkins2.jpg
UUID_NO_LOCATION = "6191423D-8DB8-4D4C-92BE-9BBBA308AAC4" # Tulips.jpg"
def modify_file(filename): def modify_file(filename):
"""appends data to a file to modify it""" """appends data to a file to modify it"""
@@ -1147,6 +1150,52 @@ def test_query_duplicate():
assert sorted(uuid_got) == sorted(UUID_DUPLICATES) assert sorted(uuid_got) == sorted(UUID_DUPLICATES)
def test_query_location():
"""Test query with --location"""
import json
import os
import os.path
from osxphotos.cli import query
runner = CliRunner()
cwd = os.getcwd()
result = runner.invoke(
query,
["--json", "--db", os.path.join(cwd, CLI_PHOTOS_DB), "--location"],
)
assert result.exit_code == 0
# build list of uuids we got from the output JSON
json_got = json.loads(result.output)
uuid_got = [photo["uuid"] for photo in json_got]
assert UUID_LOCATION in uuid_got
assert UUID_NO_LOCATION not in uuid_got
def test_query_no_location():
"""Test query with --no-location"""
import json
import os
import os.path
from osxphotos.cli import query
runner = CliRunner()
cwd = os.getcwd()
result = runner.invoke(
query,
["--json", "--db", os.path.join(cwd, CLI_PHOTOS_DB), "--no-location"],
)
assert result.exit_code == 0
# build list of uuids we got from the output JSON
json_got = json.loads(result.output)
uuid_got = [photo["uuid"] for photo in json_got]
assert UUID_NO_LOCATION in uuid_got
assert UUID_LOCATION not in uuid_got
def test_export(): def test_export():
import glob import glob
import os import os