mirror of
https://github.com/janeczku/calibre-web
synced 2024-12-18 06:00:32 +00:00
Further migration to flask_babel
Bugfix sort order Bugfix tasklist
This commit is contained in:
parent
2e007a160e
commit
aaa749933d
@ -200,7 +200,7 @@ def admin():
|
|||||||
form_date -= timedelta(hours=int(commit[20:22]), minutes=int(commit[23:]))
|
form_date -= timedelta(hours=int(commit[20:22]), minutes=int(commit[23:]))
|
||||||
elif commit[19] == '-':
|
elif commit[19] == '-':
|
||||||
form_date += timedelta(hours=int(commit[20:22]), minutes=int(commit[23:]))
|
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:
|
else:
|
||||||
commit = version['version']
|
commit = version['version']
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
from babel import Locale
|
|
||||||
from babel import negotiate_locale
|
from babel import negotiate_locale
|
||||||
from flask_babel import Babel
|
from flask_babel import Babel, Locale
|
||||||
from babel.core import UnknownLocaleError
|
from babel.core import UnknownLocaleError
|
||||||
from flask import request, g
|
from flask import request, g
|
||||||
|
|
||||||
|
@ -919,7 +919,7 @@ class CalibreDB:
|
|||||||
.count())
|
.count())
|
||||||
if no_lang_count:
|
if no_lang_count:
|
||||||
tags.append([Category(_("None"), "none"), 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:
|
else:
|
||||||
if not languages:
|
if not languages:
|
||||||
languages = self.session.query(Languages) \
|
languages = self.session.query(Languages) \
|
||||||
|
@ -22,15 +22,16 @@
|
|||||||
|
|
||||||
# custom jinja filters
|
# custom jinja filters
|
||||||
|
|
||||||
|
from markupsafe import escape
|
||||||
import datetime
|
import datetime
|
||||||
import mimetypes
|
import mimetypes
|
||||||
from uuid import uuid4
|
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 import Blueprint, request, url_for
|
||||||
from flask_babel import get_locale
|
from flask_babel import format_date
|
||||||
from flask_login import current_user
|
from flask_login import current_user
|
||||||
from markupsafe import escape
|
|
||||||
from . import constants, logger
|
from . import constants, logger
|
||||||
|
|
||||||
jinjia = Blueprint('jinjia', __name__)
|
jinjia = Blueprint('jinjia', __name__)
|
||||||
@ -76,7 +77,7 @@ def mimetype_filter(val):
|
|||||||
@jinjia.app_template_filter('formatdate')
|
@jinjia.app_template_filter('formatdate')
|
||||||
def formatdate_filter(val):
|
def formatdate_filter(val):
|
||||||
try:
|
try:
|
||||||
return format_date(val, format='medium', locale=get_locale())
|
return format_date(val, format='medium')
|
||||||
except AttributeError as e:
|
except AttributeError as e:
|
||||||
log.error('Babel error: %s, Current user locale: %s, Current User: %s', e,
|
log.error('Babel error: %s, Current user locale: %s, Current User: %s', e,
|
||||||
current_user.locale,
|
current_user.locale,
|
||||||
|
@ -20,7 +20,7 @@ from datetime import datetime
|
|||||||
from flask import Blueprint, request, redirect, url_for, flash
|
from flask import Blueprint, request, redirect, url_for, flash
|
||||||
from flask import session as flask_session
|
from flask import session as flask_session
|
||||||
from flask_login import current_user
|
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 flask_babel import gettext as _
|
||||||
from sqlalchemy.sql.expression import func, not_, and_, or_, text
|
from sqlalchemy.sql.expression import func, not_, and_, or_, text
|
||||||
from sqlalchemy.sql.functions import coalesce
|
from sqlalchemy.sql.functions import coalesce
|
||||||
@ -193,14 +193,14 @@ def extend_search_term(searchterm,
|
|||||||
try:
|
try:
|
||||||
searchterm.extend([_(u"Published after ") +
|
searchterm.extend([_(u"Published after ") +
|
||||||
format_date(datetime.strptime(pub_start, "%Y-%m-%d"),
|
format_date(datetime.strptime(pub_start, "%Y-%m-%d"),
|
||||||
format='medium', locale=get_locale())])
|
format='medium')])
|
||||||
except ValueError:
|
except ValueError:
|
||||||
pub_start = u""
|
pub_start = u""
|
||||||
if pub_end:
|
if pub_end:
|
||||||
try:
|
try:
|
||||||
searchterm.extend([_(u"Published before ") +
|
searchterm.extend([_(u"Published before ") +
|
||||||
format_date(datetime.strptime(pub_end, "%Y-%m-%d"),
|
format_date(datetime.strptime(pub_end, "%Y-%m-%d"),
|
||||||
format='medium', locale=get_locale())])
|
format='medium')])
|
||||||
except ValueError:
|
except ValueError:
|
||||||
pub_end = u""
|
pub_end = u""
|
||||||
elements = {'tag': db.Tags, 'serie':db.Series, 'shelf':ub.Shelf}
|
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:
|
if column_start:
|
||||||
search_term.extend([u"{} >= {}".format(c.name,
|
search_term.extend([u"{} >= {}".format(c.name,
|
||||||
format_date(datetime.strptime(column_start, "%Y-%m-%d").date(),
|
format_date(datetime.strptime(column_start, "%Y-%m-%d").date(),
|
||||||
format='medium',
|
format='medium')
|
||||||
locale=get_locale())
|
|
||||||
)])
|
)])
|
||||||
cc_present = True
|
cc_present = True
|
||||||
if column_end:
|
if column_end:
|
||||||
search_term.extend([u"{} <= {}".format(c.name,
|
search_term.extend([u"{} <= {}".format(c.name,
|
||||||
format_date(datetime.strptime(column_end, "%Y-%m-%d").date(),
|
format_date(datetime.strptime(column_end, "%Y-%m-%d").date(),
|
||||||
format='medium',
|
format='medium')
|
||||||
locale=get_locale())
|
|
||||||
)])
|
)])
|
||||||
cc_present = True
|
cc_present = True
|
||||||
elif term.get('custom_column_' + str(c.id)):
|
elif term.get('custom_column_' + str(c.id)):
|
||||||
search_term.extend([(u"{}: {}".format(c.name, term.get('custom_column_' + str(c.id))))])
|
search_term.extend([(u"{}: {}".format(c.name, term.get('custom_column_' + str(c.id))))])
|
||||||
cc_present = True
|
cc_present = True
|
||||||
|
|
||||||
|
|
||||||
if any(tags.values()) or author_name or book_title or publisher or pub_start or pub_end or rating_low \
|
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:
|
or rating_high or description or cc_present or read_status:
|
||||||
search_term, pub_start, pub_end = extend_search_term(search_term,
|
search_term, pub_start, pub_end = extend_search_term(search_term,
|
||||||
|
@ -22,7 +22,6 @@ import inspect
|
|||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
from dataclasses import asdict
|
|
||||||
|
|
||||||
from flask import Blueprint, Response, request, url_for
|
from flask import Blueprint, Response, request, url_for
|
||||||
from flask_login import current_user
|
from flask_login import current_user
|
||||||
@ -57,9 +56,10 @@ for f in modules:
|
|||||||
try:
|
try:
|
||||||
importlib.import_module("cps.metadata_provider." + a)
|
importlib.import_module("cps.metadata_provider." + a)
|
||||||
new_list.append(a)
|
new_list.append(a)
|
||||||
except (ImportError, IndentationError, SyntaxError) as e:
|
except (IndentationError, SyntaxError) as e:
|
||||||
log.error("Import error for metadata source: {} - {}".format(a, e))
|
log.error("Syntax error for metadata source: {} - {}".format(a, e))
|
||||||
pass
|
except ImportError as e:
|
||||||
|
log.debug("Import error for metadata source: {} - {}".format(a, e))
|
||||||
|
|
||||||
|
|
||||||
def list_classes(provider_list):
|
def list_classes(provider_list):
|
||||||
|
@ -19,12 +19,13 @@ from markupsafe import escape
|
|||||||
from flask import Blueprint, jsonify
|
from flask import Blueprint, jsonify
|
||||||
from flask_login import login_required, current_user
|
from flask_login import login_required, current_user
|
||||||
from flask_babel import gettext as _
|
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 babel.units import format_unit
|
||||||
|
|
||||||
from . import logger
|
from . import logger
|
||||||
from .render_template import render_title_template
|
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__)
|
tasks = Blueprint('tasks', __name__)
|
||||||
|
|
||||||
@ -50,11 +51,11 @@ def get_tasks_status():
|
|||||||
# helper function to apply localize status information in tasklist entries
|
# helper function to apply localize status information in tasklist entries
|
||||||
def render_task_status(tasklist):
|
def render_task_status(tasklist):
|
||||||
rendered_tasklist = list()
|
rendered_tasklist = list()
|
||||||
for __, user, __, task in tasklist:
|
for __, user, __, task, __ in tasklist:
|
||||||
if user == current_user.name or current_user.role_admin():
|
if user == current_user.name or current_user.role_admin():
|
||||||
ret = {}
|
ret = {}
|
||||||
if task.start_time:
|
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)
|
ret['runtime'] = format_runtime(task.runtime)
|
||||||
|
|
||||||
# localize the task status
|
# localize the task status
|
||||||
@ -67,12 +68,22 @@ def render_task_status(tasklist):
|
|||||||
ret['status'] = _(u'Started')
|
ret['status'] = _(u'Started')
|
||||||
elif task.stat == STAT_FINISH_SUCCESS:
|
elif task.stat == STAT_FINISH_SUCCESS:
|
||||||
ret['status'] = _(u'Finished')
|
ret['status'] = _(u'Finished')
|
||||||
|
elif task.stat == STAT_ENDED:
|
||||||
|
ret['status'] = _(u'Ended')
|
||||||
|
elif task.stat == STAT_CANCELLED:
|
||||||
|
ret['status'] = _(u'Cancelled')
|
||||||
else:
|
else:
|
||||||
ret['status'] = _(u'Unknown Status')
|
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['progress'] = "{} %".format(int(task.progress * 100))
|
||||||
ret['user'] = escape(user) # prevent xss
|
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)
|
rendered_tasklist.append(ret)
|
||||||
|
|
||||||
return rendered_tasklist
|
return rendered_tasklist
|
||||||
@ -82,7 +93,7 @@ def render_task_status(tasklist):
|
|||||||
def format_runtime(runtime):
|
def format_runtime(runtime):
|
||||||
ret_val = ""
|
ret_val = ""
|
||||||
if runtime.days:
|
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)
|
minutes, seconds = divmod(runtime.seconds, 60)
|
||||||
hours, minutes = divmod(minutes, 60)
|
hours, minutes = divmod(minutes, 60)
|
||||||
# ToDo: locale.number_symbols._data['timeSeparator'] -> localize time separator ?
|
# ToDo: locale.number_symbols._data['timeSeparator'] -> localize time separator ?
|
||||||
|
12
cps/web.py
12
cps/web.py
@ -24,7 +24,6 @@ import mimetypes
|
|||||||
import chardet # dependency of requests
|
import chardet # dependency of requests
|
||||||
import copy
|
import copy
|
||||||
|
|
||||||
from babel import Locale
|
|
||||||
from flask import Blueprint, jsonify
|
from flask import Blueprint, jsonify
|
||||||
from flask import request, redirect, send_from_directory, make_response, flash, abort, url_for
|
from flask import request, redirect, send_from_directory, make_response, flash, abort, url_for
|
||||||
from flask import session as flask_session
|
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 werkzeug.security import generate_password_hash, check_password_hash
|
||||||
|
|
||||||
from . import constants, logger, isoLanguages, services
|
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 . import calibre_db, kobo_sync_status
|
||||||
from .search import render_search_results, render_adv_search_results
|
from .search import render_search_results, render_adv_search_results
|
||||||
from .gdriveutils import getFileFromEbooksFolder, do_gdrive_download
|
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
|
edit_book_read_status
|
||||||
from .pagination import Pagination
|
from .pagination import Pagination
|
||||||
from .redirect import redirect_back
|
from .redirect import redirect_back
|
||||||
|
from .babel import get_available_locale
|
||||||
from .usermanagement import login_required_if_no_ano
|
from .usermanagement import login_required_if_no_ano
|
||||||
from .kobo_sync_status import remove_synced_book
|
from .kobo_sync_status import remove_synced_book
|
||||||
from .render_template import render_title_template
|
from .render_template import render_title_template
|
||||||
@ -960,7 +960,7 @@ def publisher_list():
|
|||||||
.count())
|
.count())
|
||||||
if no_publisher_count:
|
if no_publisher_count:
|
||||||
entries.append([db.Category(_("None"), "-1"), 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)
|
char_list = generate_char_list(entries)
|
||||||
return render_title_template('list.html', entries=entries, folder='web.books_list', charlist=char_list,
|
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)
|
title=_(u"Publishers"), page="publisherlist", data="publisher", order=order_no)
|
||||||
@ -990,7 +990,7 @@ def series_list():
|
|||||||
.count())
|
.count())
|
||||||
if no_series_count:
|
if no_series_count:
|
||||||
entries.append([db.Category(_("None"), "-1"), 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,
|
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)
|
title=_(u"Series"), page="serieslist", data="series", order=order_no)
|
||||||
else:
|
else:
|
||||||
@ -1092,7 +1092,7 @@ def category_list():
|
|||||||
.count())
|
.count())
|
||||||
if no_tag_count:
|
if no_tag_count:
|
||||||
entries.append([db.Category(_("None"), "-1"), 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)
|
char_list = generate_char_list(entries)
|
||||||
return render_title_template('list.html', entries=entries, folder='web.books_list', charlist=char_list,
|
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)
|
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
|
@login_required
|
||||||
def profile():
|
def profile():
|
||||||
languages = calibre_db.speaking_language()
|
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
|
kobo_support = feature_support['kobo'] and config.config_kobo_sync
|
||||||
if feature_support['oauth'] and config.config_login_type == 2:
|
if feature_support['oauth'] and config.config_login_type == 2:
|
||||||
oauth_status = get_oauth_status()
|
oauth_status = get_oauth_status()
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# GDrive Integration
|
# 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
|
gevent>20.6.0,<22.0.0
|
||||||
greenlet>=0.4.17,<1.2.0
|
greenlet>=0.4.17,<1.2.0
|
||||||
httplib2>=0.9.2,<0.21.0
|
httplib2>=0.9.2,<0.21.0
|
||||||
@ -13,7 +13,7 @@ rsa>=3.4.2,<4.9.0
|
|||||||
|
|
||||||
# Gmail
|
# Gmail
|
||||||
google-auth-oauthlib>=0.4.3,<0.6.0
|
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
|
||||||
goodreads>=0.3.2,<0.4.0
|
goodreads>=0.3.2,<0.4.0
|
||||||
|
Loading…
Reference in New Issue
Block a user