Added repl command to CLI; closes #472
This commit is contained in:
@@ -110,6 +110,7 @@ Alternatively, you can also run the command line utility like this: ``python3 -m
|
|||||||
persons Print out persons (faces) found in the Photos library.
|
persons Print out persons (faces) found in the Photos library.
|
||||||
places Print out places found in the Photos library.
|
places Print out places found in the Photos library.
|
||||||
query Query the Photos database using 1 or more search options; if...
|
query Query the Photos database using 1 or more search options; if...
|
||||||
|
repl Run interactive osxphotos shell
|
||||||
tutorial Display osxphotos tutorial.
|
tutorial Display osxphotos tutorial.
|
||||||
|
|
||||||
To get help on a specific command, use ``osxphotos help <command_name>``
|
To get help on a specific command, use ``osxphotos help <command_name>``
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
""" version info """
|
""" version info """
|
||||||
|
|
||||||
__version__ = "0.42.40"
|
__version__ = "0.42.41"
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
"""Command line interface for osxphotos """
|
"""Command line interface for osxphotos """
|
||||||
|
|
||||||
|
import code
|
||||||
import csv
|
import csv
|
||||||
import datetime
|
import datetime
|
||||||
import json
|
import json
|
||||||
@@ -16,6 +17,7 @@ import bitmath
|
|||||||
import click
|
import click
|
||||||
import osxmetadata
|
import osxmetadata
|
||||||
import yaml
|
import yaml
|
||||||
|
from rich import pretty
|
||||||
|
|
||||||
import osxphotos
|
import osxphotos
|
||||||
|
|
||||||
@@ -3773,3 +3775,73 @@ def tutorial(ctx, cli_obj, width):
|
|||||||
"""Display osxphotos tutorial."""
|
"""Display osxphotos tutorial."""
|
||||||
width = width[0] if width else 100
|
width = width[0] if width else 100
|
||||||
click.echo_via_pager(tutorial_help(width=width))
|
click.echo_via_pager(tutorial_help(width=width))
|
||||||
|
|
||||||
|
|
||||||
|
def _show_photo(photo):
|
||||||
|
"""open image with default image viewer
|
||||||
|
|
||||||
|
Note: This is for debugging only -- it will actually open any filetype which could
|
||||||
|
be very, very bad.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
photo: PhotoInfo object or a path to a photo on disk
|
||||||
|
"""
|
||||||
|
photopath = photo.path if isinstance(photo, osxphotos.PhotoInfo) else photo
|
||||||
|
|
||||||
|
if not os.path.isfile(photopath):
|
||||||
|
return f"'{photopath}' does not appear to be a valid photo path"
|
||||||
|
|
||||||
|
os.system(f"open '{photopath}'")
|
||||||
|
|
||||||
|
|
||||||
|
def _load_photos_db(dbpath):
|
||||||
|
print("Loading database")
|
||||||
|
tic = time.perf_counter()
|
||||||
|
photosdb = osxphotos.PhotosDB(dbfile=dbpath, verbose=print)
|
||||||
|
toc = time.perf_counter()
|
||||||
|
tictoc = toc - tic
|
||||||
|
print(f"Done: took {tictoc:0.2f} seconds")
|
||||||
|
return photosdb
|
||||||
|
|
||||||
|
|
||||||
|
def _get_photos(photosdb):
|
||||||
|
photos = photosdb.photos(images=True, movies=True)
|
||||||
|
photos.extend(photosdb.photos(images=True, movies=True, intrash=True))
|
||||||
|
return photos
|
||||||
|
|
||||||
|
|
||||||
|
@cli.command()
|
||||||
|
@DB_OPTION
|
||||||
|
@click.pass_obj
|
||||||
|
@click.pass_context
|
||||||
|
def repl(ctx, cli_obj, db):
|
||||||
|
"""Run interactive osxphotos shell"""
|
||||||
|
pretty.install()
|
||||||
|
print(f"python version: {sys.version}")
|
||||||
|
print(f"osxphotos version: {osxphotos._version.__version__}")
|
||||||
|
db = db or get_photos_db()
|
||||||
|
photosdb = _load_photos_db(db)
|
||||||
|
print("Getting photos")
|
||||||
|
tic = time.perf_counter()
|
||||||
|
photos = _get_photos(photosdb)
|
||||||
|
toc = time.perf_counter()
|
||||||
|
tictoc = toc - tic
|
||||||
|
|
||||||
|
# shortcut for helper functions
|
||||||
|
get_photo = photosdb.get_photo
|
||||||
|
show = _show_photo
|
||||||
|
|
||||||
|
print(f"Found {len(photos)} photos in {tictoc:0.2f} seconds")
|
||||||
|
print("The following variables are defined:")
|
||||||
|
print(f"- photosdb: PhotosDB() instance for {photosdb.library_path}")
|
||||||
|
print(
|
||||||
|
f"- photos: list of PhotoInfo objects for all photos in photosdb, including those in the trash"
|
||||||
|
)
|
||||||
|
print(f"\nThe following functions may be helpful:")
|
||||||
|
print(f"- get_photo(uuid): return a PhotoInfo object for photo with uuid")
|
||||||
|
print(f"- show(photo): open a photo object in the default viewer")
|
||||||
|
print(
|
||||||
|
f"- help(object): print help text including list of methods for object; for example, help(PhotosDB)"
|
||||||
|
)
|
||||||
|
print(f"- quit(): exit this interactive shell\n")
|
||||||
|
code.interact(banner="", local=locals())
|
||||||
|
|||||||
@@ -6457,6 +6457,8 @@ def test_export_directory_template_function():
|
|||||||
with runner.isolated_filesystem():
|
with runner.isolated_filesystem():
|
||||||
with open("foo.py", "w") as f:
|
with open("foo.py", "w") as f:
|
||||||
f.writelines(["def foo(photo, **kwargs):\n"," return 'foo/bar'"])
|
f.writelines(["def foo(photo, **kwargs):\n"," return 'foo/bar'"])
|
||||||
|
|
||||||
|
tempdir = os.getcwd()
|
||||||
result = runner.invoke(
|
result = runner.invoke(
|
||||||
cli,
|
cli,
|
||||||
[
|
[
|
||||||
@@ -6464,10 +6466,11 @@ def test_export_directory_template_function():
|
|||||||
"--db",
|
"--db",
|
||||||
os.path.join(cwd, PHOTOS_DB_15_7),
|
os.path.join(cwd, PHOTOS_DB_15_7),
|
||||||
".",
|
".",
|
||||||
|
"-V",
|
||||||
"--uuid",
|
"--uuid",
|
||||||
CLI_EXPORT_UUID,
|
CLI_EXPORT_UUID,
|
||||||
"--directory",
|
"--directory",
|
||||||
"{function:foo.py::foo}"
|
"{function:"+f"{tempdir}" + "/foo.py::foo}"
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
assert result.exit_code == 0
|
assert result.exit_code == 0
|
||||||
|
|||||||
Reference in New Issue
Block a user