From 779e69a38cf4bbe1c32037dc9e84628f761bab42 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Mon, 9 Jan 2023 21:38:45 +0530 Subject: [PATCH] Remove use of global icu_upper/lower --- src/calibre/db/adding.py | 3 ++ src/calibre/db/backend.py | 2 +- src/calibre/db/cache.py | 6 +-- src/calibre/db/categories.py | 8 ++-- src/calibre/db/legacy.py | 19 ++++++--- src/calibre/db/search.py | 20 ++++++---- src/calibre/db/tables.py | 7 ++-- src/calibre/db/utils.py | 15 ++++--- src/calibre/db/write.py | 9 +++-- src/calibre/devices/mtp/books.py | 2 +- src/calibre/devices/mtp/driver.py | 21 ++++++---- src/calibre/ebooks/metadata/author_mapper.py | 4 +- src/calibre/ebooks/metadata/book/base.py | 16 +++++--- src/calibre/ebooks/metadata/opf2.py | 40 ++++++++++++------- src/calibre/ebooks/metadata/sources/amazon.py | 26 +++++++----- src/calibre/ebooks/metadata/tag_mapper.py | 2 + src/calibre/ebooks/metadata/worker.py | 1 + src/calibre/ebooks/oeb/polish/css.py | 14 +++---- src/calibre/ebooks/oeb/polish/embed.py | 4 +- src/calibre/ebooks/oeb/polish/stats.py | 9 +++-- .../ebooks/oeb/polish/tests/cascade.py | 14 ++++--- src/calibre/ebooks/oeb/polish/utils.py | 2 + .../ebooks/oeb/transforms/manglecase.py | 6 +-- src/calibre/gui2/actions/similar_books.py | 1 + src/calibre/gui2/add.py | 1 + src/calibre/gui2/author_mapper.py | 2 +- src/calibre/gui2/custom_column_widgets.py | 28 +++++++------ .../gui2/device_drivers/mtp_folder_browser.py | 8 ++-- src/calibre/gui2/dialogs/authors_edit.py | 11 ++--- .../gui2/dialogs/edit_authors_dialog.py | 15 ++++--- src/calibre/gui2/dialogs/metadata_bulk.py | 14 ++++--- src/calibre/gui2/dialogs/plugin_updater.py | 11 ++--- .../gui2/dialogs/saved_search_editor.py | 6 +-- src/calibre/gui2/dialogs/tag_categories.py | 7 ++-- src/calibre/gui2/dialogs/tag_list_editor.py | 18 +++++---- src/calibre/gui2/dialogs/template_dialog.py | 2 +- src/calibre/gui2/font_family_chooser.py | 9 +++-- src/calibre/gui2/metadata/diff.py | 4 +- src/calibre/gui2/preferences/search.py | 11 ++--- src/calibre/gui2/store/search/models.py | 15 +++---- src/calibre/gui2/tag_browser/model.py | 11 ++--- src/calibre/gui2/tag_mapper.py | 6 +-- src/calibre/gui2/toc/main.py | 17 ++++---- src/calibre/gui2/tweak_book/manage_fonts.py | 17 ++++---- src/calibre/library/caches.py | 28 +++++++------ .../library/catalogs/epub_mobi_builder.py | 2 +- src/calibre/library/database2.py | 2 +- src/calibre/library/field_metadata.py | 1 + src/calibre/srv/metadata.py | 14 +++---- src/calibre/utils/fonts/scanner.py | 2 +- src/calibre/utils/formatter_functions.py | 2 +- src/calibre/utils/icu.py | 2 +- src/calibre/utils/matcher.py | 20 ++++++---- 53 files changed, 317 insertions(+), 220 deletions(-) diff --git a/src/calibre/db/adding.py b/src/calibre/db/adding.py index 58452b32a0..b78e6fdadb 100644 --- a/src/calibre/db/adding.py +++ b/src/calibre/db/adding.py @@ -15,6 +15,7 @@ from calibre import prints from calibre.constants import filesystem_encoding, ismacos, iswindows from calibre.ebooks import BOOK_EXTENSIONS from calibre.utils.filenames import make_long_path_useable +from calibre.utils.icu import lower as icu_lower from polyglot.builtins import itervalues @@ -48,10 +49,12 @@ def compile_rule(rule): return icu_lower(filename).endswith(q) elif 'glob' in mt: q = compile_glob(rule['query']) + def func(filename): return (q.match(filename) is not None) else: q = re.compile(rule['query']) + def func(filename): return (q.match(filename) is not None) ans = func diff --git a/src/calibre/db/backend.py b/src/calibre/db/backend.py index f8d2b7ab09..614abdbcdc 100644 --- a/src/calibre/db/backend.py +++ b/src/calibre/db/backend.py @@ -46,7 +46,7 @@ from calibre.utils.formatter_functions import ( compile_user_template_functions, formatter_functions, load_user_template_functions, unload_user_template_functions, ) -from calibre.utils.icu import sort_key +from calibre.utils.icu import lower as icu_lower, sort_key from calibre.utils.resources import get_path as P from polyglot.builtins import ( cmp, iteritems, itervalues, native_string_type, reraise, string_or_bytes, diff --git a/src/calibre/db/cache.py b/src/calibre/db/cache.py index c7508026bc..cab398e9fa 100644 --- a/src/calibre/db/cache.py +++ b/src/calibre/db/cache.py @@ -24,7 +24,7 @@ from time import monotonic, sleep, time from calibre import as_unicode, detect_ncpus, isbytestring from calibre.constants import iswindows, preferred_encoding from calibre.customize.ui import ( - run_plugins_on_import, run_plugins_on_postadd, run_plugins_on_postimport + run_plugins_on_import, run_plugins_on_postadd, run_plugins_on_postimport, ) from calibre.db import SPOOL_SIZE, _get_next_series_num_for_list from calibre.db.annotations import merge_annotations @@ -34,7 +34,7 @@ from calibre.db.fields import IDENTITY, InvalidLinkTable, create_field from calibre.db.lazy import FormatMetadata, FormatsList, ProxyMetadata from calibre.db.listeners import EventDispatcher, EventType from calibre.db.locking import ( - DowngradeLockError, LockingError, SafeReadLock, create_locks, try_lock + DowngradeLockError, LockingError, SafeReadLock, create_locks, try_lock, ) from calibre.db.search import Search from calibre.db.tables import VirtualTable @@ -47,7 +47,7 @@ from calibre.ebooks.metadata.opf2 import metadata_to_opf from calibre.ptempfile import PersistentTemporaryFile, SpooledTemporaryFile, base_dir from calibre.utils.config import prefs, tweaks from calibre.utils.date import UNDEFINED_DATE, now as nowf, utcnow -from calibre.utils.icu import sort_key +from calibre.utils.icu import lower as icu_lower, sort_key from calibre.utils.localization import canonicalize_lang from polyglot.builtins import cmp, iteritems, itervalues, string_or_bytes diff --git a/src/calibre/db/categories.py b/src/calibre/db/categories.py index 07b7c50cd5..f0c8636348 100644 --- a/src/calibre/db/categories.py +++ b/src/calibre/db/categories.py @@ -8,11 +8,13 @@ __docformat__ = 'restructuredtext en' import copy from collections import OrderedDict from functools import partial -from polyglot.builtins import iteritems, native_string_type from calibre.ebooks.metadata import author_to_author_sort -from calibre.utils.config_base import tweaks, prefs -from calibre.utils.icu import sort_key, collation_order +from calibre.utils.config_base import prefs, tweaks +from calibre.utils.icu import ( + collation_order, lower as icu_lower, sort_key, upper as icu_upper, +) +from polyglot.builtins import iteritems, native_string_type CATEGORY_SORTS = ('name', 'popularity', 'rating') # This has to be a tuple not a set diff --git a/src/calibre/db/legacy.py b/src/calibre/db/legacy.py index 7567050030..a333bb3d6c 100644 --- a/src/calibre/db/legacy.py +++ b/src/calibre/db/legacy.py @@ -4,24 +4,30 @@ __license__ = 'GPL v3' __copyright__ = '2013, Kovid Goyal ' -import os, traceback, weakref -from polyglot.builtins import iteritems +import os +import traceback +import weakref from collections.abc import MutableMapping from calibre import force_unicode, isbytestring from calibre.constants import preferred_encoding -from calibre.db import _get_next_series_num_for_list, _get_series_values, get_data_as_dict +from calibre.db import ( + _get_next_series_num_for_list, _get_series_values, get_data_as_dict, +) from calibre.db.adding import ( - find_books_in_directory, import_book_directory_multiple, - import_book_directory, recursive_import, add_catalog, add_news) + add_catalog, add_news, find_books_in_directory, import_book_directory, + import_book_directory_multiple, recursive_import, +) from calibre.db.backend import DB, set_global_state as backend_set_global_state from calibre.db.cache import Cache -from calibre.db.errors import NoSuchFormat from calibre.db.categories import CATEGORY_SORTS +from calibre.db.errors import NoSuchFormat from calibre.db.view import View from calibre.db.write import clean_identifier, get_series_values from calibre.utils.date import utcnow +from calibre.utils.icu import lower as icu_lower from calibre.utils.search_query_parser import set_saved_searches +from polyglot.builtins import iteritems def cleanup_tags(tags): @@ -156,6 +162,7 @@ class ThreadSafePrefs(MutableMapping): if isinstance(raw, bytes): raw = raw.decode(preferred_encoding) import json + from calibre.utils.config import from_json return json.loads(raw, object_hook=from_json) diff --git a/src/calibre/db/search.py b/src/calibre/db/search.py index 60d48cee3f..b4de2f014b 100644 --- a/src/calibre/db/search.py +++ b/src/calibre/db/search.py @@ -5,18 +5,22 @@ __license__ = 'GPL v3' __copyright__ = '2013, Kovid Goyal ' __docformat__ = 'restructuredtext en' -import regex, weakref, operator -from functools import partial +import operator +import regex +import weakref +from collections import OrderedDict, deque from datetime import timedelta -from collections import deque, OrderedDict +from functools import partial -from calibre.constants import preferred_encoding, DEBUG +from calibre.constants import DEBUG, preferred_encoding from calibre.db.utils import force_to_bool from calibre.utils.config_base import prefs -from calibre.utils.date import parse_date, UNDEFINED_DATE, now, dt_as_local -from calibre.utils.icu import primary_no_punc_contains, primary_contains, sort_key -from calibre.utils.localization import lang_map, canonicalize_lang -from calibre.utils.search_query_parser import SearchQueryParser, ParseException +from calibre.utils.date import UNDEFINED_DATE, dt_as_local, now, parse_date +from calibre.utils.icu import ( + lower as icu_lower, primary_contains, primary_no_punc_contains, sort_key, +) +from calibre.utils.localization import canonicalize_lang, lang_map +from calibre.utils.search_query_parser import ParseException, SearchQueryParser from polyglot.builtins import iteritems, string_or_bytes CONTAINS_MATCH = 0 diff --git a/src/calibre/db/tables.py b/src/calibre/db/tables.py index cff608b312..4a2a4da706 100644 --- a/src/calibre/db/tables.py +++ b/src/calibre/db/tables.py @@ -6,13 +6,14 @@ __copyright__ = '2011, Kovid Goyal ' __docformat__ = 'restructuredtext en' import numbers -from datetime import datetime, timedelta from collections import defaultdict +from datetime import datetime, timedelta -from calibre.utils.date import parse_date, UNDEFINED_DATE, utc_tz from calibre.ebooks.metadata import author_to_author_sort -from polyglot.builtins import iteritems, itervalues +from calibre.utils.date import UNDEFINED_DATE, parse_date, utc_tz +from calibre.utils.icu import lower as icu_lower from calibre_extensions.speedup import parse_date as _c_speedup +from polyglot.builtins import iteritems, itervalues def c_parse(val): diff --git a/src/calibre/db/utils.py b/src/calibre/db/utils.py index 2d3fc1deae..8c8a449284 100644 --- a/src/calibre/db/utils.py +++ b/src/calibre/db/utils.py @@ -4,16 +4,21 @@ __license__ = 'GPL v3' __copyright__ = '2013, Kovid Goyal ' -import os, errno, sys, re -from locale import localeconv +import errno +import os +import re +import sys from collections import OrderedDict, namedtuple -from polyglot.builtins import iteritems, itervalues, string_or_bytes +from locale import localeconv from threading import Lock from calibre import as_unicode, prints -from calibre.constants import cache_dir, get_windows_number_formats, iswindows, preferred_encoding - +from calibre.constants import ( + cache_dir, get_windows_number_formats, iswindows, preferred_encoding, +) +from calibre.utils.icu import lower as icu_lower from calibre.utils.localization import canonicalize_lang +from polyglot.builtins import iteritems, itervalues, string_or_bytes def force_to_bool(val): diff --git a/src/calibre/db/write.py b/src/calibre/db/write.py index 5f97dd80ce..8b240316ff 100644 --- a/src/calibre/db/write.py +++ b/src/calibre/db/write.py @@ -6,16 +6,17 @@ __copyright__ = '2013, Kovid Goyal ' __docformat__ = 'restructuredtext en' import re -from functools import partial from datetime import datetime -from polyglot.builtins import iteritems, itervalues +from functools import partial from calibre.constants import preferred_encoding from calibre.ebooks.metadata import author_to_author_sort, title_sort from calibre.utils.date import ( - parse_only_date, parse_date, UNDEFINED_DATE, isoformat, is_date_undefined) + UNDEFINED_DATE, is_date_undefined, isoformat, parse_date, parse_only_date, +) +from calibre.utils.icu import lower as icu_lower, strcmp from calibre.utils.localization import canonicalize_lang -from calibre.utils.icu import strcmp +from polyglot.builtins import iteritems, itervalues missing = object() diff --git a/src/calibre/devices/mtp/books.py b/src/calibre/devices/mtp/books.py index 3384a830d5..44a6ca0495 100644 --- a/src/calibre/devices/mtp/books.py +++ b/src/calibre/devices/mtp/books.py @@ -12,6 +12,7 @@ from calibre.ebooks.metadata import title_sort from calibre.ebooks.metadata.book.base import Metadata from calibre.ebooks.metadata.book.json_codec import JsonCodec from calibre.utils.date import utcnow +from calibre.utils.icu import lower as icu_lower class BookList(BL): @@ -73,4 +74,3 @@ class Book(Metadata): class JSONCodec(JsonCodec): pass - diff --git a/src/calibre/devices/mtp/driver.py b/src/calibre/devices/mtp/driver.py index 6d12c601e0..5d0e53d8de 100644 --- a/src/calibre/devices/mtp/driver.py +++ b/src/calibre/devices/mtp/driver.py @@ -5,7 +5,11 @@ __license__ = 'GPL v3' __copyright__ = '2012, Kovid Goyal ' __docformat__ = 'restructuredtext en' -import json, traceback, posixpath, importlib, os +import importlib +import json +import os +import posixpath +import traceback from io import BytesIO from calibre import prints @@ -13,9 +17,10 @@ from calibre.constants import iswindows, numeric_version from calibre.devices.errors import PathError from calibre.devices.mtp.base import debug from calibre.devices.mtp.defaults import DeviceDefaults -from calibre.ptempfile import SpooledTemporaryFile, PersistentTemporaryDirectory +from calibre.ptempfile import PersistentTemporaryDirectory, SpooledTemporaryFile from calibre.utils.filenames import shorten_components_to -from polyglot.builtins import iteritems, itervalues, as_bytes +from calibre.utils.icu import lower as icu_lower +from polyglot.builtins import as_bytes, iteritems, itervalues BASE = importlib.import_module('calibre.devices.mtp.%s.driver'%( 'windows' if iswindows else 'unix')).MTP_DEVICE @@ -153,9 +158,10 @@ class MTP_DEVICE(BASE): # Device information {{{ def _update_drive_info(self, storage, location_code, name=None): - from calibre.utils.date import isoformat, now - from calibre.utils.config import from_json, to_json import uuid + + from calibre.utils.config import from_json, to_json + from calibre.utils.date import isoformat, now f = storage.find_path(self.calibre_file_paths['driveinfo'].split('/')) dinfo = {} if f is not None: @@ -213,8 +219,7 @@ class MTP_DEVICE(BASE): self.report_progress(0, msg) def books(self, oncard=None, end_session=True): - from calibre.devices.mtp.books import JSONCodec - from calibre.devices.mtp.books import BookList, Book + from calibre.devices.mtp.books import Book, BookList, JSONCodec self.report_progress(0, _('Listing files, this can take a while')) self.get_driveinfo() # Ensure driveinfo is loaded sid = {'carda':self._carda_id, 'cardb':self._cardb_id}.get(oncard, @@ -288,8 +293,8 @@ class MTP_DEVICE(BASE): return bl def read_file_metadata(self, mtp_file): - from calibre.ebooks.metadata.meta import get_metadata from calibre.customize.ui import quick_metadata + from calibre.ebooks.metadata.meta import get_metadata ext = mtp_file.name.rpartition('.')[-1].lower() stream = self.get_mtp_file(mtp_file) with quick_metadata: diff --git a/src/calibre/ebooks/metadata/author_mapper.py b/src/calibre/ebooks/metadata/author_mapper.py index e7705b539a..9286f160f7 100644 --- a/src/calibre/ebooks/metadata/author_mapper.py +++ b/src/calibre/ebooks/metadata/author_mapper.py @@ -5,7 +5,9 @@ import re from collections import deque -from calibre.utils.icu import capitalize, lower, upper +from calibre.utils.icu import ( + capitalize, lower, lower as icu_lower, upper, upper as icu_upper, +) def cap_author_token(token): diff --git a/src/calibre/ebooks/metadata/book/base.py b/src/calibre/ebooks/metadata/book/base.py index bc17b256f0..ed6b15e1e0 100644 --- a/src/calibre/ebooks/metadata/book/base.py +++ b/src/calibre/ebooks/metadata/book/base.py @@ -5,15 +5,17 @@ __license__ = 'GPL v3' __copyright__ = '2010, Kovid Goyal ' __docformat__ = 'restructuredtext en' -import copy, traceback +import copy +import traceback from calibre import prints from calibre.constants import DEBUG -from calibre.ebooks.metadata.book import (SC_COPYABLE_FIELDS, - SC_FIELDS_COPY_NOT_NULL, STANDARD_METADATA_FIELDS, - TOP_LEVEL_IDENTIFIERS, ALL_METADATA_FIELDS) +from calibre.ebooks.metadata.book import ( + ALL_METADATA_FIELDS, SC_COPYABLE_FIELDS, SC_FIELDS_COPY_NOT_NULL, + STANDARD_METADATA_FIELDS, TOP_LEVEL_IDENTIFIERS, +) from calibre.library.field_metadata import FieldMetadata -from calibre.utils.icu import sort_key +from calibre.utils.icu import lower as icu_lower, sort_key from polyglot.builtins import iteritems, string_or_bytes # Special sets used to optimize the performance of getting and setting @@ -56,6 +58,8 @@ def reset_field_metadata(): def ck(typ): return icu_lower(typ).strip().replace(':', '').replace(',', '') + + def cv(val): return val.strip().replace(',', '|') @@ -734,8 +738,8 @@ class Metadata: A string representation of this object, suitable for printing to console ''' - from calibre.utils.date import isoformat from calibre.ebooks.metadata import authors_to_string + from calibre.utils.date import isoformat ans = [] def fmt(x, y): diff --git a/src/calibre/ebooks/metadata/opf2.py b/src/calibre/ebooks/metadata/opf2.py index ce3eb80a4c..d3a7a6744a 100644 --- a/src/calibre/ebooks/metadata/opf2.py +++ b/src/calibre/ebooks/metadata/opf2.py @@ -8,21 +8,29 @@ __docformat__ = 'restructuredtext en' lxml based OPF parser. ''' -import re, sys, functools, os, uuid, glob, io, json, copy - +import copy +import functools +import glob +import io +import json +import os +import re +import sys +import uuid from lxml import etree -from calibre.ebooks import escape_xpath_attr +from calibre import guess_type, prints from calibre.constants import __appname__, __version__, filesystem_encoding +from calibre.ebooks import escape_xpath_attr +from calibre.ebooks.metadata import MetaInformation, check_isbn, string_to_authors +from calibre.ebooks.metadata.book.base import Metadata from calibre.ebooks.metadata.toc import TOC from calibre.ebooks.metadata.utils import parse_opf, pretty_print_opf as _pretty_print -from calibre.ebooks.metadata import string_to_authors, MetaInformation, check_isbn -from calibre.ebooks.metadata.book.base import Metadata -from calibre.utils.date import parse_date, isoformat -from calibre.utils.localization import get_lang, canonicalize_lang -from calibre import prints, guess_type from calibre.utils.cleantext import clean_ascii_chars, clean_xml_chars from calibre.utils.config import tweaks +from calibre.utils.date import isoformat, parse_date +from calibre.utils.icu import lower as icu_lower, upper as icu_upper +from calibre.utils.localization import canonicalize_lang, get_lang from calibre.utils.xml_parse import safe_xml_fromstring from polyglot.builtins import iteritems from polyglot.urllib import unquote, urlparse @@ -480,9 +488,10 @@ class TitleSortField(MetadataField): def serialize_user_metadata(metadata_elem, all_user_metadata, tail='\n'+(' '*8)): + from calibre.ebooks.metadata.book.json_codec import ( + encode_is_multiple, object_to_unicode, + ) from calibre.utils.config import to_json - from calibre.ebooks.metadata.book.json_codec import (object_to_unicode, - encode_is_multiple) for name, fm in all_user_metadata.items(): try: @@ -626,8 +635,8 @@ class OPF: # {{{ def read_user_metadata(self): self._user_metadata_ = {} temp = Metadata('x', ['x']) - from calibre.utils.config import from_json from calibre.ebooks.metadata.book.json_codec import decode_is_multiple + from calibre.utils.config import from_json elems = self.root.xpath('//*[name() = "meta" and starts-with(@name,' '"calibre:user_metadata:") and @content]') for elem in elems: @@ -1448,7 +1457,8 @@ class OPFCreator(Metadata): # Actual rendering from lxml.builder import ElementMaker - from calibre.ebooks.oeb.base import OPF2_NS, DC11_NS, CALIBRE_NS + + from calibre.ebooks.oeb.base import CALIBRE_NS, DC11_NS, OPF2_NS DNS = OPF2_NS+'___xx___' E = ElementMaker(namespace=DNS, nsmap={None:DNS}) M = ElementMaker(namespace=DNS, @@ -1571,9 +1581,10 @@ class OPFCreator(Metadata): def metadata_to_opf(mi, as_string=True, default_lang=None): - from lxml import etree import textwrap - from calibre.ebooks.oeb.base import OPF, DC + from lxml import etree + + from calibre.ebooks.oeb.base import DC, OPF if not mi.application_id: mi.application_id = str(uuid.uuid4()) @@ -1652,6 +1663,7 @@ def metadata_to_opf(mi, as_string=True, default_lang=None): if mi.tags: for tag in mi.tags: factory(DC('subject'), tag) + def meta(n, c): return factory('meta', name='calibre:' + n, content=c) if getattr(mi, 'author_link_map', None) is not None: diff --git a/src/calibre/ebooks/metadata/sources/amazon.py b/src/calibre/ebooks/metadata/sources/amazon.py index 3594495184..78a268d784 100644 --- a/src/calibre/ebooks/metadata/sources/amazon.py +++ b/src/calibre/ebooks/metadata/sources/amazon.py @@ -4,15 +4,18 @@ from __future__ import absolute_import, division, print_function, unicode_literals import re -import string import socket +import string import time from functools import partial + try: from queue import Empty, Queue except ImportError: from Queue import Empty, Queue + from threading import Thread + try: from urllib.parse import urlparse except ImportError: @@ -24,9 +27,10 @@ from calibre import as_unicode, browser, random_user_agent, xml_replace_entities from calibre.ebooks.metadata import check_isbn from calibre.ebooks.metadata.book.base import Metadata from calibre.ebooks.metadata.sources.base import Option, Source, fixauthors, fixcase +from calibre.ebooks.oeb.base import urlquote +from calibre.utils.icu import lower as icu_lower from calibre.utils.localization import canonicalize_lang from calibre.utils.random_ua import accept_header_for_ua -from calibre.ebooks.oeb.base import urlquote def sort_matches_preferring_kindle_editions(matches): @@ -89,9 +93,10 @@ def parse_html(raw): def parse_details_page(url, log, timeout, browser, domain): - from calibre.utils.cleantext import clean_ascii_chars - from calibre.ebooks.chardet import xml_to_unicode from lxml.html import tostring + + from calibre.ebooks.chardet import xml_to_unicode + from calibre.utils.cleantext import clean_ascii_chars try: from calibre.ebooks.metadata.sources.update import search_engines_module get_data_for_cached_url = search_engines_module().get_data_for_cached_url @@ -726,6 +731,7 @@ class Worker(Thread): # Get details {{{ ns = ns[0] if len(ns) == 0 and ns.text: import html5lib + # html5lib parsed noscript as CDATA ns = html5lib.parseFragment( '
%s
' % (ns.text), treebuilder='lxml', namespaceHTMLElements=False)[0] @@ -1271,9 +1277,9 @@ class Amazon(Source): def create_query(self, log, title=None, authors=None, identifiers={}, # {{{ domain=None, for_amazon=True): try: - from urllib.parse import urlencode, unquote_plus + from urllib.parse import unquote_plus, urlencode except ImportError: - from urllib import urlencode, unquote_plus + from urllib import unquote_plus, urlencode if domain is None: domain = self.domain @@ -1442,8 +1448,8 @@ class Amazon(Source): # }}} def search_amazon(self, br, testing, log, abort, title, authors, identifiers, timeout): # {{{ - from calibre.utils.cleantext import clean_ascii_chars from calibre.ebooks.chardet import xml_to_unicode + from calibre.utils.cleantext import clean_ascii_chars matches = [] query, domain = self.create_query(log, title=title, authors=authors, identifiers=identifiers) @@ -1703,8 +1709,10 @@ class Amazon(Source): def manual_tests(domain, **kw): # {{{ # To run these test use: # calibre-debug -c "from calibre.ebooks.metadata.sources.amazon import *; manual_tests('com')" - from calibre.ebooks.metadata.sources.test import (test_identify_plugin, - isbn_test, title_test, authors_test, comments_test, series_test) + from calibre.ebooks.metadata.sources.test import ( + authors_test, comments_test, isbn_test, series_test, test_identify_plugin, + title_test, + ) all_tests = {} all_tests['com'] = [ # {{{ ( # Paperback with series diff --git a/src/calibre/ebooks/metadata/tag_mapper.py b/src/calibre/ebooks/metadata/tag_mapper.py index 198e20ae2b..4d41f1e616 100644 --- a/src/calibre/ebooks/metadata/tag_mapper.py +++ b/src/calibre/ebooks/metadata/tag_mapper.py @@ -4,6 +4,8 @@ from collections import deque +from calibre.utils.icu import lower as icu_lower, upper as icu_upper + def compile_pat(pat): import regex diff --git a/src/calibre/ebooks/metadata/worker.py b/src/calibre/ebooks/metadata/worker.py index 2e3de51942..4c9b939949 100644 --- a/src/calibre/ebooks/metadata/worker.py +++ b/src/calibre/ebooks/metadata/worker.py @@ -8,6 +8,7 @@ from calibre.customize.ui import run_plugins_on_import from calibre.ebooks.metadata.meta import metadata_from_formats from calibre.ebooks.metadata.opf2 import metadata_to_opf from calibre.utils.filenames import samefile +from calibre.utils.icu import lower as icu_lower def serialize_metadata_for(paths, tdir, group_id): diff --git a/src/calibre/ebooks/oeb/polish/css.py b/src/calibre/ebooks/oeb/polish/css.py index 386f962b23..8155eaeee5 100644 --- a/src/calibre/ebooks/oeb/polish/css.py +++ b/src/calibre/ebooks/oeb/polish/css.py @@ -6,18 +6,18 @@ __copyright__ = '2014, Kovid Goyal ' import re from collections import defaultdict +from css_parser.css import CSSRule, CSSStyleDeclaration from functools import partial from operator import itemgetter -from css_parser.css import CSSRule, CSSStyleDeclaration -from css_selectors import parse, SelectorSyntaxError - from calibre import force_unicode -from calibre.ebooks.oeb.base import OEB_STYLES, OEB_DOCS, XHTML, css_text +from calibre.ebooks.oeb.base import OEB_DOCS, OEB_STYLES, XHTML, css_text from calibre.ebooks.oeb.normalize_css import normalize_filter_css, normalizers -from calibre.ebooks.oeb.polish.pretty import pretty_script_or_style, pretty_xml_tree, serialize -from calibre.utils.icu import numeric_sort_key -from css_selectors import Select, SelectorError +from calibre.ebooks.oeb.polish.pretty import ( + pretty_script_or_style, pretty_xml_tree, serialize, +) +from calibre.utils.icu import lower as icu_lower, numeric_sort_key +from css_selectors import Select, SelectorError, SelectorSyntaxError, parse from polyglot.builtins import iteritems, itervalues from polyglot.functools import lru_cache diff --git a/src/calibre/ebooks/oeb/polish/embed.py b/src/calibre/ebooks/oeb/polish/embed.py index 443933bf7c..3904bd18d3 100644 --- a/src/calibre/ebooks/oeb/polish/embed.py +++ b/src/calibre/ebooks/oeb/polish/embed.py @@ -6,12 +6,12 @@ __copyright__ = '2013, Kovid Goyal ' __docformat__ = 'restructuredtext en' import sys - from lxml import etree from calibre import prints from calibre.ebooks.oeb.base import XHTML from calibre.utils.filenames import ascii_filename +from calibre.utils.icu import lower as icu_lower from polyglot.builtins import iteritems, itervalues, string_or_bytes props = {'font-family':None, 'font-weight':'normal', 'font-style':'normal', 'font-stretch':'normal'} @@ -163,7 +163,7 @@ def embed_font(container, font, all_font_rules, report, warned): if not isinstance(ff, string_or_bytes): ff = ff[0] if rule is None: - from calibre.utils.fonts.scanner import font_scanner, NoFonts + from calibre.utils.fonts.scanner import NoFonts, font_scanner if ff in warned: return try: diff --git a/src/calibre/ebooks/oeb/polish/stats.py b/src/calibre/ebooks/oeb/polish/stats.py index 67feeb3b65..91b302ecb2 100644 --- a/src/calibre/ebooks/oeb/polish/stats.py +++ b/src/calibre/ebooks/oeb/polish/stats.py @@ -5,15 +5,16 @@ __license__ = 'GPL v3' __copyright__ = '2013, Kovid Goyal ' __docformat__ = 'restructuredtext en' +import regex import sys from functools import partial - from lxml.etree import tostring -import regex from calibre.ebooks.oeb.base import XHTML, css_text -from calibre.ebooks.oeb.polish.cascade import iterrules, resolve_styles, iterdeclaration -from calibre.utils.icu import ord_string, safe_chr +from calibre.ebooks.oeb.polish.cascade import iterdeclaration, iterrules, resolve_styles +from calibre.utils.icu import ( + lower as icu_lower, ord_string, safe_chr, upper as icu_upper, +) from polyglot.builtins import iteritems, itervalues from tinycss.fonts3 import parse_font_family diff --git a/src/calibre/ebooks/oeb/polish/tests/cascade.py b/src/calibre/ebooks/oeb/polish/tests/cascade.py index fd2e07c104..ec47d9911b 100644 --- a/src/calibre/ebooks/oeb/polish/tests/cascade.py +++ b/src/calibre/ebooks/oeb/polish/tests/cascade.py @@ -4,18 +4,20 @@ __license__ = 'GPL v3' __copyright__ = '2016, Kovid Goyal ' +from css_parser import parseStyle from functools import partial -from css_parser import parseStyle - from calibre.constants import iswindows -from calibre.ebooks.oeb.base import OEB_STYLES, OEB_DOCS -from calibre.ebooks.oeb.polish.cascade import iterrules, resolve_styles, DEFAULTS +from calibre.ebooks.oeb.base import OEB_DOCS, OEB_STYLES +from calibre.ebooks.oeb.polish.cascade import DEFAULTS, iterrules, resolve_styles +from calibre.ebooks.oeb.polish.container import ContainerBase, href_to_name from calibre.ebooks.oeb.polish.css import remove_property_value from calibre.ebooks.oeb.polish.embed import find_matching_font -from calibre.ebooks.oeb.polish.container import ContainerBase, href_to_name -from calibre.ebooks.oeb.polish.stats import StatsCollector, font_keys, normalize_font_properties, prepare_font_rule +from calibre.ebooks.oeb.polish.stats import ( + StatsCollector, font_keys, normalize_font_properties, prepare_font_rule, +) from calibre.ebooks.oeb.polish.tests.base import BaseTest +from calibre.utils.icu import lower as icu_lower from calibre.utils.logging import Log, Stream from polyglot.builtins import iteritems diff --git a/src/calibre/ebooks/oeb/polish/utils.py b/src/calibre/ebooks/oeb/polish/utils.py index 955237ce07..afd5e6b6cf 100644 --- a/src/calibre/ebooks/oeb/polish/utils.py +++ b/src/calibre/ebooks/oeb/polish/utils.py @@ -8,6 +8,7 @@ import re, os from bisect import bisect from calibre import guess_type as _guess_type, replace_entities +from calibre.utils.icu import upper as icu_upper BLOCK_TAG_NAMES = frozenset(( @@ -248,6 +249,7 @@ def apply_func_to_match_groups(match, func=icu_upper, handle_entities=handle_ent found_groups = False i = 0 parts, pos = [], match.start() + def f(text): return handle_entities(text, func) while True: diff --git a/src/calibre/ebooks/oeb/transforms/manglecase.py b/src/calibre/ebooks/oeb/transforms/manglecase.py index 4b955663c5..835c1939d3 100644 --- a/src/calibre/ebooks/oeb/transforms/manglecase.py +++ b/src/calibre/ebooks/oeb/transforms/manglecase.py @@ -6,10 +6,10 @@ __license__ = 'GPL v3' __copyright__ = '2008, Marshall T. Vandegrift ' from lxml import etree -from calibre.ebooks.oeb.base import XHTML, XHTML_NS -from calibre.ebooks.oeb.base import CSS_MIME -from calibre.ebooks.oeb.base import namespace + +from calibre.ebooks.oeb.base import CSS_MIME, XHTML, XHTML_NS, namespace from calibre.ebooks.oeb.stylizer import Stylizer +from calibre.utils.icu import lower as icu_lower, upper as icu_upper from polyglot.builtins import string_or_bytes CASE_MANGLER_CSS = """ diff --git a/src/calibre/gui2/actions/similar_books.py b/src/calibre/gui2/actions/similar_books.py index cc248ba20e..cac3aa2fe6 100644 --- a/src/calibre/gui2/actions/similar_books.py +++ b/src/calibre/gui2/actions/similar_books.py @@ -9,6 +9,7 @@ __docformat__ = 'restructuredtext en' from qt.core import QToolButton from calibre.gui2.actions import InterfaceAction +from calibre.utils.icu import lower as icu_lower from polyglot.builtins import string_or_bytes diff --git a/src/calibre/gui2/add.py b/src/calibre/gui2/add.py index 9f0f1bbe4d..b91351c02b 100644 --- a/src/calibre/gui2/add.py +++ b/src/calibre/gui2/add.py @@ -31,6 +31,7 @@ from calibre.ptempfile import PersistentTemporaryDirectory from calibre.utils import join_with_timeout from calibre.utils.config import prefs from calibre.utils.filenames import make_long_path_useable +from calibre.utils.icu import lower as icu_lower from calibre.utils.ipc.pool import Failure, Pool from polyglot.builtins import iteritems, string_or_bytes from polyglot.queue import Empty diff --git a/src/calibre/gui2/author_mapper.py b/src/calibre/gui2/author_mapper.py index 1605793d4b..5d26d08a9c 100644 --- a/src/calibre/gui2/author_mapper.py +++ b/src/calibre/gui2/author_mapper.py @@ -10,7 +10,7 @@ from calibre.gui2 import Application, elided_text from calibre.gui2.tag_mapper import ( RuleEdit as RuleEditBase, RuleEditDialog as RuleEditDialogBase, RuleItem as RuleItemBase, Rules as RulesBase, RulesDialog as RulesDialogBase, - Tester as TesterBase + Tester as TesterBase, ) from calibre.utils.config import JSONConfig diff --git a/src/calibre/gui2/custom_column_widgets.py b/src/calibre/gui2/custom_column_widgets.py index 7969dbfe9d..243f30331e 100644 --- a/src/calibre/gui2/custom_column_widgets.py +++ b/src/calibre/gui2/custom_column_widgets.py @@ -8,24 +8,26 @@ __docformat__ = 'restructuredtext en' import os from collections import OrderedDict from functools import partial - -from qt.core import (Qt, QComboBox, QLabel, QSpinBox, QDoubleSpinBox, - QDateTime, QGroupBox, QVBoxLayout, QSizePolicy, QGridLayout, QUrl, - QSpacerItem, QIcon, QCheckBox, QWidget, QHBoxLayout, QLineEdit, - QMessageBox, QToolButton, QPlainTextEdit, QApplication, QStyle, QDialog) +from qt.core import ( + QApplication, QCheckBox, QComboBox, QDateTime, QDialog, QDoubleSpinBox, QGridLayout, + QGroupBox, QHBoxLayout, QIcon, QLabel, QLineEdit, QMessageBox, QPlainTextEdit, + QSizePolicy, QSpacerItem, QSpinBox, QStyle, Qt, QToolButton, QUrl, QVBoxLayout, + QWidget, +) from calibre.ebooks.metadata import title_sort -from calibre.utils.date import (qt_to_dt, now, as_local_time, as_utc, - internal_iso_format_string, is_date_undefined) -from calibre.gui2.complete2 import EditWithComplete as EWC +from calibre.gui2 import UNDEFINED_QDATETIME, elided_text, error_dialog, gprefs from calibre.gui2.comments_editor import Editor as CommentsEditor -from calibre.gui2 import UNDEFINED_QDATETIME, error_dialog, elided_text, gprefs +from calibre.gui2.complete2 import EditWithComplete as EWC from calibre.gui2.dialogs.tag_editor import TagEditor -from calibre.utils.config import tweaks -from calibre.utils.icu import sort_key -from calibre.library.comments import comments_to_html from calibre.gui2.library.delegates import ClearingDoubleSpinBox, ClearingSpinBox -from calibre.gui2.widgets2 import RatingEditor, DateTimeEdit as DateTimeEditBase +from calibre.gui2.widgets2 import DateTimeEdit as DateTimeEditBase, RatingEditor +from calibre.library.comments import comments_to_html +from calibre.utils.config import tweaks +from calibre.utils.date import ( + as_local_time, as_utc, internal_iso_format_string, is_date_undefined, now, qt_to_dt, +) +from calibre.utils.icu import lower as icu_lower, sort_key class EditWithComplete(EWC): diff --git a/src/calibre/gui2/device_drivers/mtp_folder_browser.py b/src/calibre/gui2/device_drivers/mtp_folder_browser.py index 3855b4f736..a852b6b83e 100644 --- a/src/calibre/gui2/device_drivers/mtp_folder_browser.py +++ b/src/calibre/gui2/device_drivers/mtp_folder_browser.py @@ -6,11 +6,13 @@ __copyright__ = '2012, Kovid Goyal ' __docformat__ = 'restructuredtext en' from operator import attrgetter - -from qt.core import (QTabWidget, QTreeWidget, QTreeWidgetItem, Qt, QDialog, - QDialogButtonBox, QVBoxLayout, QSize, pyqtSignal, QIcon, QLabel) +from qt.core import ( + QDialog, QDialogButtonBox, QIcon, QLabel, QSize, Qt, QTabWidget, QTreeWidget, + QTreeWidgetItem, QVBoxLayout, pyqtSignal, +) from calibre.gui2 import file_icon_provider +from calibre.utils.icu import lower as icu_lower def browser_item(f, parent): diff --git a/src/calibre/gui2/dialogs/authors_edit.py b/src/calibre/gui2/dialogs/authors_edit.py index 5777013d9a..2de105021c 100644 --- a/src/calibre/gui2/dialogs/authors_edit.py +++ b/src/calibre/gui2/dialogs/authors_edit.py @@ -5,15 +5,16 @@ __license__ = 'GPL v3' __copyright__ = '2013, Kovid Goyal ' from collections import OrderedDict - from qt.core import ( - QDialog, QGridLayout, QDialogButtonBox, QListWidget, QApplication, Qt, - pyqtSignal, QSize, QPushButton, QIcon, QStyledItemDelegate, QLabel, QAbstractItemView) + QAbstractItemView, QApplication, QDialog, QDialogButtonBox, QGridLayout, QIcon, + QLabel, QListWidget, QPushButton, QSize, QStyledItemDelegate, Qt, pyqtSignal, +) -from calibre.utils.config_base import tweaks +from calibre.ebooks.metadata import string_to_authors from calibre.gui2 import gprefs from calibre.gui2.complete2 import EditWithComplete -from calibre.ebooks.metadata import string_to_authors +from calibre.utils.config_base import tweaks +from calibre.utils.icu import lower as icu_lower class ItemDelegate(QStyledItemDelegate): diff --git a/src/calibre/gui2/dialogs/edit_authors_dialog.py b/src/calibre/gui2/dialogs/edit_authors_dialog.py index 69a0907150..7f3dfb657b 100644 --- a/src/calibre/gui2/dialogs/edit_authors_dialog.py +++ b/src/calibre/gui2/dialogs/edit_authors_dialog.py @@ -5,19 +5,22 @@ __copyright__ = '2008, Kovid Goyal kovid@kovidgoyal.net' __docformat__ = 'restructuredtext en' __license__ = 'GPL v3' -from functools import partial from contextlib import contextmanager - -from qt.core import (Qt, QDialog, QTableWidgetItem, QAbstractItemView, QIcon, - QDialogButtonBox, QFrame, QLabel, QTimer, QMenu, QApplication, - QItemDelegate, QAction) +from functools import partial +from qt.core import ( + QAbstractItemView, QAction, QApplication, QDialog, QDialogButtonBox, QFrame, QIcon, + QItemDelegate, QLabel, QMenu, Qt, QTableWidgetItem, QTimer, +) from calibre.ebooks.metadata import author_to_author_sort, string_to_authors from calibre.gui2 import error_dialog, gprefs from calibre.gui2.dialogs.edit_authors_dialog_ui import Ui_EditAuthorsDialog from calibre.utils.config import prefs from calibre.utils.config_base import tweaks -from calibre.utils.icu import sort_key, primary_contains, contains, primary_startswith +from calibre.utils.icu import ( + contains, lower as icu_lower, primary_contains, primary_startswith, sort_key, + upper as icu_upper, +) QT_HIDDEN_CLEAR_ACTION = '_q_qlineeditclearaction' diff --git a/src/calibre/gui2/dialogs/metadata_bulk.py b/src/calibre/gui2/dialogs/metadata_bulk.py index 2706c34906..1ff57fbd65 100644 --- a/src/calibre/gui2/dialogs/metadata_bulk.py +++ b/src/calibre/gui2/dialogs/metadata_bulk.py @@ -7,9 +7,9 @@ import regex from collections import defaultdict, namedtuple from io import BytesIO from qt.core import ( - QApplication, QComboBox, QCompleter, QDateTime, QDialog, - QDialogButtonBox, QFont, QGridLayout, QInputDialog, QLabel, QLineEdit, - QProgressBar, QSize, Qt, QVBoxLayout, pyqtSignal + QApplication, QComboBox, QCompleter, QDateTime, QDialog, QDialogButtonBox, QFont, + QGridLayout, QInputDialog, QLabel, QLineEdit, QProgressBar, QSize, Qt, QVBoxLayout, + pyqtSignal, ) from threading import Thread @@ -21,7 +21,7 @@ from calibre.ebooks.metadata.book.formatter import SafeFormat from calibre.ebooks.metadata.opf2 import OPF from calibre.gui2 import ( UNDEFINED_QDATETIME, FunctionDispatcher, error_dialog, gprefs, info_dialog, - question_dialog + question_dialog, ) from calibre.gui2.custom_column_widgets import populate_metadata_page from calibre.gui2.dialogs.metadata_bulk_ui import Ui_MetadataBulkDialog @@ -30,7 +30,9 @@ from calibre.gui2.dialogs.template_line_editor import TemplateLineEditor from calibre.gui2.widgets import LineEditECM from calibre.utils.config import JSONConfig, dynamic, prefs, tweaks from calibre.utils.date import internal_iso_format_string, qt_to_dt -from calibre.utils.icu import capitalize, sort_key +from calibre.utils.icu import ( + capitalize, lower as icu_lower, sort_key, upper as icu_upper, +) from calibre.utils.titlecase import titlecase from polyglot.builtins import error_message, iteritems, itervalues, native_string_type @@ -317,7 +319,7 @@ class MyBlockingBusy(QDialog): # {{{ elif args.cover_action == 'trim': self.progress_next_step_range.emit(len(self.ids)) from calibre.utils.img import ( - image_from_data, image_to_data, remove_borders_from_image + image_from_data, image_to_data, remove_borders_from_image, ) for book_id in self.ids: cdata = cache.cover(book_id) diff --git a/src/calibre/gui2/dialogs/plugin_updater.py b/src/calibre/gui2/dialogs/plugin_updater.py index 7bd8c75fad..0fd4658189 100644 --- a/src/calibre/gui2/dialogs/plugin_updater.py +++ b/src/calibre/gui2/dialogs/plugin_updater.py @@ -9,24 +9,25 @@ import datetime import re import traceback from qt.core import ( - QAbstractItemView, QAbstractTableModel, QAction, QBrush, QComboBox, - QDialog, QDialogButtonBox, QFont, QFrame, QHBoxLayout, QIcon, QLabel, QLineEdit, - QModelIndex, QSize, QSortFilterProxyModel, Qt, QTableView, QUrl, QVBoxLayout + QAbstractItemView, QAbstractTableModel, QAction, QBrush, QComboBox, QDialog, + QDialogButtonBox, QFont, QFrame, QHBoxLayout, QIcon, QLabel, QLineEdit, QModelIndex, + QSize, QSortFilterProxyModel, Qt, QTableView, QUrl, QVBoxLayout, ) from calibre import prints from calibre.constants import ( - DEBUG, __appname__, __version__, ismacos, iswindows, numeric_version + DEBUG, __appname__, __version__, ismacos, iswindows, numeric_version, ) from calibre.customize import PluginInstallationType from calibre.customize.ui import ( NameConflict, add_plugin, disable_plugin, enable_plugin, has_external_plugins, - initialized_plugins, is_disabled, remove_plugin + initialized_plugins, is_disabled, remove_plugin, ) from calibre.gui2 import error_dialog, gprefs, info_dialog, open_url, question_dialog from calibre.gui2.preferences.plugins import ConfigWidget from calibre.utils.date import UNDEFINED_DATE, format_date from calibre.utils.https import get_https_resource_securely +from calibre.utils.icu import lower as icu_lower from polyglot.builtins import itervalues SERVER = 'https://code.calibre-ebook.com/plugins/' diff --git a/src/calibre/gui2/dialogs/saved_search_editor.py b/src/calibre/gui2/dialogs/saved_search_editor.py index 20deb7072c..1a8b83274c 100644 --- a/src/calibre/gui2/dialogs/saved_search_editor.py +++ b/src/calibre/gui2/dialogs/saved_search_editor.py @@ -3,15 +3,15 @@ from qt.core import ( - QFormLayout, QIcon, QLabel, QLineEdit, QListWidget, Qt, QVBoxLayout, QDialog, - QDialogButtonBox, QPlainTextEdit + QDialog, QDialogButtonBox, QFormLayout, QIcon, QLabel, QLineEdit, QListWidget, + QPlainTextEdit, Qt, QVBoxLayout, ) from calibre import prepare_string_for_xml from calibre.gui2 import error_dialog from calibre.gui2.dialogs.confirm_delete import confirm from calibre.gui2.widgets2 import Dialog -from calibre.utils.icu import sort_key +from calibre.utils.icu import lower as icu_lower, sort_key def commit_searches(searches): diff --git a/src/calibre/gui2/dialogs/tag_categories.py b/src/calibre/gui2/dialogs/tag_categories.py index 090421f94d..9df414d4c8 100644 --- a/src/calibre/gui2/dialogs/tag_categories.py +++ b/src/calibre/gui2/dialogs/tag_categories.py @@ -1,15 +1,16 @@ __license__ = 'GPL v3' __copyright__ = '2008, Kovid Goyal ' -from qt.core import (Qt, QApplication, QDialog, QIcon, QListWidgetItem) - from collections import namedtuple +from qt.core import QApplication, QDialog, QIcon, QListWidgetItem, Qt from calibre.constants import islinux from calibre.gui2 import error_dialog, warning_dialog from calibre.gui2.dialogs.confirm_delete import confirm from calibre.gui2.dialogs.tag_categories_ui import Ui_TagCategories -from calibre.utils.icu import primary_sort_key, strcmp, primary_contains +from calibre.utils.icu import ( + lower as icu_lower, primary_contains, primary_sort_key, strcmp, +) class TagCategories(QDialog, Ui_TagCategories): diff --git a/src/calibre/gui2/dialogs/tag_list_editor.py b/src/calibre/gui2/dialogs/tag_list_editor.py index be790b809b..a452b57391 100644 --- a/src/calibre/gui2/dialogs/tag_list_editor.py +++ b/src/calibre/gui2/dialogs/tag_list_editor.py @@ -3,19 +3,23 @@ from functools import partial +from qt.core import ( + QAbstractItemView, QAction, QApplication, QColor, QDialog, QDialogButtonBox, QFrame, + QIcon, QItemDelegate, QLabel, QMenu, QSize, Qt, QTableWidgetItem, QTimer, + pyqtSignal, +) -from qt.core import (Qt, QDialog, QTableWidgetItem, QIcon, QSize, QAbstractItemView, - QDialogButtonBox, QItemDelegate, QApplication, - pyqtSignal, QAction, QFrame, QLabel, QTimer, QMenu, QColor) - +from calibre.gui2 import error_dialog, gprefs, question_dialog from calibre.gui2.actions.show_quickview import get_quickview_action_plugin from calibre.gui2.complete2 import EditWithComplete -from calibre.gui2.dialogs.tag_list_editor_ui import Ui_TagListEditor from calibre.gui2.dialogs.confirm_delete import confirm +from calibre.gui2.dialogs.tag_list_editor_ui import Ui_TagListEditor from calibre.gui2.widgets import EnLineEdit -from calibre.gui2 import question_dialog, error_dialog, gprefs from calibre.utils.config import prefs -from calibre.utils.icu import contains, primary_contains, primary_startswith, capitalize +from calibre.utils.icu import ( + capitalize, contains, lower as icu_lower, primary_contains, primary_startswith, + upper as icu_upper, +) from calibre.utils.titlecase import titlecase QT_HIDDEN_CLEAR_ACTION = '_q_qlineeditclearaction' diff --git a/src/calibre/gui2/dialogs/template_dialog.py b/src/calibre/gui2/dialogs/template_dialog.py index 22086c705f..5077bb980f 100644 --- a/src/calibre/gui2/dialogs/template_dialog.py +++ b/src/calibre/gui2/dialogs/template_dialog.py @@ -32,7 +32,7 @@ from calibre.utils.config_base import tweaks from calibre.utils.date import DEFAULT_DATE from calibre.utils.formatter import PythonTemplateContext, StopException from calibre.utils.formatter_functions import StoredObjectType, formatter_functions -from calibre.utils.icu import sort_key +from calibre.utils.icu import lower as icu_lower, sort_key from calibre.utils.localization import localize_user_manual_link from calibre.utils.resources import get_path as P diff --git a/src/calibre/gui2/font_family_chooser.py b/src/calibre/gui2/font_family_chooser.py index 5de96c6e6a..338828d9b7 100644 --- a/src/calibre/gui2/font_family_chooser.py +++ b/src/calibre/gui2/font_family_chooser.py @@ -8,14 +8,15 @@ __docformat__ = 'restructuredtext en' import os import shutil from qt.core import ( - QAbstractItemView, QDialog, QDialogButtonBox, QFont, QFontComboBox, - QFontDatabase, QFontInfo, QFontMetrics, QGridLayout, QHBoxLayout, QIcon, QLabel, - QLineEdit, QListView, QPen, QPushButton, QSize, QSizePolicy, QStringListModel, - QStyle, QStyledItemDelegate, Qt, QToolButton, QVBoxLayout, QWidget, pyqtSignal + QAbstractItemView, QDialog, QDialogButtonBox, QFont, QFontComboBox, QFontDatabase, + QFontInfo, QFontMetrics, QGridLayout, QHBoxLayout, QIcon, QLabel, QLineEdit, + QListView, QPen, QPushButton, QSize, QSizePolicy, QStringListModel, QStyle, + QStyledItemDelegate, Qt, QToolButton, QVBoxLayout, QWidget, pyqtSignal, ) from calibre.constants import config_dir from calibre.gui2 import choose_files, empty_index, error_dialog, info_dialog +from calibre.utils.icu import lower as icu_lower def add_fonts(parent): diff --git a/src/calibre/gui2/metadata/diff.py b/src/calibre/gui2/metadata/diff.py index c59ddeeee4..e12e283b5e 100644 --- a/src/calibre/gui2/metadata/diff.py +++ b/src/calibre/gui2/metadata/diff.py @@ -12,7 +12,7 @@ from qt.core import ( QAction, QApplication, QCheckBox, QColor, QDialog, QDialogButtonBox, QFont, QGridLayout, QHBoxLayout, QIcon, QKeySequence, QLabel, QMenu, QPainter, QPen, QPixmap, QScrollArea, QSize, QSizePolicy, QStackedLayout, Qt, QToolButton, - QVBoxLayout, QWidget, pyqtSignal + QVBoxLayout, QWidget, pyqtSignal, ) from calibre import fit_image @@ -26,6 +26,7 @@ from calibre.gui2.metadata.basic_widgets import PubdateEdit, RatingEdit from calibre.gui2.widgets2 import RightClickButton from calibre.ptempfile import PersistentTemporaryFile from calibre.utils.date import UNDEFINED_DATE +from calibre.utils.icu import lower as icu_lower from polyglot.builtins import iteritems, itervalues Widgets = namedtuple('Widgets', 'new old label button') @@ -783,6 +784,7 @@ if __name__ == '__main__': ids = sorted(db.all_ids(), reverse=True) ids = tuple(zip(ids[0::2], ids[1::2])) gm = partial(db.get_metadata, index_is_id=True, get_cover=True, cover_as_data=True) + def get_metadata(x): return list(map(gm, ids[x])) d = CompareMany(list(range(len(ids))), get_metadata, db.field_metadata, db=db) diff --git a/src/calibre/gui2/preferences/search.py b/src/calibre/gui2/preferences/search.py index 13faccb23f..d0264dfd2c 100644 --- a/src/calibre/gui2/preferences/search.py +++ b/src/calibre/gui2/preferences/search.py @@ -8,13 +8,14 @@ __docformat__ = 'restructuredtext en' from qt.core import QApplication, QTimer from calibre.db.categories import find_categories -from calibre.gui2.preferences import ConfigWidgetBase, test_widget, \ - CommaSeparatedList, AbortCommit -from calibre.gui2.preferences.search_ui import Ui_Form from calibre.gui2 import config, error_dialog, gprefs -from calibre.utils.config import prefs -from calibre.utils.icu import sort_key +from calibre.gui2.preferences import ( + AbortCommit, CommaSeparatedList, ConfigWidgetBase, test_widget, +) +from calibre.gui2.preferences.search_ui import Ui_Form from calibre.library.caches import set_use_primary_find_in_search +from calibre.utils.config import prefs +from calibre.utils.icu import lower as icu_lower, sort_key from polyglot.builtins import iteritems diff --git a/src/calibre/gui2/store/search/models.py b/src/calibre/gui2/store/search/models.py index ed63c66e27..9e14375134 100644 --- a/src/calibre/gui2/store/search/models.py +++ b/src/calibre/gui2/store/search/models.py @@ -2,18 +2,19 @@ __license__ = 'GPL 3' __copyright__ = '2011, John Schember ' __docformat__ = 'restructuredtext en' -import re, string +import re +import string from operator import attrgetter - -from qt.core import (Qt, QAbstractItemModel, QPixmap, QModelIndex, QSize, - pyqtSignal, QIcon, QApplication) +from qt.core import ( + QAbstractItemModel, QApplication, QIcon, QModelIndex, QPixmap, QSize, Qt, + pyqtSignal, +) from calibre import force_unicode from calibre.gui2 import FunctionDispatcher +from calibre.gui2.store.search.download_thread import CoverThreadPool, DetailsThreadPool from calibre.gui2.store.search_result import SearchResult -from calibre.gui2.store.search.download_thread import DetailsThreadPool, \ - CoverThreadPool -from calibre.utils.icu import sort_key +from calibre.utils.icu import lower as icu_lower, sort_key from calibre.utils.localization import pgettext from calibre.utils.search_query_parser import SearchQueryParser diff --git a/src/calibre/gui2/tag_browser/model.py b/src/calibre/gui2/tag_browser/model.py index c16cb0988d..34b20627af 100644 --- a/src/calibre/gui2/tag_browser/model.py +++ b/src/calibre/gui2/tag_browser/model.py @@ -10,21 +10,22 @@ import os import traceback from collections import OrderedDict, namedtuple from qt.core import ( - QAbstractItemModel, QFont, QIcon, QMimeData, QModelIndex, QObject, Qt, - pyqtSignal + QAbstractItemModel, QFont, QIcon, QMimeData, QModelIndex, QObject, Qt, pyqtSignal, ) from calibre.constants import config_dir from calibre.db.categories import Tag, category_display_order from calibre.ebooks.metadata import rating_to_stars -from calibre.gui2 import config, error_dialog, file_icon_provider, gprefs, question_dialog +from calibre.gui2 import ( + config, error_dialog, file_icon_provider, gprefs, question_dialog, +) from calibre.gui2.dialogs.confirm_delete import confirm from calibre.library.field_metadata import category_icon_map from calibre.utils.config import prefs, tweaks from calibre.utils.formatter import EvalFormatter from calibre.utils.icu import ( - contains, lower, primary_contains, primary_strcmp, sort_key, - strcmp, collation_order_for_partitioning + collation_order_for_partitioning, contains, lower, lower as icu_lower, + primary_contains, primary_strcmp, sort_key, strcmp, upper as icu_upper, ) from calibre.utils.serialize import json_dumps, json_loads from polyglot.builtins import iteritems, itervalues diff --git a/src/calibre/gui2/tag_mapper.py b/src/calibre/gui2/tag_mapper.py index a4266e93fa..0f11a3fd03 100644 --- a/src/calibre/gui2/tag_mapper.py +++ b/src/calibre/gui2/tag_mapper.py @@ -6,9 +6,9 @@ import textwrap from collections import OrderedDict from qt.core import ( QAbstractItemView, QComboBox, QDialog, QDialogButtonBox, QHBoxLayout, QIcon, - QInputDialog, QItemSelectionModel, QLabel, QLineEdit, QListWidget, - QListWidgetItem, QMenu, QPalette, QPushButton, QSize, QStaticText, QStyle, - QStyledItemDelegate, Qt, QToolButton, QVBoxLayout, QWidget, pyqtSignal + QInputDialog, QItemSelectionModel, QLabel, QLineEdit, QListWidget, QListWidgetItem, + QMenu, QPalette, QPushButton, QSize, QStaticText, QStyle, QStyledItemDelegate, Qt, + QToolButton, QVBoxLayout, QWidget, pyqtSignal, ) from calibre.ebooks.metadata.tag_mapper import compile_pat, map_tags diff --git a/src/calibre/gui2/toc/main.py b/src/calibre/gui2/toc/main.py index 5111a36399..50f1e6565b 100644 --- a/src/calibre/gui2/toc/main.py +++ b/src/calibre/gui2/toc/main.py @@ -8,11 +8,10 @@ import tempfile import textwrap from functools import partial from qt.core import ( - QAbstractItemView, QCheckBox, QCursor, QDialog, QDialogButtonBox, - QEvent, QFrame, QGridLayout, QIcon, QInputDialog, QItemSelectionModel, - QKeySequence, QLabel, QMenu, QPushButton, QScrollArea, QSize, QSizePolicy, - QStackedWidget, Qt, QToolButton, QTreeWidget, QTreeWidgetItem, QVBoxLayout, - QWidget, pyqtSignal + QAbstractItemView, QCheckBox, QCursor, QDialog, QDialogButtonBox, QEvent, QFrame, + QGridLayout, QIcon, QInputDialog, QItemSelectionModel, QKeySequence, QLabel, QMenu, + QPushButton, QScrollArea, QSize, QSizePolicy, QStackedWidget, Qt, QToolButton, + QTreeWidget, QTreeWidgetItem, QVBoxLayout, QWidget, pyqtSignal, ) from threading import Thread from time import monotonic @@ -20,17 +19,16 @@ from time import monotonic from calibre.constants import TOC_DIALOG_APP_UID, islinux, iswindows from calibre.ebooks.oeb.polish.container import AZW3Container, get_container from calibre.ebooks.oeb.polish.toc import ( - TOC, add_id, commit_toc, from_files, from_links, from_xpaths, get_toc -) -from calibre.gui2 import ( - Application, error_dialog, info_dialog, set_app_uid + TOC, add_id, commit_toc, from_files, from_links, from_xpaths, get_toc, ) +from calibre.gui2 import Application, error_dialog, info_dialog, set_app_uid from calibre.gui2.convert.xpath_wizard import XPathEdit from calibre.gui2.progress_indicator import ProgressIndicator from calibre.gui2.toc.location import ItemEdit from calibre.ptempfile import reset_base_dir from calibre.utils.config import JSONConfig from calibre.utils.filenames import atomic_rename +from calibre.utils.icu import lower as icu_lower, upper as icu_upper from calibre.utils.logging import GUILog ICON_SIZE = 24 @@ -1166,6 +1164,7 @@ class TOCEditor(QDialog): # {{{ def main(shm_name=None): import json import struct + from calibre.utils.shm import SharedMemory # Ensure we can continue to function if GUI is closed diff --git a/src/calibre/gui2/tweak_book/manage_fonts.py b/src/calibre/gui2/tweak_book/manage_fonts.py index a6ee741f84..14cfaaa032 100644 --- a/src/calibre/gui2/tweak_book/manage_fonts.py +++ b/src/calibre/gui2/tweak_book/manage_fonts.py @@ -4,23 +4,24 @@ __license__ = 'GPL v3' __copyright__ = '2014, Kovid Goyal ' -import sys, textwrap +import sys +import textwrap from io import BytesIO - from qt.core import ( - QSplitter, QVBoxLayout, QTableView, QWidget, QLabel, QAbstractTableModel, - Qt, QTimer, QPushButton, pyqtSignal, QFormLayout, QLineEdit, QIcon, QSize, - QHBoxLayout, QTextEdit, QApplication, QMessageBox, QAbstractItemView, QDialog, QDialogButtonBox) + QAbstractItemView, QAbstractTableModel, QApplication, QDialog, QDialogButtonBox, + QFormLayout, QHBoxLayout, QIcon, QLabel, QLineEdit, QMessageBox, QPushButton, QSize, + QSplitter, Qt, QTableView, QTextEdit, QTimer, QVBoxLayout, QWidget, pyqtSignal, +) from calibre.ebooks.oeb.polish.container import get_container -from calibre.ebooks.oeb.polish.fonts import font_family_data, change_font +from calibre.ebooks.oeb.polish.fonts import change_font, font_family_data from calibre.gui2 import error_dialog, info_dialog from calibre.gui2.tweak_book import current_container, set_current_container from calibre.gui2.tweak_book.widgets import Dialog from calibre.gui2.widgets import BusyCursor -from calibre.utils.icu import primary_sort_key as sort_key -from calibre.utils.fonts.scanner import font_scanner, NoFonts from calibre.utils.fonts.metadata import FontMetadata, UnsupportedFont +from calibre.utils.fonts.scanner import NoFonts, font_scanner +from calibre.utils.icu import lower as icu_lower, primary_sort_key as sort_key from polyglot.builtins import iteritems diff --git a/src/calibre/library/caches.py b/src/calibre/library/caches.py index 197cc736f8..efc3994a1d 100644 --- a/src/calibre/library/caches.py +++ b/src/calibre/library/caches.py @@ -5,22 +5,24 @@ __license__ = 'GPL v3' __copyright__ = '2010, Kovid Goyal ' __docformat__ = 'restructuredtext en' -import time, traceback, locale -from itertools import repeat -from datetime import timedelta -from threading import Thread +import locale +import time +import traceback from contextlib import suppress +from datetime import timedelta +from itertools import repeat +from threading import Thread -from calibre.utils.config import tweaks, prefs -from calibre.utils.date import parse_date, now, UNDEFINED_DATE, clean_date_for_sort -from calibre.utils.search_query_parser import SearchQueryParser -from calibre.utils.search_query_parser import ParseException -from calibre.utils.localization import (canonicalize_lang, lang_map, get_udc) +from calibre import force_unicode, prints from calibre.db.search import CONTAINS_MATCH, EQUALS_MATCH, REGEXP_MATCH, _match -from calibre.ebooks.metadata import title_sort, author_to_author_sort +from calibre.ebooks.metadata import author_to_author_sort, title_sort from calibre.ebooks.metadata.opf2 import metadata_to_opf -from calibre import prints, force_unicode -from polyglot.builtins import iteritems, itervalues, string_or_bytes, cmp +from calibre.utils.config import prefs, tweaks +from calibre.utils.date import UNDEFINED_DATE, clean_date_for_sort, now, parse_date +from calibre.utils.icu import lower as icu_lower +from calibre.utils.localization import canonicalize_lang, get_udc, lang_map +from calibre.utils.search_query_parser import ParseException, SearchQueryParser +from polyglot.builtins import cmp, iteritems, itervalues, string_or_bytes class MetadataBackup(Thread): # {{{ @@ -437,6 +439,7 @@ class ResultCache(SearchQueryParser): # {{{ if val_func is None: loc = self.field_metadata[location]['rec_index'] + def val_func(item, loc=loc): return item[loc] q = '' @@ -472,6 +475,7 @@ class ResultCache(SearchQueryParser): # {{{ elif dt == 'rating': def cast(x): return (0 if x is None else int(x)) + def adjust(x): return (x // 2) elif dt in ('float', 'composite'): diff --git a/src/calibre/library/catalogs/epub_mobi_builder.py b/src/calibre/library/catalogs/epub_mobi_builder.py index cabe14deab..79a6964821 100644 --- a/src/calibre/library/catalogs/epub_mobi_builder.py +++ b/src/calibre/library/catalogs/epub_mobi_builder.py @@ -35,7 +35,7 @@ from calibre.utils.date import ( ) from calibre.utils.filenames import ascii_text, shorten_components_to from calibre.utils.formatter import TemplateFormatter -from calibre.utils.icu import capitalize, collation_order, sort_key +from calibre.utils.icu import capitalize, collation_order, sort_key, upper as icu_upper from calibre.utils.localization import get_lang, lang_as_iso639_1 from calibre.utils.resources import get_image_path as I, get_path as P from calibre.utils.xml_parse import safe_xml_fromstring diff --git a/src/calibre/library/database2.py b/src/calibre/library/database2.py index 268258a21a..3ea0ecb429 100644 --- a/src/calibre/library/database2.py +++ b/src/calibre/library/database2.py @@ -58,7 +58,7 @@ from calibre.utils.filenames import ( WindowsAtomicFolderMove, ascii_filename, hardlink_file, samefile, ) from calibre.utils.formatter_functions import load_user_template_functions -from calibre.utils.icu import lower, sort_key, strcmp +from calibre.utils.icu import lower, lower as icu_lower, sort_key, strcmp from calibre.utils.img import save_cover_data_to from calibre.utils.localization import calibre_langcode_to_name, canonicalize_lang from calibre.utils.recycle_bin import delete_file, delete_tree diff --git a/src/calibre/library/field_metadata.py b/src/calibre/library/field_metadata.py index be54e3f652..f1efea9a9f 100644 --- a/src/calibre/library/field_metadata.py +++ b/src/calibre/library/field_metadata.py @@ -8,6 +8,7 @@ import traceback from collections import OrderedDict from calibre.utils.config_base import tweaks +from calibre.utils.icu import lower as icu_lower from polyglot.builtins import iteritems, itervalues category_icon_map = { diff --git a/src/calibre/srv/metadata.py b/src/calibre/srv/metadata.py index 6960b89d8f..8f3dabb16a 100644 --- a/src/calibre/srv/metadata.py +++ b/src/calibre/srv/metadata.py @@ -3,8 +3,8 @@ import os -from copy import copy from collections import namedtuple +from copy import copy from datetime import datetime, time from functools import partial from threading import Lock @@ -12,14 +12,14 @@ from threading import Lock from calibre.constants import config_dir from calibre.db.categories import Tag, category_display_order from calibre.ebooks.metadata.sources.identify import urls_from_identifiers -from calibre.utils.date import isoformat, UNDEFINED_DATE, local_tz -from calibre.utils.config import tweaks -from calibre.utils.formatter import EvalFormatter -from calibre.utils.file_type_icons import EXT_MAP -from calibre.utils.icu import collation_order_for_partitioning -from calibre.utils.localization import calibre_langcode_to_name from calibre.library.comments import comments_to_html, markdown from calibre.library.field_metadata import category_icon_map +from calibre.utils.config import tweaks +from calibre.utils.date import UNDEFINED_DATE, isoformat, local_tz +from calibre.utils.file_type_icons import EXT_MAP +from calibre.utils.formatter import EvalFormatter +from calibre.utils.icu import collation_order_for_partitioning, upper as icu_upper +from calibre.utils.localization import calibre_langcode_to_name from polyglot.builtins import iteritems, itervalues from polyglot.urllib import quote diff --git a/src/calibre/utils/fonts/scanner.py b/src/calibre/utils/fonts/scanner.py index d3b2983308..c1985250e2 100644 --- a/src/calibre/utils/fonts/scanner.py +++ b/src/calibre/utils/fonts/scanner.py @@ -14,7 +14,7 @@ from calibre.constants import ( DEBUG, config_dir, filesystem_encoding, ismacos, iswindows, isworker, ) from calibre.utils.fonts.metadata import FontMetadata, UnsupportedFont -from calibre.utils.icu import sort_key +from calibre.utils.icu import lower as icu_lower, sort_key from calibre.utils.resources import get_path as P from polyglot.builtins import itervalues diff --git a/src/calibre/utils/formatter_functions.py b/src/calibre/utils/formatter_functions.py index ed7c86b086..30540ca2d4 100644 --- a/src/calibre/utils/formatter_functions.py +++ b/src/calibre/utils/formatter_functions.py @@ -26,7 +26,7 @@ from calibre.constants import DEBUG from calibre.ebooks.metadata import title_sort from calibre.utils.config import tweaks from calibre.utils.date import UNDEFINED_DATE, format_date, now, parse_date -from calibre.utils.icu import capitalize, sort_key, strcmp +from calibre.utils.icu import capitalize, lower as icu_lower, sort_key, strcmp from calibre.utils.localization import _, calibre_langcode_to_name, canonicalize_lang from calibre.utils.titlecase import titlecase from polyglot.builtins import iteritems, itervalues diff --git a/src/calibre/utils/icu.py b/src/calibre/utils/icu.py index 6ee1c4ed8a..596adfee46 100644 --- a/src/calibre/utils/icu.py +++ b/src/calibre/utils/icu.py @@ -287,7 +287,7 @@ def partition_by_first_letter(items, reverse=False, key=lambda x:x): ans = OrderedDict() last_c, last_ordnum = ' ', 0 for item in items: - c = icu_upper(key(item) or ' ') + c = upper(key(item) or ' ') ordnum, ordlen = collation_order(c) if last_ordnum != ordnum: last_c = c[0:1] diff --git a/src/calibre/utils/matcher.py b/src/calibre/utils/matcher.py index 07f1c799d0..aac31436e0 100644 --- a/src/calibre/utils/matcher.py +++ b/src/calibre/utils/matcher.py @@ -4,17 +4,22 @@ __license__ = 'GPL v3' __copyright__ = '2014, Kovid Goyal ' -import atexit, os, sys -from math import ceil -from unicodedata import normalize -from threading import Thread, Lock -from operator import itemgetter +import atexit +import os +import sys from collections import OrderedDict from itertools import islice +from math import ceil +from operator import itemgetter +from threading import Lock, Thread +from unicodedata import normalize -from calibre import detect_ncpus as cpu_count, as_unicode +from calibre import as_unicode, detect_ncpus as cpu_count from calibre.constants import filesystem_encoding -from calibre.utils.icu import primary_sort_key, primary_find, primary_collator +from calibre.utils.icu import ( + lower as icu_lower, primary_collator, primary_find, primary_sort_key, + upper as icu_upper, +) from polyglot.builtins import iteritems, itervalues from polyglot.queue import Queue @@ -275,6 +280,7 @@ def test(return_tests=False): @unittest.skipIf(is_sanitized, 'Sanitizer enabled can\'t check for leaks') def test_mem_leaks(self): import gc + from calibre.utils.mem import get_memory as memory m = Matcher(['a'], scorer=CScorer) m('a')