This commit is contained in:
Rhet Turnbull 2023-05-07 07:33:07 -07:00 committed by GitHub
parent ee8053d867
commit f0aa69d8bb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 55 additions and 38 deletions

View File

@ -119,7 +119,9 @@ def rich_echo(
# if not outputting to terminal, use a huge width to avoid wrapping
# otherwise tests fail
width = 10_000
console = get_rich_console() or Console(theme=theme or get_rich_theme(), width=width)
console = get_rich_console() or Console(
theme=theme or get_rich_theme(), width=width
)
if markdown:
message = Markdown(message)
# Markdown always adds a new line so disable unless explicitly specified

View File

@ -7,28 +7,25 @@ if is_macos:
import objc
import Foundation
def theme():
with objc.autorelease_pool():
user_defaults = Foundation.NSUserDefaults.standardUserDefaults()
system_theme = user_defaults.stringForKey_("AppleInterfaceStyle")
return "dark" if system_theme == "Dark" else "light"
def is_dark_mode():
return theme() == "dark"
def is_light_mode():
return theme() == "light"
else:
def theme():
return "light"
def is_dark_mode():
return theme() == "dark"
def is_light_mode():
return theme() == "light"

View File

@ -255,7 +255,9 @@ class ExportCommand(click.Command):
if is_macos:
formatter.write(
rich_text("## Extended Attributes", width=formatter.width, markdown=True)
rich_text(
"## Extended Attributes", width=formatter.width, markdown=True
)
)
formatter.write("\n")
formatter.write_text(

View File

@ -68,7 +68,6 @@ class PathOrStdin(click.Path):
class DateTimeISO8601(click.ParamType):
name = "DATETIME"
def convert(self, value, param, ctx):
@ -82,7 +81,6 @@ class DateTimeISO8601(click.ParamType):
class BitMathSize(click.ParamType):
name = "BITMATH"
def convert(self, value, param, ctx):
@ -102,7 +100,6 @@ class BitMathSize(click.ParamType):
class TimeISO8601(click.ParamType):
name = "TIME"
def convert(self, value, param, ctx):
@ -141,7 +138,6 @@ class FunctionCall(click.ParamType):
class ExportDBType(click.ParamType):
name = "EXPORTDB"
def convert(self, value, param, ctx):
@ -279,7 +275,6 @@ class StrpDateTimePattern(click.ParamType):
class Latitude(click.ParamType):
name = "Latitude"
def convert(self, value, param, ctx):
@ -295,7 +290,6 @@ class Latitude(click.ParamType):
class Longitude(click.ParamType):
name = "Longitude"
def convert(self, value, param, ctx):

View File

@ -32,7 +32,8 @@ from .list import _list_libraries
from .print_photo_info import print_photo_fields, print_photo_info
from .verbose import get_verbose_console
MACOS_OPTIONS = make_click_option_decorator(*[
MACOS_OPTIONS = make_click_option_decorator(
*[
click.Option(
["--add-to-album"],
metavar="ALBUM",
@ -41,7 +42,11 @@ MACOS_OPTIONS = make_click_option_decorator(*[
"This only works if the Photos library being queried is the last-opened (default) library in Photos. "
"This feature is currently experimental. I don't know how well it will work on large query sets.",
),
] if is_macos else [])
]
if is_macos
else []
)
@click.command()
@DB_OPTION

View File

@ -58,6 +58,7 @@ def repl(ctx, cli_obj, db, emacs, beta, **kwargs):
import logging
from objexplore import explore
if is_macos:
from photoscript import Album, Photo, PhotosLibrary
from rich import inspect as _inspect

View File

@ -182,7 +182,9 @@ class ExportReportWriterSQLite(ReportWriterABC):
with suppress(FileNotFoundError):
os.unlink(self.output_file)
self._conn = sqlite3.connect(self.output_file, check_same_thread=SQLITE_CHECK_SAME_THREAD)
self._conn = sqlite3.connect(
self.output_file, check_same_thread=SQLITE_CHECK_SAME_THREAD
)
self._create_tables()
self.report_id = self._generate_report_id()
@ -534,7 +536,9 @@ class SyncReportWriterSQLite(ReportWriterABC):
with suppress(FileNotFoundError):
os.unlink(self.output_file)
self._conn = sqlite3.connect(self.output_file, check_same_thread=SQLITE_CHECK_SAME_THREAD)
self._conn = sqlite3.connect(
self.output_file, check_same_thread=SQLITE_CHECK_SAME_THREAD
)
self._create_tables()
self.report_id = self._generate_report_id()

View File

@ -170,6 +170,7 @@ def get_photo_metadata(photos: list[PhotoInfo]) -> str:
photos_dict[k] = v
elif photos_dict[k] and v != photos_dict[k]:
photos_dict[k] = f"{photos_dict[k]} {v}"
# convert photos_dict to JSON string
# wouldn't it be nice if json encoder handled datetimes...
def default(o):

View File

@ -21,6 +21,7 @@ __all__ = [
"utc_offset_seconds",
]
# TODO: look at https://github.com/regebro/tzlocal for more robust implementation
def get_local_tz(dt: datetime.datetime) -> datetime.tzinfo:
"""Return local timezone as datetime.timezone tzinfo for dt
@ -207,4 +208,3 @@ def utc_offset_seconds(dt: datetime.datetime) -> int:
return dt.tzinfo.utcoffset(dt).total_seconds()
else:
raise ValueError("dt does not have timezone info")

View File

@ -23,7 +23,7 @@ import sys
import threading
import time
assert(sys.platform == "darwin")
assert sys.platform == "darwin"
import AVFoundation
import CoreServices
@ -87,6 +87,7 @@ PHOTOKIT_NOTIFICATION_FINISHED_REQUEST = "PyPhotoKitNotificationFinishedRequest"
# minimum amount to sleep while waiting for export
MIN_SLEEP = 0.015
### utility functions
def NSURL_to_path(url):
"""Convert URL string as represented by NSURL to a path string"""
@ -629,7 +630,8 @@ class PhotoAsset:
def handler(imageData, dataUTI, orientation, info):
"""result handler for requestImageDataAndOrientationForAsset_options_resultHandler_
all returned by the request is set as properties of nonlocal data (Fetchdata object)"""
all returned by the request is set as properties of nonlocal data (Fetchdata object)
"""
nonlocal requestdata
@ -676,7 +678,8 @@ class PhotoAsset:
def handler(data):
"""result handler for requestImageDataAndOrientationForAsset_options_resultHandler_
all returned by the request is set as properties of nonlocal data (Fetchdata object)"""
all returned by the request is set as properties of nonlocal data (Fetchdata object)
"""
nonlocal requestdata
@ -713,7 +716,8 @@ class PhotoAsset:
def handler(imageData, dataUTI, orientation, info):
"""result handler for requestImageDataAndOrientationForAsset_options_resultHandler_
all returned by the request is set as properties of nonlocal data (Fetchdata object)"""
all returned by the request is set as properties of nonlocal data (Fetchdata object)
"""
nonlocal data

View File

@ -309,7 +309,9 @@ def _process_faceinfo_5(photosdb):
face["righteyey"] = row[34]
face["roll"] = row[35]
face["size"] = row[36]
face["yaw"] = 0 # Photos 4 only (this is in Photos 5-7, but dropped in Ventura so just don't support it)
face[
"yaw"
] = 0 # Photos 4 only (this is in Photos 5-7, but dropped in Ventura so just don't support it)
face["pitch"] = 0 # not defined in Photos 5
photosdb._db_faceinfo_pk[pk] = face

View File

@ -71,6 +71,7 @@ PlaceNames = namedtuple(
],
)
# The following classes represent Photo Library Reverse Geolocation Info as stored
# in ZADDITIONALASSETATTRIBUTES.ZREVERSELOCATIONDATA
# These classes are used by bpylist.archiver to unarchive the serialized objects

View File

@ -29,7 +29,7 @@ def sqlgrep(
flags = re.IGNORECASE if ignore_case else 0
try:
with sqlite3.connect(f"file:{filename}?mode=ro", uri=True) as conn:
regex = re.compile(f'({pattern})', flags=flags)
regex = re.compile(f"({pattern})", flags=flags)
filename_header = f"{filename}: " if print_filename else ""
conn.row_factory = sqlite3.Row
cursor = conn.cursor()

View File

@ -17,12 +17,10 @@ if is_macos:
import Foundation
import objc
def known_timezone_names():
"""Get list of valid timezones on macOS"""
return Foundation.NSTimeZone.knownTimeZoneNames()
class Timezone:
"""Create Timezone object from either name (str) or offset from GMT (int)"""
@ -63,6 +61,7 @@ if is_macos:
if isinstance(other, Timezone):
return self.timezone == other.timezone
return False
else:
import zoneinfo
from datetime import datetime
@ -71,7 +70,6 @@ else:
"""Get list of valid timezones"""
return zoneinfo.available_timezones()
class Timezone:
"""Create Timezone object from either name (str) or offset from GMT (int)"""

View File

@ -520,10 +520,13 @@ def _load_uti_dict():
EXT_UTI_DICT[row["extension"]] = row["UTI"]
UTI_EXT_DICT[row["UTI"]] = row["preferred_extension"]
_load_uti_dict()
# OS version for determining which methods can be used
OS_VER, OS_MAJOR, _ = (int(x) for x in get_macos_version()) if is_macos else (None, None, None)
OS_VER, OS_MAJOR, _ = (
(int(x) for x in get_macos_version()) if is_macos else (None, None, None)
)
def _get_uti_from_mdls(extension):

View File

@ -56,6 +56,7 @@ VERSION_INFO_URL = "https://pypi.org/pypi/osxphotos/json"
is_macos = sys.platform == "darwin"
def assert_macos():
assert is_macos, "This feature only runs on macOS"
@ -280,6 +281,8 @@ def list_photo_libraries():
T = TypeVar("T", bound=Union[str, pathlib.Path])
def normalize_fs_path(path: T) -> T:
"""Normalize filesystem paths with unicode in them"""
form = "NFD" if is_macos else "NFC"