From aaa749933d16a57b06309f01ef33962a866e3cc1 Mon Sep 17 00:00:00 2001 From: Ozzie Isaacs Date: Tue, 26 Apr 2022 14:55:00 +0200 Subject: [PATCH] Further migration to flask_babel Bugfix sort order Bugfix tasklist --- cps/admin.py | 2 +- cps/babel.py | 3 +-- cps/db.py | 2 +- cps/jinjia.py | 9 +++++---- cps/search.py | 13 +++++-------- cps/search_metadata.py | 8 ++++---- cps/tasks_status.py | 23 +++++++++++++++++------ cps/web.py | 12 ++++++------ optional-requirements.txt | 4 ++-- 9 files changed, 42 insertions(+), 34 deletions(-) diff --git a/cps/admin.py b/cps/admin.py index f5ae1037..91a16126 100644 --- a/cps/admin.py +++ b/cps/admin.py @@ -200,7 +200,7 @@ def admin(): form_date -= timedelta(hours=int(commit[20:22]), minutes=int(commit[23:])) elif commit[19] == '-': form_date += timedelta(hours=int(commit[20:22]), minutes=int(commit[23:])) - commit = format_datetime(form_date - tz, format='short', locale=locale) + commit = format_datetime(form_date - tz, format='short') else: commit = version['version'] diff --git a/cps/babel.py b/cps/babel.py index c1675809..f5ecaf5a 100644 --- a/cps/babel.py +++ b/cps/babel.py @@ -1,6 +1,5 @@ -from babel import Locale from babel import negotiate_locale -from flask_babel import Babel +from flask_babel import Babel, Locale from babel.core import UnknownLocaleError from flask import request, g diff --git a/cps/db.py b/cps/db.py index f28baeca..21104622 100644 --- a/cps/db.py +++ b/cps/db.py @@ -919,7 +919,7 @@ class CalibreDB: .count()) if no_lang_count: tags.append([Category(_("None"), "none"), no_lang_count]) - return sorted(tags, key=lambda x: x[0].name, reverse=reverse_order) + return sorted(tags, key=lambda x: x[0].name.lower(), reverse=reverse_order) else: if not languages: languages = self.session.query(Languages) \ diff --git a/cps/jinjia.py b/cps/jinjia.py index f88b36a2..e42c650c 100644 --- a/cps/jinjia.py +++ b/cps/jinjia.py @@ -22,15 +22,16 @@ # custom jinja filters +from markupsafe import escape import datetime import mimetypes from uuid import uuid4 -from babel.dates import format_date +# from babel.dates import format_date from flask import Blueprint, request, url_for -from flask_babel import get_locale +from flask_babel import format_date from flask_login import current_user -from markupsafe import escape + from . import constants, logger jinjia = Blueprint('jinjia', __name__) @@ -76,7 +77,7 @@ def mimetype_filter(val): @jinjia.app_template_filter('formatdate') def formatdate_filter(val): try: - return format_date(val, format='medium', locale=get_locale()) + return format_date(val, format='medium') except AttributeError as e: log.error('Babel error: %s, Current user locale: %s, Current User: %s', e, current_user.locale, diff --git a/cps/search.py b/cps/search.py index cd172b6b..602881bf 100644 --- a/cps/search.py +++ b/cps/search.py @@ -20,7 +20,7 @@ from datetime import datetime from flask import Blueprint, request, redirect, url_for, flash from flask import session as flask_session from flask_login import current_user -from flask_babel import get_locale, format_date +from flask_babel import format_date from flask_babel import gettext as _ from sqlalchemy.sql.expression import func, not_, and_, or_, text from sqlalchemy.sql.functions import coalesce @@ -193,14 +193,14 @@ def extend_search_term(searchterm, try: searchterm.extend([_(u"Published after ") + format_date(datetime.strptime(pub_start, "%Y-%m-%d"), - format='medium', locale=get_locale())]) + format='medium')]) except ValueError: pub_start = u"" if pub_end: try: searchterm.extend([_(u"Published before ") + format_date(datetime.strptime(pub_end, "%Y-%m-%d"), - format='medium', locale=get_locale())]) + format='medium')]) except ValueError: pub_end = u"" elements = {'tag': db.Tags, 'serie':db.Series, 'shelf':ub.Shelf} @@ -291,22 +291,19 @@ def render_adv_search_results(term, offset=None, order=None, limit=None): if column_start: search_term.extend([u"{} >= {}".format(c.name, format_date(datetime.strptime(column_start, "%Y-%m-%d").date(), - format='medium', - locale=get_locale()) + format='medium') )]) cc_present = True if column_end: search_term.extend([u"{} <= {}".format(c.name, format_date(datetime.strptime(column_end, "%Y-%m-%d").date(), - format='medium', - locale=get_locale()) + format='medium') )]) cc_present = True elif term.get('custom_column_' + str(c.id)): search_term.extend([(u"{}: {}".format(c.name, term.get('custom_column_' + str(c.id))))]) cc_present = True - if any(tags.values()) or author_name or book_title or publisher or pub_start or pub_end or rating_low \ or rating_high or description or cc_present or read_status: search_term, pub_start, pub_end = extend_search_term(search_term, diff --git a/cps/search_metadata.py b/cps/search_metadata.py index ae95a28e..e018da32 100644 --- a/cps/search_metadata.py +++ b/cps/search_metadata.py @@ -22,7 +22,6 @@ import inspect import json import os import sys -from dataclasses import asdict from flask import Blueprint, Response, request, url_for from flask_login import current_user @@ -57,9 +56,10 @@ for f in modules: try: importlib.import_module("cps.metadata_provider." + a) new_list.append(a) - except (ImportError, IndentationError, SyntaxError) as e: - log.error("Import error for metadata source: {} - {}".format(a, e)) - pass + except (IndentationError, SyntaxError) as e: + log.error("Syntax error for metadata source: {} - {}".format(a, e)) + except ImportError as e: + log.debug("Import error for metadata source: {} - {}".format(a, e)) def list_classes(provider_list): diff --git a/cps/tasks_status.py b/cps/tasks_status.py index e355ed85..e5f91975 100644 --- a/cps/tasks_status.py +++ b/cps/tasks_status.py @@ -19,12 +19,13 @@ from markupsafe import escape from flask import Blueprint, jsonify from flask_login import login_required, current_user from flask_babel import gettext as _ -from flask_babel import get_locale, format_datetime +from flask_babel import format_datetime from babel.units import format_unit from . import logger from .render_template import render_title_template -from .services.worker import WorkerThread, STAT_WAITING, STAT_FAIL, STAT_STARTED, STAT_FINISH_SUCCESS +from .services.worker import WorkerThread, STAT_WAITING, STAT_FAIL, STAT_STARTED, STAT_FINISH_SUCCESS, STAT_ENDED, \ + STAT_CANCELLED tasks = Blueprint('tasks', __name__) @@ -50,11 +51,11 @@ def get_tasks_status(): # helper function to apply localize status information in tasklist entries def render_task_status(tasklist): rendered_tasklist = list() - for __, user, __, task in tasklist: + for __, user, __, task, __ in tasklist: if user == current_user.name or current_user.role_admin(): ret = {} if task.start_time: - ret['starttime'] = format_datetime(task.start_time, format='short', locale=get_locale()) + ret['starttime'] = format_datetime(task.start_time, format='short') ret['runtime'] = format_runtime(task.runtime) # localize the task status @@ -67,12 +68,22 @@ def render_task_status(tasklist): ret['status'] = _(u'Started') elif task.stat == STAT_FINISH_SUCCESS: ret['status'] = _(u'Finished') + elif task.stat == STAT_ENDED: + ret['status'] = _(u'Ended') + elif task.stat == STAT_CANCELLED: + ret['status'] = _(u'Cancelled') else: ret['status'] = _(u'Unknown Status') - ret['taskMessage'] = "{}: {}".format(_(task.name), task.message) + ret['taskMessage'] = "{}: {}".format(task.name, task.message) if task.message else task.name ret['progress'] = "{} %".format(int(task.progress * 100)) ret['user'] = escape(user) # prevent xss + + # Hidden fields + ret['task_id'] = task.id + ret['stat'] = task.stat + ret['is_cancellable'] = task.is_cancellable + rendered_tasklist.append(ret) return rendered_tasklist @@ -82,7 +93,7 @@ def render_task_status(tasklist): def format_runtime(runtime): ret_val = "" if runtime.days: - ret_val = format_unit(runtime.days, 'duration-day', length="long", locale=get_locale()) + ', ' + ret_val = format_unit(runtime.days, 'duration-day', length="long") + ', ' minutes, seconds = divmod(runtime.seconds, 60) hours, minutes = divmod(minutes, 60) # ToDo: locale.number_symbols._data['timeSeparator'] -> localize time separator ? diff --git a/cps/web.py b/cps/web.py index 83425191..1aa4cc1b 100644 --- a/cps/web.py +++ b/cps/web.py @@ -24,7 +24,6 @@ import mimetypes import chardet # dependency of requests import copy -from babel import Locale from flask import Blueprint, jsonify from flask import request, redirect, send_from_directory, make_response, flash, abort, url_for from flask import session as flask_session @@ -40,7 +39,7 @@ from werkzeug.datastructures import Headers from werkzeug.security import generate_password_hash, check_password_hash from . import constants, logger, isoLanguages, services -from . import babel, db, ub, config, app +from . import db, ub, config, app from . import calibre_db, kobo_sync_status from .search import render_search_results, render_adv_search_results from .gdriveutils import getFileFromEbooksFolder, do_gdrive_download @@ -50,6 +49,7 @@ from .helper import check_valid_domain, check_email, check_username, \ edit_book_read_status from .pagination import Pagination from .redirect import redirect_back +from .babel import get_available_locale from .usermanagement import login_required_if_no_ano from .kobo_sync_status import remove_synced_book from .render_template import render_title_template @@ -960,7 +960,7 @@ def publisher_list(): .count()) if no_publisher_count: entries.append([db.Category(_("None"), "-1"), no_publisher_count]) - entries = sorted(entries, key=lambda x: x[0].name, reverse=not order_no) + entries = sorted(entries, key=lambda x: x[0].name.lower(), reverse=not order_no) char_list = generate_char_list(entries) return render_title_template('list.html', entries=entries, folder='web.books_list', charlist=char_list, title=_(u"Publishers"), page="publisherlist", data="publisher", order=order_no) @@ -990,7 +990,7 @@ def series_list(): .count()) if no_series_count: entries.append([db.Category(_("None"), "-1"), no_series_count]) - entries = sorted(entries, key=lambda x: x[0].name, reverse=not order_no) + entries = sorted(entries, key=lambda x: x[0].name.lower(), reverse=not order_no) return render_title_template('list.html', entries=entries, folder='web.books_list', charlist=char_list, title=_(u"Series"), page="serieslist", data="series", order=order_no) else: @@ -1092,7 +1092,7 @@ def category_list(): .count()) if no_tag_count: entries.append([db.Category(_("None"), "-1"), no_tag_count]) - entries = sorted(entries, key=lambda x: x[0].name, reverse=not order_no) + entries = sorted(entries, key=lambda x: x[0].name.lower(), reverse=not order_no) char_list = generate_char_list(entries) return render_title_template('list.html', entries=entries, folder='web.books_list', charlist=char_list, title=_(u"Categories"), page="catlist", data="category", order=order_no) @@ -1417,7 +1417,7 @@ def change_profile(kobo_support, local_oauth_check, oauth_status, translations, @login_required def profile(): languages = calibre_db.speaking_language() - translations = babel.list_translations() + [Locale('en')] + translations = get_available_locale() kobo_support = feature_support['kobo'] and config.config_kobo_sync if feature_support['oauth'] and config.config_login_type == 2: oauth_status = get_oauth_status() diff --git a/optional-requirements.txt b/optional-requirements.txt index 07e1ad88..4360d221 100644 --- a/optional-requirements.txt +++ b/optional-requirements.txt @@ -1,5 +1,5 @@ # GDrive Integration -google-api-python-client>=1.7.11,<2.46.0 +google-api-python-client>=1.7.11,<2.50.0 gevent>20.6.0,<22.0.0 greenlet>=0.4.17,<1.2.0 httplib2>=0.9.2,<0.21.0 @@ -13,7 +13,7 @@ rsa>=3.4.2,<4.9.0 # Gmail google-auth-oauthlib>=0.4.3,<0.6.0 -google-api-python-client>=1.7.11,<2.46.0 +google-api-python-client>=1.7.11,<2.50.0 # goodreads goodreads>=0.3.2,<0.4.0