Skip to content

Commit

Permalink
Fix for unknown UTI #1643
Browse files Browse the repository at this point in the history
  • Loading branch information
RhetTbull committed Aug 15, 2024
1 parent c74e863 commit a7aec32
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 13 deletions.
40 changes: 27 additions & 13 deletions osxphotos/uti.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
""" get UTI for a given file extension and the preferred extension for a given UTI
On macOS <= 11 (Big Sur), uses objective C CoreServices methods
UTTypeCopyPreferredTagWithClass and UTTypeCreatePreferredIdentifierForTag to retrieve the
On macOS <= 11 (Big Sur), uses objective C CoreServices methods
UTTypeCopyPreferredTagWithClass and UTTypeCreatePreferredIdentifierForTag to retrieve the
UTI and the extension. These are deprecated in 10.15 (Catalina) and no longer supported on Monterey.
On Monterey, these calls are replaced with Swift methods that I can't call from python so
this code uses a cached dict of UTI values. The code first checks to see if the extension or UTI
is available in the cache and if so, returns it. If not, it performs a subprocess call to `mdls` to
retrieve the UTI (by creating a temp file with the correct extension) and returns the UTI. This only
works for the extension -> UTI lookup. On Monterey, if there is no cached value for UTI -> extension lookup,
On Monterey, these calls are replaced with Swift methods that I can't call from python so
this code uses a cached dict of UTI values. The code first checks to see if the extension or UTI
is available in the cache and if so, returns it. If not, it performs a subprocess call to `mdls` to
retrieve the UTI (by creating a temp file with the correct extension) and returns the UTI. This only
works for the extension -> UTI lookup. On Monterey, if there is no cached value for UTI -> extension lookup,
returns None.
Outside of macOS uses only the hardcoded list of UTIs.
Expand All @@ -19,6 +19,7 @@
from __future__ import annotations

import csv
import logging
import os
import pathlib
import re
Expand All @@ -31,6 +32,8 @@
import CoreServices
import objc

logger = logging.getLogger("osxphotos")

__all__ = ["get_preferred_uti_extension", "get_uti_for_extension", "get_uti_for_path"]

# cached values of all the UTIs (< 6 chars long) known to my Mac running macOS 10.15.7
Expand Down Expand Up @@ -229,6 +232,7 @@
odt,org.oasis-open.opendocument.text,odt,application/vnd.oasis.opendocument.text
omf,com.avid.open-media-framework,omf,None
orf,com.olympus.raw-image,orf,None
orf,com.olympus.or-raw-image,orf,None
otc,public.opentype-collection-font,otc,None
otf,public.opentype-font,otf,None
otg,org.oasis-open.opendocument.graphics-template,otg,application/vnd.oasis.opendocument.graphics-template
Expand Down Expand Up @@ -576,10 +580,16 @@ def _get_ext_from_uti_dict(uti):
return None


def get_preferred_uti_extension(uti: str) -> str | None:
"""get preferred extension for a UTI type
uti: UTI str, e.g. 'public.jpeg'
returns: preferred extension as str or None if cannot be determined"""
def get_preferred_uti_extension(uti: str) -> str:
"""Get preferred extension for a UTI type
Args:
uti: UTI str, e.g. 'public.jpeg'
Returns: preferred extension as str or empty string if extension cannot be determined
Note: Logs a warning if extension cannot be determined.
"""

if is_macos and (OS_VER, OS_MAJOR) <= (10, 16):
# reference: https://developer.apple.com/documentation/coreservices/1442744-uttypecopypreferredtagwithclass?language=objc
Expand All @@ -595,9 +605,13 @@ def get_preferred_uti_extension(uti: str) -> str | None:
if uti == "public.heic":
return "heic"

return None
logger.warning(f"Could not determine extension for UTI: {uti}")
return ""

return _get_ext_from_uti_dict(uti)
ext = _get_ext_from_uti_dict(uti) or ""
if not ext:
logger.warning(f"Could not determine extension for UTI: {uti}")
return ext


def get_uti_for_extension(extension: str) -> str | None:
Expand Down
9 changes: 9 additions & 0 deletions tests/test_uti.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
""" test uti.py """

import logging

import pytest

import osxphotos.uti
Expand All @@ -20,6 +22,13 @@ def test_get_preferred_uti_extension():
assert get_preferred_uti_extension(uti) == UTI_DICT[uti]


def test_get_preferred_uti_extension_unknown(caplog):
"""test get_preferred_uti_extension for unknown UTI #1643"""
caplog.set_level(logging.WARNING)
assert get_preferred_uti_extension("com.OSXPHOTOS.UNKNOWN.FOOBAR") == ""
assert "Could not determine extension for UTI" in caplog.text


def test_get_uti_for_extension():
"""get get_uti_for_extension"""
for ext in EXT_DICT:
Expand Down

0 comments on commit a7aec32

Please sign in to comment.