Feature custom sidecar 1123 (#1129)
* Working on custom sidecar, #1123 * Working on custom sidecar, #1123 * Added custom sidecar example * Added WRITE_SKIPPED argument for --sidecar-template * Updated report writer for user sidecars * Added noqa to long lines in report writer * Initial tests for --sidecar-template * Initial tests for --sidecar-template * Initial tests for --sidecar-template * Completed tests for --sidecar-template * Added json example for --sidecar-template * Added json example for --sidecar-template
This commit is contained in:
403
tests/test_cli_export_sidecar_template.py
Normal file
403
tests/test_cli_export_sidecar_template.py
Normal file
@@ -0,0 +1,403 @@
|
||||
"""Test export with --sidecar-template (#1123)"""
|
||||
|
||||
import csv
|
||||
import json
|
||||
import os
|
||||
import pathlib
|
||||
import sqlite3
|
||||
|
||||
import pytest
|
||||
from click.testing import CliRunner
|
||||
|
||||
from osxphotos.cli import export
|
||||
|
||||
PHOTOS_DB = "./tests/Test-10.15.7.photoslibrary"
|
||||
|
||||
PHOTO_UUID = "E9BC5C36-7CD1-40A1-A72B-8B8FAC227D51" # wedding.jpg
|
||||
SIDECAR_FILENAME = "wedding.jpg.txt"
|
||||
SIDECAR_DATA = """
|
||||
|
||||
|
||||
Sidecar: wedding.jpg.txt
|
||||
Photo: wedding.jpg
|
||||
UUID: E9BC5C36-7CD1-40A1-A72B-8B8FAC227D51
|
||||
Rating: ★★★★★
|
||||
"""
|
||||
|
||||
|
||||
def test_export_sidecar_template_1():
|
||||
"""test basic export with --sidecar-template"""
|
||||
runner = CliRunner()
|
||||
cwd = os.getcwd()
|
||||
# pylint: disable=not-context-manager
|
||||
with runner.isolated_filesystem():
|
||||
result = runner.invoke(
|
||||
export,
|
||||
[
|
||||
"--library",
|
||||
os.path.join(cwd, PHOTOS_DB),
|
||||
".",
|
||||
"-V",
|
||||
"--uuid",
|
||||
PHOTO_UUID,
|
||||
"--sidecar-template",
|
||||
os.path.join(cwd, "tests", "custom_sidecar.mako"),
|
||||
"{filepath}.txt",
|
||||
"no",
|
||||
"no",
|
||||
"no",
|
||||
],
|
||||
)
|
||||
assert result.exit_code == 0
|
||||
sidecar_file = pathlib.Path(SIDECAR_FILENAME)
|
||||
assert sidecar_file.exists()
|
||||
sidecar_data = sidecar_file.read_text()
|
||||
assert sidecar_data == SIDECAR_DATA
|
||||
|
||||
|
||||
def test_export_sidecar_template_strip_whitespace():
|
||||
"""test basic export with --sidecar-template and STRIP_WHITESPACE = True"""
|
||||
runner = CliRunner()
|
||||
cwd = os.getcwd()
|
||||
# pylint: disable=not-context-manager
|
||||
with runner.isolated_filesystem():
|
||||
result = runner.invoke(
|
||||
export,
|
||||
[
|
||||
"--library",
|
||||
os.path.join(cwd, PHOTOS_DB),
|
||||
".",
|
||||
"-V",
|
||||
"--uuid",
|
||||
PHOTO_UUID,
|
||||
"--sidecar-template",
|
||||
os.path.join(cwd, "tests", "custom_sidecar.mako"),
|
||||
"{filepath}.txt",
|
||||
"no",
|
||||
"yes",
|
||||
"no",
|
||||
],
|
||||
)
|
||||
assert result.exit_code == 0
|
||||
sidecar_file = pathlib.Path(SIDECAR_FILENAME)
|
||||
assert sidecar_file.exists()
|
||||
sidecar_data = sidecar_file.read_text()
|
||||
sidecar_expected = (
|
||||
"\n".join(line.strip() for line in SIDECAR_DATA.splitlines()) + "\n"
|
||||
)
|
||||
assert sidecar_data == sidecar_expected
|
||||
|
||||
|
||||
def test_export_sidecar_template_strip_lines():
|
||||
"""test basic export with --sidecar-template and STRIP_LINES = True"""
|
||||
runner = CliRunner()
|
||||
cwd = os.getcwd()
|
||||
# pylint: disable=not-context-manager
|
||||
with runner.isolated_filesystem():
|
||||
result = runner.invoke(
|
||||
export,
|
||||
[
|
||||
"--library",
|
||||
os.path.join(cwd, PHOTOS_DB),
|
||||
".",
|
||||
"-V",
|
||||
"--uuid",
|
||||
PHOTO_UUID,
|
||||
"--sidecar-template",
|
||||
os.path.join(cwd, "tests", "custom_sidecar.mako"),
|
||||
"{filepath}.txt",
|
||||
"no",
|
||||
"no",
|
||||
"yes",
|
||||
],
|
||||
)
|
||||
assert result.exit_code == 0
|
||||
sidecar_file = pathlib.Path(SIDECAR_FILENAME)
|
||||
assert sidecar_file.exists()
|
||||
sidecar_data = sidecar_file.read_text()
|
||||
sidecar_expected = "\n".join(
|
||||
line for line in SIDECAR_DATA.splitlines() if line.strip()
|
||||
)
|
||||
assert sidecar_data == sidecar_expected
|
||||
|
||||
|
||||
def test_export_sidecar_template_strip_lines_strip_whitespace():
|
||||
"""test basic export with --sidecar-template and STRIP_LINES = True and STRIP_WHITESPACE = True"""
|
||||
runner = CliRunner()
|
||||
cwd = os.getcwd()
|
||||
# pylint: disable=not-context-manager
|
||||
with runner.isolated_filesystem():
|
||||
result = runner.invoke(
|
||||
export,
|
||||
[
|
||||
"--library",
|
||||
os.path.join(cwd, PHOTOS_DB),
|
||||
".",
|
||||
"-V",
|
||||
"--uuid",
|
||||
PHOTO_UUID,
|
||||
"--sidecar-template",
|
||||
os.path.join(cwd, "tests", "custom_sidecar.mako"),
|
||||
"{filepath}.txt",
|
||||
"no",
|
||||
"yes",
|
||||
"yes",
|
||||
],
|
||||
)
|
||||
assert result.exit_code == 0
|
||||
sidecar_file = pathlib.Path(SIDECAR_FILENAME)
|
||||
assert sidecar_file.exists()
|
||||
sidecar_data = sidecar_file.read_text()
|
||||
sidecar_expected = "\n".join(
|
||||
line.strip() for line in SIDECAR_DATA.splitlines() if line.strip()
|
||||
)
|
||||
assert sidecar_data == sidecar_expected
|
||||
|
||||
|
||||
def test_export_sidecar_template_update_no():
|
||||
"""test basic export with --sidecar-template and WRITE_SKIPPED = False, also test --cleanup"""
|
||||
runner = CliRunner()
|
||||
cwd = os.getcwd()
|
||||
# pylint: disable=not-context-manager
|
||||
with runner.isolated_filesystem():
|
||||
result = runner.invoke(
|
||||
export,
|
||||
[
|
||||
"--library",
|
||||
os.path.join(cwd, PHOTOS_DB),
|
||||
".",
|
||||
"-V",
|
||||
"--uuid",
|
||||
PHOTO_UUID,
|
||||
"--sidecar-template",
|
||||
os.path.join(cwd, "tests", "custom_sidecar.mako"),
|
||||
"{filepath}.txt",
|
||||
"no",
|
||||
"no",
|
||||
"no",
|
||||
],
|
||||
)
|
||||
|
||||
# run export again, should not update sidecar
|
||||
result = runner.invoke(
|
||||
export,
|
||||
[
|
||||
"--library",
|
||||
os.path.join(cwd, PHOTOS_DB),
|
||||
".",
|
||||
"-V",
|
||||
"--uuid",
|
||||
PHOTO_UUID,
|
||||
"--sidecar-template",
|
||||
os.path.join(cwd, "tests", "custom_sidecar.mako"),
|
||||
"{filepath}.txt",
|
||||
"no",
|
||||
"no",
|
||||
"no",
|
||||
"--update",
|
||||
"--cleanup",
|
||||
],
|
||||
)
|
||||
assert result.exit_code == 0
|
||||
sidecar_file = pathlib.Path(SIDECAR_FILENAME)
|
||||
assert sidecar_file.exists()
|
||||
sidecar_data = sidecar_file.read_text()
|
||||
sidecar_expected = "\n".join(
|
||||
line.strip() for line in SIDECAR_DATA.splitlines() if line.strip()
|
||||
)
|
||||
assert sidecar_data == SIDECAR_DATA
|
||||
assert "Skipping existing sidecar file" in result.output
|
||||
assert "Deleted: 0 files, 0 directories" in result.output
|
||||
|
||||
|
||||
def test_export_sidecar_template_update_ues():
|
||||
"""test basic export with --sidecar-template and WRITE_SKIPPED = True, also test --cleanup"""
|
||||
runner = CliRunner()
|
||||
cwd = os.getcwd()
|
||||
# pylint: disable=not-context-manager
|
||||
with runner.isolated_filesystem():
|
||||
result = runner.invoke(
|
||||
export,
|
||||
[
|
||||
"--library",
|
||||
os.path.join(cwd, PHOTOS_DB),
|
||||
".",
|
||||
"-V",
|
||||
"--uuid",
|
||||
PHOTO_UUID,
|
||||
"--sidecar-template",
|
||||
os.path.join(cwd, "tests", "custom_sidecar.mako"),
|
||||
"{filepath}.txt",
|
||||
"no",
|
||||
"no",
|
||||
"no",
|
||||
],
|
||||
)
|
||||
|
||||
# run export again, should not update sidecar
|
||||
result = runner.invoke(
|
||||
export,
|
||||
[
|
||||
"--library",
|
||||
os.path.join(cwd, PHOTOS_DB),
|
||||
".",
|
||||
"-V",
|
||||
"--uuid",
|
||||
PHOTO_UUID,
|
||||
"--sidecar-template",
|
||||
os.path.join(cwd, "tests", "custom_sidecar.mako"),
|
||||
"{filepath}.txt",
|
||||
"yes",
|
||||
"no",
|
||||
"no",
|
||||
"--update",
|
||||
"--cleanup",
|
||||
],
|
||||
)
|
||||
assert result.exit_code == 0
|
||||
sidecar_file = pathlib.Path(SIDECAR_FILENAME)
|
||||
assert sidecar_file.exists()
|
||||
sidecar_data = sidecar_file.read_text()
|
||||
sidecar_expected = "\n".join(
|
||||
line.strip() for line in SIDECAR_DATA.splitlines() if line.strip()
|
||||
)
|
||||
assert sidecar_data == SIDECAR_DATA
|
||||
assert "Skipping existing sidecar file" not in result.output
|
||||
assert "Writing sidecar file" in result.output
|
||||
assert "Deleted: 0 files, 0 directories" in result.output
|
||||
|
||||
|
||||
def test_export_sidecar_template_report_csv():
|
||||
"""test basic export with --sidecar-template --report to csv"""
|
||||
runner = CliRunner()
|
||||
cwd = os.getcwd()
|
||||
# pylint: disable=not-context-manager
|
||||
with runner.isolated_filesystem():
|
||||
result = runner.invoke(
|
||||
export,
|
||||
[
|
||||
"--library",
|
||||
os.path.join(cwd, PHOTOS_DB),
|
||||
".",
|
||||
"-V",
|
||||
"--uuid",
|
||||
PHOTO_UUID,
|
||||
"--sidecar-template",
|
||||
os.path.join(cwd, "tests", "custom_sidecar.mako"),
|
||||
"{filepath}.txt",
|
||||
"no",
|
||||
"no",
|
||||
"no",
|
||||
"--report",
|
||||
"report.csv",
|
||||
],
|
||||
)
|
||||
assert result.exit_code == 0
|
||||
|
||||
# verify report output
|
||||
report_file = pathlib.Path("report.csv")
|
||||
assert report_file.exists()
|
||||
csvreader = csv.DictReader(report_file.open())
|
||||
assert "sidecar_user" in csvreader.fieldnames
|
||||
|
||||
found_sidecar = 0
|
||||
for row in csvreader: # sourcery skip: no-loop-in-tests
|
||||
# sidecar ends with .txt so verify report has sidecar_user = 1
|
||||
if row["filename"].endswith(
|
||||
".txt"
|
||||
): # sourcery skip: no-conditionals-in-tests
|
||||
assert str(row["sidecar_user"]) == "1"
|
||||
found_sidecar += 1
|
||||
else:
|
||||
assert str(row["sidecar_user"]) == "0"
|
||||
assert found_sidecar
|
||||
|
||||
|
||||
def test_export_sidecar_template_report_json():
|
||||
"""test basic export with --sidecar-template --report to json"""
|
||||
runner = CliRunner()
|
||||
cwd = os.getcwd()
|
||||
# pylint: disable=not-context-manager
|
||||
with runner.isolated_filesystem():
|
||||
result = runner.invoke(
|
||||
export,
|
||||
[
|
||||
"--library",
|
||||
os.path.join(cwd, PHOTOS_DB),
|
||||
".",
|
||||
"-V",
|
||||
"--uuid",
|
||||
PHOTO_UUID,
|
||||
"--sidecar-template",
|
||||
os.path.join(cwd, "tests", "custom_sidecar.mako"),
|
||||
"{filepath}.txt",
|
||||
"no",
|
||||
"no",
|
||||
"no",
|
||||
"--report",
|
||||
"report.json",
|
||||
],
|
||||
)
|
||||
assert result.exit_code == 0
|
||||
|
||||
# read the json report output and verify it is correct
|
||||
report_file = pathlib.Path("report.json")
|
||||
assert report_file.exists()
|
||||
report_data = json.loads(report_file.read_text())
|
||||
assert "sidecar_user" in report_data[0]
|
||||
found_sidecar = 0
|
||||
for row in report_data: # sourcery skip: no-loop-in-tests
|
||||
# sidecar ends with .txt so verify report has sidecar_user = 1
|
||||
if row["filename"].endswith(
|
||||
".txt"
|
||||
): # sourcery skip: no-conditionals-in-tests
|
||||
assert row["sidecar_user"]
|
||||
found_sidecar += 1
|
||||
else:
|
||||
assert not row["sidecar_user"]
|
||||
assert found_sidecar
|
||||
|
||||
|
||||
def test_export_sidecar_template_report_db():
|
||||
"""test basic export with --sidecar-template --report to sqlite db"""
|
||||
runner = CliRunner()
|
||||
cwd = os.getcwd()
|
||||
# pylint: disable=not-context-manager
|
||||
with runner.isolated_filesystem():
|
||||
result = runner.invoke(
|
||||
export,
|
||||
[
|
||||
"--library",
|
||||
os.path.join(cwd, PHOTOS_DB),
|
||||
".",
|
||||
"-V",
|
||||
"--uuid",
|
||||
PHOTO_UUID,
|
||||
"--sidecar-template",
|
||||
os.path.join(cwd, "tests", "custom_sidecar.mako"),
|
||||
"{filepath}.txt",
|
||||
"no",
|
||||
"no",
|
||||
"no",
|
||||
"--report",
|
||||
"report.db",
|
||||
],
|
||||
)
|
||||
assert result.exit_code == 0
|
||||
|
||||
# read the report sqlite db and verify it is correct
|
||||
report_file = pathlib.Path("report.db")
|
||||
assert report_file.exists()
|
||||
conn = sqlite3.connect(report_file)
|
||||
c = conn.cursor()
|
||||
c.execute("SELECT filename, sidecar_user FROM report")
|
||||
rows = c.fetchall()
|
||||
found_sidecar = 0
|
||||
for row in rows: # sourcery skip: no-loop-in-tests
|
||||
# sidecar ends with .txt so verify report has sidecar_user = 1
|
||||
if row[0].endswith(".txt"): # sourcery skip: no-conditionals-in-tests
|
||||
assert row[1] == 1
|
||||
found_sidecar += 1
|
||||
else:
|
||||
assert row[1] == 0
|
||||
assert found_sidecar
|
||||
Reference in New Issue
Block a user