Make PyICU optional

Update README.md
This commit is contained in:
Timmy Welch 2023-04-22 22:00:26 -07:00
parent c1aba269a9
commit e70c47d12a
No known key found for this signature in database
10 changed files with 125 additions and 69 deletions

View File

@ -22,7 +22,6 @@ import shutil
import sys
from typing import cast
import natsort
import wordninja
from comicapi import filenamelexer, filenameparser, utils
@ -280,7 +279,7 @@ class ComicArchive:
# seems like some archive creators are on Windows, and don't know about case-sensitivity!
if sort_list:
files = cast(list[str], natsort.os_sorted(files))
files = cast(list[str], utils.os_sorted(files))
# make a sub-list of image files
self.page_list = []

View File

@ -18,22 +18,46 @@ import json
import logging
import os
import pathlib
import platform
import unicodedata
from collections import defaultdict
from collections.abc import Mapping
from collections.abc import Iterable, Mapping
from shutil import which # noqa: F401
from typing import Any
import natsort
import pycountry
import rapidfuzz.fuzz
import comicapi.data
try:
import icu
del icu
icu_available = True
except ImportError:
icu_available = False
logger = logging.getLogger(__name__)
class UtilsVars:
already_fixed_encoding = False
def _custom_key(tup):
lst = []
for x in natsort.os_sort_keygen()(tup):
ret = x
if len(x) > 1 and isinstance(x[1], int) and isinstance(x[0], str) and x[0] == "":
ret = ("a", *x[1:])
lst.append(ret)
return tuple(lst)
def os_sorted(lst: Iterable) -> Iterable:
key = _custom_key
if icu_available or platform.system() == "Windows":
key = natsort.os_sort_keygen()
return sorted(lst, key=key)
def combine_notes(existing_notes: str | None, new_notes: str | None, split: str) -> str:

View File

@ -1,10 +0,0 @@
#!/usr/bin/env python3
from __future__ import annotations
import localefix
from comictaggerlib.main import App
if __name__ == "__main__":
localefix.configure_locale()
App().run()

View File

