Make PyICU optional
Fix more locale issues Update README.md
This commit is contained in:
parent
e2dfcc91ce
commit
bf55037690
32
README.md
32
README.md
@ -33,21 +33,13 @@ For details, screen-shots, and more, visit [the Wiki](https://github.com/comicta
|
||||
|
||||
## Installation
|
||||
|
||||
It is reccomended to either use the Binaries or a package manager for the best experience
|
||||
|
||||
### Binaries
|
||||
|
||||
Windows and macOS binaries are provided in the [Releases Page](https://github.com/comictagger/comictagger/releases).
|
||||
Windows, Linux and MacOS binaries are provided in the [Releases Page](https://github.com/comictagger/comictagger/releases).
|
||||
|
||||
Just unzip the archive in any folder and run, no additional installation steps are required.
|
||||
|
||||
### PIP installation
|
||||
|
||||
A pip package is provided, you can install it with:
|
||||
|
||||
```
|
||||
$ pip3 install comictagger[GUI]
|
||||
```
|
||||
|
||||
There are two optional dependencies GUI and CBR. You can install the optional dependencies by specifying one or more of `GUI`,`CBR` or `all` in braces e.g. `comictagger[CBR,GUI]`
|
||||
Unzip the archive in any folder and run, no additional installation steps are required.
|
||||
|
||||
### Chocolatey installation (Windows only)
|
||||
|
||||
@ -55,12 +47,26 @@ A [Chocolatey package](https://community.chocolatey.org/packages/comictagger), m
|
||||
```powershell
|
||||
choco install comictagger
|
||||
```
|
||||
|
||||
### PyPi installation
|
||||
|
||||
! Please note that pages may not be sorted correctly if ICU is not installed on Linux and MacOS.
|
||||
If you have issues installing ICU please see the PyICU documentation [here](https://pyicu.org)
|
||||
|
||||
A PyPi package is provided, you can install it with:
|
||||
|
||||
```
|
||||
$ pip3 install comictagger[GUI,ICU]
|
||||
```
|
||||
|
||||
There are several optional dependencies GUI, CBR, 7Z and ICU. You can install the optional dependencies by specifying one or more of `GUI`,`CBR` or `all` in braces e.g. `comictagger[CBR,GUI,ICU]`
|
||||
|
||||
### From source
|
||||
|
||||
1. Ensure you have python 3.9 installed
|
||||
2. Clone this repository `git clone https://github.com/comictagger/comictagger.git`
|
||||
3. `pip3 install -r requirements_dev.txt`
|
||||
7. `pip3 install .` or `pip3 install .[GUI]`
|
||||
7. `pip3 install .` or `pip3 install .[GUI,ICU]`
|
||||
|
||||
|
||||
## Contributors
|
||||
|
@ -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 = []
|
||||
|
@ -15,25 +15,69 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import locale
|
||||
import logging
|
||||
import os
|
||||
import pathlib
|
||||
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 = (str(x[1]), *x[1:])
|
||||
|
||||
lst.append(ret)
|
||||
return tuple(lst)
|
||||
|
||||
|
||||
def os_sorted(lst: Iterable) -> Iterable:
|
||||
if icu_available:
|
||||
raise Exception("fuck off")
|
||||
return natsort.os_sorted(lst)
|
||||
return sorted(lst, key=_custom_key)
|
||||
|
||||
|
||||
def save_locale() -> dict[int, tuple[str | None, str | None]]:
|
||||
locales: dict[int, tuple[str | None, str | None]] = {
|
||||
locale.LC_ALL: (None, None),
|
||||
locale.LC_COLLATE: (None, None),
|
||||
locale.LC_CTYPE: (None, None),
|
||||
locale.LC_MESSAGES: (None, None),
|
||||
locale.LC_MONETARY: (None, None),
|
||||
locale.LC_NUMERIC: (None, None),
|
||||
locale.LC_TIME: (None, None),
|
||||
}
|
||||
for x in locales:
|
||||
locales[x] = locale.getlocale(x)
|
||||
return locales
|
||||
|
||||
|
||||
def set_locale(locales: dict[int, tuple[str | None, str | None]]) -> None:
|
||||
for x, value in locales.items():
|
||||
locale.setlocale(x, value)
|
||||
|
||||
|
||||
def combine_notes(existing_notes: str | None, new_notes: str | None, split: str) -> str:
|
||||
|
@ -9,14 +9,20 @@ import types
|
||||
|
||||
import settngs
|
||||
|
||||
from comicapi.utils import save_locale, set_locale
|
||||
from comictaggerlib.graphics import graphics_path
|
||||
from comictalker.comictalker import ComicTalker
|
||||
|
||||
logger = logging.getLogger("comictagger")
|
||||
|
||||
try:
|
||||
qt_available = True
|
||||
loc = save_locale()
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
qt_available = True
|
||||
|
||||
set_locale(loc)
|
||||
|
||||
def show_exception_box(log_msg: str) -> None:
|
||||
"""Checks if a QApplication instance is available and shows a messagebox with the exception message.
|
||||
If unavailable (non-console application), log an additional notice.
|
||||
|
@ -25,11 +25,15 @@ import tempfile
|
||||
|
||||
import requests
|
||||
|
||||
from comicapi.utils import save_locale, set_locale
|
||||
from comictaggerlib import ctversion
|
||||
|
||||
try:
|
||||
loc = save_locale()
|
||||
from PyQt5 import QtCore, QtNetwork
|
||||
|
||||
set_locale(loc)
|
||||
|
||||
qt_available = True
|
||||
except ImportError:
|
||||
qt_available = False
|
||||
|
@ -25,6 +25,7 @@ import settngs
|
||||
|
||||
import comicapi
|
||||
import comictalker
|
||||
from comicapi.utils import save_locale, set_locale
|
||||
from comictaggerlib import cli, ctsettings
|
||||
from comictaggerlib.ctversion import version
|
||||
from comictaggerlib.log import setup_logging
|
||||
@ -36,9 +37,13 @@ else:
|
||||
|
||||
logger = logging.getLogger("comictagger")
|
||||
|
||||
|
||||
try:
|
||||
loc = save_locale()
|
||||
from comictaggerlib import gui
|
||||
|
||||
set_locale(loc)
|
||||
|
||||
qt_available = gui.qt_available
|
||||
except Exception:
|
||||
logger.exception("Qt unavailable")
|
||||
|
@ -6,13 +6,17 @@ import io
|
||||
import logging
|
||||
import traceback
|
||||
|
||||
from comicapi.utils import save_locale, set_locale
|
||||
from comictaggerlib.graphics import graphics_path
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
try:
|
||||
loc = save_locale()
|
||||
from PyQt5 import QtGui, QtWidgets
|
||||
|
||||
set_locale(loc)
|
||||
|
||||
qt_available = True
|
||||
except ImportError:
|
||||
qt_available = False
|
||||
|
1
requirements-ICU.txt
Normal file
1
requirements-ICU.txt
Normal file
@ -0,0 +1 @@
|
||||
pyicu; sys_platform == 'linux' or sys_platform == 'darwin'
|
@ -5,7 +5,6 @@ natsort>=8.1.0
|
||||
pathvalidate
|
||||
pillow>=9.1.0, <10
|
||||
pycountry
|
||||
#pyicu; sys_platform == 'linux' or sys_platform == 'darwin'
|
||||
rapidfuzz>=2.12.0
|
||||
requests==2.*
|
||||
settngs==0.6.2
|
||||
|
@ -12,7 +12,7 @@ from testing.filenames import datadir
|
||||
|
||||
|
||||
@pytest.mark.xfail(not comicapi.archivers.rar.rar_support, reason="rar support")
|
||||
def test_getPageNameList():
|
||||
def test_get_page_name_list():
|
||||
c = comicapi.comicarchive.ComicArchive(datadir / "fake_cbr.cbr")
|
||||
assert c.seems_to_be_a_comic_archive()
|
||||
pageNameList = c.get_page_name_list()
|
||||
|
@ -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")
|
||||
|
Loading…
Reference in New Issue
Block a user