@ -9,7 +9,7 @@ block_cipher = None
a = Analysis(
["comictagger.py"],
["comictaggerlib/__main__.py"],
pathex=[],
binaries=[],
datas=[],

View File

@ -0,0 +1,5 @@
from __future__ import annotations
from comictaggerlib.main import main
main()

View File

@ -73,12 +73,12 @@ try:
return True
return super().event(event)
except ImportError as e:
except ImportError:
def show_exception_box(log_msg: str) -> None:
...
logger.error(str(e))
logger.exception("Qt unavailable")
qt_available = False

View File

@ -17,8 +17,12 @@ from __future__ import annotations
import argparse
import json
import locale
import logging
import logging.handlers
import os
import signal
import subprocess
import sys
import settngs
@ -48,6 +52,49 @@ except Exception:
logger.setLevel(logging.DEBUG)
def _lang_code_mac() -> str:
"""
stolen from https://github.com/mu-editor/mu
Returns the user's language preference as defined in the Language & Region
preference pane in macOS's System Preferences.
"""
# Uses the shell command `defaults read -g AppleLocale` that prints out a
# language code to standard output. Assumptions about the command:
# - It exists and is in the shell's PATH.
# - It accepts those arguments.
# - It returns a usable language code.
#
# Reference documentation:
# - The man page for the `defaults` command on macOS.
# - The macOS underlying API:
# https://developer.apple.com/documentation/foundation/nsuserdefaults.
lang_detect_command = "defaults read -g AppleLocale"
status, output = subprocess.getstatusoutput(lang_detect_command)
if status == 0:
# Command was successful.
lang_code = output
else:
logging.warning("Language detection command failed: %r", output)
lang_code = ""
return lang_code
def configure_locale() -> None:
if sys.platform == "darwin" and "LANG" not in os.environ:
code = _lang_code_mac()
if code != "":
os.environ["LANG"] = f"{code}.utf-8"
locale.setlocale(locale.LC_ALL, "")
sys.stdout.reconfigure(encoding=sys.getdefaultencoding()) # type: ignore[attr-defined]
sys.stderr.reconfigure(encoding=sys.getdefaultencoding()) # type: ignore[attr-defined]
sys.stdin.reconfigure(encoding=sys.getdefaultencoding()) # type: ignore[attr-defined]
def update_publishers(config: settngs.Config[settngs.Namespace]) -> None:
json_file = config[0].runtime_config.user_config_dir / "publishers.json"
if json_file.exists():
@ -66,6 +113,7 @@ class App:
self.config_load_success = False
def run(self) -> None:
configure_locale()
conf = self.initialize()
self.initialize_dirs(conf.config)
self.load_plugins(conf)

View File

@ -1,50 +0,0 @@
from __future__ import annotations
import locale
import logging
import os
import subprocess
import sys
def _lang_code_mac() -> str:
"""
stolen from https://github.com/mu-editor/mu
Returns the user's language preference as defined in the Language & Region
preference pane in macOS's System Preferences.
"""
# Uses the shell command `defaults read -g AppleLocale` that prints out a
# language code to standard output. Assumptions about the command:
# - It exists and is in the shell's PATH.
# - It accepts those arguments.
# - It returns a usable language code.
#
# Reference documentation:
# - The man page for the `defaults` command on macOS.
# - The macOS underlying API:
# https://developer.apple.com/documentation/foundation/nsuserdefaults.
lang_detect_command = "defaults read -g AppleLocale"
status, output = subprocess.getstatusoutput(lang_detect_command)
if status == 0:
# Command was successful.
lang_code = output
else:
logging.warning("Language detection command failed: %r", output)
lang_code = ""
return lang_code
def configure_locale() -> None:
if sys.platform == "darwin" and "LANG" not in os.environ:
code = _lang_code_mac()
if code != "":
os.environ["LANG"] = f"{code}.utf-8"
locale.setlocale(locale.LC_ALL, "")
sys.stdout.reconfigure(encoding=sys.getdefaultencoding()) # type: ignore[attr-defined]
sys.stderr.reconfigure(encoding=sys.getdefaultencoding()) # type: ignore[attr-defined]
sys.stdin.reconfigure(encoding=sys.getdefaultencoding()) # type: ignore[attr-defined]

View File

@ -36,7 +36,7 @@ install_requires = read("requirements.txt").splitlines()
extras_require = {}
extra_req_files = glob.glob("requirements-*.txt")
for extra_req_file in extra_req_files:
name = os.path.splitext(extra_req_file)[0].replace("requirements-", "", 1)
name = os.path.splitext(extra_req_file)[0].removeprefix("requirements-")
extras_require[name] = read(extra_req_file).splitlines()
# If there are any extras, add a catch-all case that includes everything.

View File

@ -7,6 +7,46 @@ import pytest
import comicapi.utils
def test_os_sorted():
page_name_list = [
"cover.jpg",
"Page1.jpeg",
"!cover.jpg",
"page4.webp",
"test/!cover.tar.gz",
"!cover.tar.gz",
"00.jpg",
"ignored.txt",
"page0.jpg",
"test/00.tar.gz",
".ignored.jpg",
"Page3.gif",
"!cover.tar.gz",
"Page2.png",
"page10.jpg",
"!cover",
]
assert comicapi.utils.os_sorted(page_name_list) == [
"!cover",
"!cover.jpg",
"!cover.tar.gz",
"!cover.tar.gz", # Depending on locale punctuation or numbers might come first (Linux, MacOS)
".ignored.jpg",
"00.jpg",
"cover.jpg",
"ignored.txt",
"page0.jpg",
"Page1.jpeg",
"Page2.png",
"Page3.gif",
"page4.webp",
"page10.jpg",
"test/!cover.tar.gz",
"test/00.tar.gz",
]
def test_recursive_list_with_file(tmp_path) -> None:
foo_png = tmp_path / "foo.png"
foo_png.write_text("not a png")