From 05933a5f0c2e19ed6330b87aa2959ad2eb08c674 Mon Sep 17 00:00:00 2001 From: ElQuimm <50202052+ElQuimm@users.noreply.github.com> Date: Tue, 13 Apr 2021 18:51:50 +0200 Subject: [PATCH 01/10] Updated italian message.po I have not removed the #, fuzzy lines, but modified the corresponding values. --- cps/translations/it/LC_MESSAGES/messages.po | 86 ++++++++++----------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/cps/translations/it/LC_MESSAGES/messages.po b/cps/translations/it/LC_MESSAGES/messages.po index 5c62edf4..590064e1 100644 --- a/cps/translations/it/LC_MESSAGES/messages.po +++ b/cps/translations/it/LC_MESSAGES/messages.po @@ -63,12 +63,12 @@ msgstr "Configurazione dell'interfaccia utente" #: cps/admin.py:237 cps/templates/admin.html:46 #, fuzzy msgid "Edit Users" -msgstr "Utente amministratore" +msgstr "Modifica gli utenti" #: cps/admin.py:263 #, fuzzy msgid "all" -msgstr "Tutti" +msgstr "tutti" #: cps/admin.py:298 cps/templates/user_edit.html:44 #: cps/templates/user_table.html:52 @@ -77,7 +77,7 @@ msgstr "tutte le lingue presenti" #: cps/admin.py:331 cps/admin.py:1233 msgid "Guest Name can't be changed" -msgstr "" +msgstr "Il nome dell'utente Guest non può essere modificato" #: cps/admin.py:345 cps/admin.py:1198 msgid "No admin user remaining, can't remove admin role" @@ -106,19 +106,19 @@ msgstr "Vuoi veramente eliminare questo scaffale?" #: cps/admin.py:435 #, fuzzy msgid "Are you sure you want to change locales of selected user(s)?" -msgstr "Vuoi veramente eliminare questo scaffale?" +msgstr "Sei sicuro di voler modificare le impostazioni locali dell'/degli utente/i selezionato/i?" #: cps/admin.py:437 msgid "Are you sure you want to change visible book languages for selected user(s)?" -msgstr "" +msgstr "Sei sicuro di voler modificare le impostazioni delle lingue visualizzabili dell'/degli utente/i selezionato/i?" #: cps/admin.py:439 msgid "Are you sure you want to change the selected role for the selected user(s)?" -msgstr "" +msgstr "Sei sicuro di voler modificare il ruolo evidenziato dell'/degli utente/i selezionato/i?" #: cps/admin.py:441 msgid "Are you sure you want to change the selected visibility restrictions for the selected user(s)?" -msgstr "" +msgstr "Sei sicuro di voler modificare le impostazioni delle restrizioni di visualizzazione dell'/degli utente/i selezionato/i?" #: cps/admin.py:687 cps/admin.py:693 cps/admin.py:703 cps/admin.py:713 #: cps/templates/modal_dialogs.html:29 cps/templates/user_table.html:28 @@ -254,12 +254,12 @@ msgstr "Modifica le impostazioni del server e-mail" #: cps/admin.py:1303 msgid "G-Mail Account Verification Successful" -msgstr "" +msgstr "L'account g-mail è stato verificato con successo" #: cps/admin.py:1328 #, python-format msgid "Test e-mail queued for sending to %(email)s, please check Tasks for result" -msgstr "" +msgstr "L'e-mail di test è stato accodato con successo per essere spedito a %(email)s, per favore verifica tramite il pulsante 'Compito' il risultato" #: cps/admin.py:1331 #, python-format @@ -714,7 +714,7 @@ msgstr "Tutti" #: cps/opds.py:385 msgid "{} Stars" -msgstr "" +msgstr "{} Stelle" #: cps/remotelogin.py:65 cps/web.py:1488 msgid "login" @@ -1109,7 +1109,7 @@ msgstr "Libro accodato con successo per essere spedito a %(kindlemail)s" #: cps/web.py:1357 #, python-format msgid "Oops! There was an error sending this book: %(res)s" -msgstr "Si è verificato un errore durante l'invio di questo libro: %(res)s" +msgstr "Oops! Si è verificato un errore durante l'invio di questo libro: %(res)s" #: cps/web.py:1359 msgid "Please update your profile with a valid Send to Kindle E-mail Address." @@ -1183,7 +1183,7 @@ msgstr "Leggi un libro" #: cps/services/gmail.py:41 msgid "Found no valid gmail.json file with OAuth information" -msgstr "" +msgstr "Ho trovato un gmail.json file senza informazione OAuth" #: cps/tasks/convert.py:114 #, python-format @@ -1314,11 +1314,11 @@ msgstr "E-mail da" #: cps/templates/admin.html:84 msgid "E-Mail Service" -msgstr "" +msgstr "Servizio e-mail" #: cps/templates/admin.html:85 msgid "Gmail via Oauth2" -msgstr "" +msgstr "Gmail via Oauth2" #: cps/templates/admin.html:100 msgid "Configuration" @@ -1370,11 +1370,11 @@ msgstr "Nome intestazione reverse proxy" #: cps/templates/admin.html:153 msgid "Edit Basic Configuration" -msgstr "Edita la configurazione di base" +msgstr "Modifica la configurazione di base" #: cps/templates/admin.html:154 msgid "Edit UI Configuration" -msgstr "Edita la configurazione dell'interfaccia utente" +msgstr "Modifica la configurazione dell'interfaccia utente" #: cps/templates/admin.html:159 msgid "Administration" @@ -2018,7 +2018,7 @@ msgstr "LDAP Member User Filter Detection" #: cps/templates/config_edit.html:344 msgid "Autodetect" -msgstr "Autodetect - determina automaticamente" +msgstr "Autodetect - identifica automaticamente" #: cps/templates/config_edit.html:345 msgid "Custom Filter" @@ -2225,23 +2225,23 @@ msgstr "Modifica metadati" #: cps/templates/email_edit.html:12 msgid "Choose Server Type" -msgstr "" +msgstr "Scegli il tipo di server" #: cps/templates/email_edit.html:14 msgid "Use Standard E-Mail Account" -msgstr "" +msgstr "Utilizza un account e-mail standard" #: cps/templates/email_edit.html:15 msgid "G-Mail Account with OAuth2 Verfification" -msgstr "" +msgstr "Utilizza un account g-mail con la verifica OAuth2" #: cps/templates/email_edit.html:21 msgid "Setup Gmail Account as E-Mail Server" -msgstr "" +msgstr "Configura l'account gmail quale server e-mail" #: cps/templates/email_edit.html:23 msgid "Revoke G-Mail Access" -msgstr "" +msgstr "Revoca l'accesso g-mail" #: cps/templates/email_edit.html:41 msgid "STARTTLS" @@ -2298,7 +2298,7 @@ msgstr "Apri il file .kobo/Kobo eReader.conf in un editore di testi e aggiungi ( #: cps/templates/http_error.html:38 msgid "Create Issue" -msgstr "Crea un rapporto di segnalazione di un problema" +msgstr "Crea un rapporto di segnalazione di problema" #: cps/templates/http_error.html:45 msgid "Return to Home" @@ -2328,11 +2328,11 @@ msgstr "Avvio" #: cps/templates/index.xml:18 msgid "Alphabetical Books" -msgstr "" +msgstr "Libri in ordine alfabetico" #: cps/templates/index.xml:22 msgid "Books sorted alphabetically" -msgstr "" +msgstr "Libri ordinati alfabeticamente" #: cps/templates/index.xml:29 msgid "Popular publications from this catalog based on Downloads." @@ -2910,86 +2910,86 @@ msgstr "Seleziona" #: cps/templates/user_table.html:101 #, fuzzy msgid "Edit User" -msgstr "Utente amministratore" +msgstr "Modifica utente" #: cps/templates/user_table.html:104 #, fuzzy msgid "Enter Username" -msgstr "Scegli un nome utente" +msgstr "Digita il nome utente" #: cps/templates/user_table.html:105 #, fuzzy msgid "Enter E-mail Address" -msgstr "Il tuo indirizzo e-mail" +msgstr "Digita l'indirizzo e-mail" #: cps/templates/user_table.html:106 #, fuzzy msgid "Enter Kindle E-mail Address" -msgstr "Invia all'email di Kindle" +msgstr "Digita l'email di Kindle" #: cps/templates/user_table.html:106 #, fuzzy msgid "Kindle E-mail" -msgstr "E-mail di test" +msgstr "E-mail di Kindle" #: cps/templates/user_table.html:107 #, fuzzy msgid "Locale" -msgstr "Scala" +msgstr "Locale" #: cps/templates/user_table.html:108 msgid "Visible Book Languages" -msgstr "" +msgstr "Lingue dei libri visualizzabili" #: cps/templates/user_table.html:109 #, fuzzy msgid "Edit Denied Tags" -msgstr "Seleziona le categorie consentite/negate" +msgstr "Modifica le categorie negate" #: cps/templates/user_table.html:109 msgid "Denied Tags" -msgstr "" +msgstr "Categorie negate" #: cps/templates/user_table.html:110 #, fuzzy msgid "Edit Allowed Tags" -msgstr "Seleziona le categorie consentite/negate" +msgstr "Modifica le categorie permesse" #: cps/templates/user_table.html:110 msgid "Allowed Tags" -msgstr "" +msgstr "Categorie permesse" #: cps/templates/user_table.html:111 #, fuzzy msgid "Edit Allowed Column Values" -msgstr "Aggiungi valori personali permetti/nega nelle colonne" +msgstr "Modifica i valori delle colonne permesse" #: cps/templates/user_table.html:111 #, fuzzy msgid "Allowed Column Values" -msgstr "Aggiungi valori personali permetti/nega nelle colonne" +msgstr "Valori delle colonne permesse" #: cps/templates/user_table.html:112 #, fuzzy msgid "Edit Denied Column Values" -msgstr "Aggiungi valori personali permetti/nega nelle colonne" +msgstr "Modifica i valori delle colonne negate" #: cps/templates/user_table.html:112 #, fuzzy msgid "Denied Columns Values" -msgstr "Aggiungi valori personali permetti/nega nelle colonne" +msgstr "Valori delle colonne negate" #: cps/templates/user_table.html:117 #, fuzzy msgid "Change Password" -msgstr "Permetti la modifica della password" +msgstr "Modifica la password" #: cps/templates/user_table.html:118 #, fuzzy msgid "Edit Public Shelfs" -msgstr "Scaffale pubblico" +msgstr "Modifica scaffali pubblici" #: cps/templates/user_table.html:120 msgid "View" -msgstr "" +msgstr "Visualizza" From 3973362457f65bec6c98b6ee42377cb3b4fe4687 Mon Sep 17 00:00:00 2001 From: malletfils Date: Wed, 14 Apr 2021 19:57:02 +0200 Subject: [PATCH 02/10] Update db.py Just adding support for Babelio (french website about books) in the link section --- cps/db.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cps/db.py b/cps/db.py index 0d7055a4..34804255 100644 --- a/cps/db.py +++ b/cps/db.py @@ -121,6 +121,8 @@ class Identifiers(Base): return u"Douban" elif format_type == "goodreads": return u"Goodreads" + elif format_type == "babelio": + return u"Babelio" elif format_type == "google": return u"Google Books" elif format_type == "kobo": @@ -148,6 +150,8 @@ class Identifiers(Base): return u"https://dx.doi.org/{0}".format(self.val) elif format_type == "goodreads": return u"https://www.goodreads.com/book/show/{0}".format(self.val) + elif format_type == "babelio": + return u"https://www.babelio.com/livres/titre/{0}".format(self.val) elif format_type == "douban": return u"https://book.douban.com/subject/{0}".format(self.val) elif format_type == "google": From 1cb8dbe795660c713ebf7f683707435ca0720836 Mon Sep 17 00:00:00 2001 From: Ozzie Isaacs Date: Thu, 15 Apr 2021 17:42:39 +0200 Subject: [PATCH 03/10] Update migration routine --- cps/config_sql.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/cps/config_sql.py b/cps/config_sql.py index 6e1ff54e..6e13489d 100644 --- a/cps/config_sql.py +++ b/cps/config_sql.py @@ -21,15 +21,16 @@ from __future__ import division, print_function, unicode_literals import os import sys -from sqlalchemy import exc, Column, String, Integer, SmallInteger, Boolean, BLOB, JSON +from sqlalchemy import Column, String, Integer, SmallInteger, Boolean, BLOB, JSON from sqlalchemy.exc import OperationalError +from sqlalchemy.sql.expression import text try: # Compatibility with sqlalchemy 2.0 from sqlalchemy.orm import declarative_base except ImportError: from sqlalchemy.ext.declarative import declarative_base -from . import constants, cli, logger, ub +from . import constants, cli, logger log = logger.create() @@ -368,17 +369,17 @@ def _migrate_table(session, orm_class): column_default = "" else: if isinstance(column.default.arg, bool): - column_default = ("DEFAULT %r" % int(column.default.arg)) + column_default = "DEFAULT {}".format(int(column.default.arg)) else: - column_default = ("DEFAULT '%r'" % column.default.arg) + column_default = "DEFAULT `{}`".format(column.default.arg) if isinstance(column.type, JSON): column_type = "JSON" else: column_type = column.type - alter_table = "ALTER TABLE %s ADD COLUMN `%s` %s %s" % (orm_class.__tablename__, + alter_table = text("ALTER TABLE %s ADD COLUMN `%s` %s %s" % (orm_class.__tablename__, column_name, column_type, - column_default) + column_default)) log.debug(alter_table) session.execute(alter_table) changed = True From 39dda3f5344ba56e5ecc78c16c42091fbb1f6049 Mon Sep 17 00:00:00 2001 From: Ozzie Isaacs Date: Thu, 15 Apr 2021 18:02:52 +0200 Subject: [PATCH 04/10] Fix opds login with colon in password #1952 --- cps/usermanagement.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cps/usermanagement.py b/cps/usermanagement.py index ef7174c4..78e80afe 100644 --- a/cps/usermanagement.py +++ b/cps/usermanagement.py @@ -75,8 +75,9 @@ def load_user_from_auth_header(header_val): basic_username = basic_password = '' # nosec try: header_val = base64.b64decode(header_val).decode('utf-8') - basic_username = header_val.split(':')[0] - basic_password = header_val.split(':')[1] + # Users with colon are invalid: rfc7617 page 4 + basic_username = header_val.split(':', 1)[0] + basic_password = header_val.split(':', 1)[1] except (TypeError, UnicodeDecodeError, binascii.Error): pass user = _fetch_user_by_name(basic_username) From 39bbee0eebf0b894ced33cffb300a581ed95cf04 Mon Sep 17 00:00:00 2001 From: Ozzie Isaacs Date: Sat, 17 Apr 2021 10:27:30 +0200 Subject: [PATCH 05/10] Books sort with non Books table column working #1938 --- cps/db.py | 15 +++++++++++---- cps/services/__init__.py | 2 +- cps/templates/book_table.html | 10 +++++----- cps/templates/email_edit.html | 4 ++-- cps/web.py | 22 +++++++++++++++++++--- 5 files changed, 38 insertions(+), 15 deletions(-) diff --git a/cps/db.py b/cps/db.py index 0d7055a4..7f05e24c 100644 --- a/cps/db.py +++ b/cps/db.py @@ -702,14 +702,21 @@ class CalibreDB(): return self.session.query(Books) \ .filter(and_(Books.authors.any(and_(*q)), func.lower(Books.title).ilike("%" + title + "%"))).first() - def search_query(self, term): + def search_query(self, term, *join): term.strip().lower() self.session.connection().connection.connection.create_function("lower", 1, lcase) q = list() authorterms = re.split("[, ]+", term) for authorterm in authorterms: q.append(Books.authors.any(func.lower(Authors.name).ilike("%" + authorterm + "%"))) - return self.session.query(Books).filter(self.common_filters(True)).filter( + query = self.session.query(Books) + if len(join) == 3: + query = query.outerjoin(join[0], join[1]).outerjoin(join[2]) + elif len(join) == 2: + query = query.outerjoin(join[0], join[1]) + elif len(join) == 1: + query = query.outerjoin(join[0]) + return query.filter(self.common_filters(True)).filter( or_(Books.tags.any(func.lower(Tags.name).ilike("%" + term + "%")), Books.series.any(func.lower(Series.name).ilike("%" + term + "%")), Books.authors.any(and_(*q)), @@ -718,10 +725,10 @@ class CalibreDB(): )) # read search results from calibre-database and return it (function is used for feed and simple search - def get_search_results(self, term, offset=None, order=None, limit=None): + def get_search_results(self, term, offset=None, order=None, limit=None, *join): order = order or [Books.sort] pagination = None - result = self.search_query(term).order_by(*order).all() + result = self.search_query(term, *join).order_by(*order).all() result_count = len(result) if offset != None and limit != None: offset = int(offset) diff --git a/cps/services/__init__.py b/cps/services/__init__.py index efd55621..e6e5954c 100644 --- a/cps/services/__init__.py +++ b/cps/services/__init__.py @@ -49,5 +49,5 @@ except ImportError as err: try: from . import gmail except ImportError as err: - log.debug("Cannot import Gmail, sending books via G-Mail Accounts will not work: %s", err) + log.debug("Cannot import gmail, sending books via Gmail Oauth2 Verification will not work: %s", err) gmail = None diff --git a/cps/templates/book_table.html b/cps/templates/book_table.html index e700eb53..bb167ad3 100644 --- a/cps/templates/book_table.html +++ b/cps/templates/book_table.html @@ -47,13 +47,13 @@ {{ text_table_row('title', _('Enter Title'),_('Title'), true, true) }} {{ text_table_row('sort', _('Enter Title Sort'),_('Title Sort'), false, true) }} {{ text_table_row('author_sort', _('Enter Author Sort'),_('Author Sort'), false, true) }} - {{ text_table_row('authors', _('Enter Authors'),_('Authors'), true) }} - {{ text_table_row('tags', _('Enter Categories'),_('Categories'), false, false) }} - {{ text_table_row('series', _('Enter Series'),_('Series'), false, false) }} + {{ text_table_row('authors', _('Enter Authors'),_('Authors'), true, true) }} + {{ text_table_row('tags', _('Enter Categories'),_('Categories'), false, true) }} + {{ text_table_row('series', _('Enter Series'),_('Series'), false, true) }} {{_('Series Index')}} - {{ text_table_row('languages', _('Enter Languages'),_('Languages'), false, false) }} + {{ text_table_row('languages', _('Enter Languages'),_('Languages'), false, true) }} - {{ text_table_row('publishers', _('Enter Publishers'),_('Publishers'), false, false) }} + {{ text_table_row('publishers', _('Enter Publishers'),_('Publishers'), false, true) }} {% if g.user.role_delete_books() and g.user.role_edit()%} {{_('Delete')}} {% endif %} diff --git a/cps/templates/email_edit.html b/cps/templates/email_edit.html index 8b92a248..ac1c36d2 100644 --- a/cps/templates/email_edit.html +++ b/cps/templates/email_edit.html @@ -12,7 +12,7 @@
@@ -20,7 +20,7 @@ {% if content.mail_gmail_token == {} %} {% else %} - + {% endif %}
diff --git a/cps/web.py b/cps/web.py index 0eaacdb1..e01b4b22 100644 --- a/cps/web.py +++ b/cps/web.py @@ -760,10 +760,26 @@ def list_books(): sort = request.args.get("sort", "id") order = request.args.get("order", "").lower() state = None + join = tuple() if sort == "state": state = json.loads(request.args.get("state", "[]")) - if sort != "state" and order: + elif sort == "tags": + order = [db.Tags.name.asc()] if order == "asc" else [db.Tags.name.desc()] + join = db.books_tags_link,db.Books.id == db.books_tags_link.c.book, db.Tags + elif sort == "series": + order = [db.Series.name.asc()] if order == "asc" else [db.Series.name.desc()] + join = db.books_series_link,db.Books.id == db.books_series_link.c.book, db.Series + elif sort == "publishers": + order = [db.Publishers.name.asc()] if order == "asc" else [db.Publishers.name.desc()] + join = db.books_publishers_link,db.Books.id == db.books_publishers_link.c.book, db.Publishers + elif sort == "authors": + order = [db.Authors.name.asc()] if order == "asc" else [db.Authors.name.desc()] + join = db.books_authors_link,db.Books.id == db.books_authors_link.c.book, db.Authors + elif sort == "languages": + order = [db.Languages.lang_code.asc()] if order == "asc" else [db.Languages.lang_code.desc()] + join = db.books_languages_link,db.Books.id == db.books_languages_link.c.book, db.Languages + elif order and sort in ["sort", "title", "authors_sort", "series_index"]: order = [text(sort + " " + order)] elif not state: order = [db.Books.timestamp.desc()] @@ -778,9 +794,9 @@ def list_books(): books = calibre_db.session.query(db.Books).filter(calibre_db.common_filters()).all() entries = calibre_db.get_checkbox_sorted(books, state, off, limit,order) elif search: - entries, filtered_count, __ = calibre_db.get_search_results(search, off, order, limit) + entries, filtered_count, __ = calibre_db.get_search_results(search, off, order, limit, *join) else: - entries, __, __ = calibre_db.fill_indexpage((int(off) / (int(limit)) + 1), limit, db.Books, True, order) + entries, __, __ = calibre_db.fill_indexpage((int(off) / (int(limit)) + 1), limit, db.Books, True, order, *join) for entry in entries: for index in range(0, len(entry.languages)): From c0a4addf30f265eef78235f17899a1254f5e4f6a Mon Sep 17 00:00:00 2001 From: Ozzie Isaacs Date: Sat, 17 Apr 2021 18:30:55 +0200 Subject: [PATCH 06/10] Cancel button in User edit now leads to the right page back #1938 --- cps/static/js/main.js | 14 ++++++++++++++ cps/static/js/table.js | 6 +++--- cps/templates/admin.html | 2 +- cps/templates/email_edit.html | 2 +- cps/templates/user_edit.html | 2 +- cps/templates/user_table.html | 3 +++ 6 files changed, 23 insertions(+), 6 deletions(-) diff --git a/cps/static/js/main.js b/cps/static/js/main.js index 81308c64..7231c51c 100644 --- a/cps/static/js/main.js +++ b/cps/static/js/main.js @@ -114,6 +114,20 @@ $(document).ready(function() { } }); +$(".session").click(function() { + window.sessionStorage.setItem("back", window.location.pathname); +}); + +$("#back").click(function() { + var loc = sessionStorage.getItem("back"); + if (!loc) { + loc = $(this).data("back"); + } + sessionStorage.removeItem("back"); + window.location.href = loc; + +}); + function confirmDialog(id, dialogid, dataValue, yesFn, noFn) { var $confirm = $("#" + dialogid); $confirm.modal('show'); diff --git a/cps/static/js/table.js b/cps/static/js/table.js index 7c4b04a7..d5a070c9 100644 --- a/cps/static/js/table.js +++ b/cps/static/js/table.js @@ -600,7 +600,7 @@ function responseHandler(res) { } function singleUserFormatter(value, row) { - return '' + this.buttontext + '' + return '' + this.buttontext + '' } function checkboxFormatter(value, row, index){ @@ -741,6 +741,6 @@ function queryParams(params) return params; } -function test(){ - console.log("hello"); +function storeLocation() { + window.sessionStorage.setItem("back", window.location.pathname); } diff --git a/cps/templates/admin.html b/cps/templates/admin.html index 5226151e..c06b7e72 100644 --- a/cps/templates/admin.html +++ b/cps/templates/admin.html @@ -26,7 +26,7 @@ {% for user in allUser %} {% if not user.role_anonymous() or config.config_anonbrowse %} - {{user.name}} + {{user.name}} {{user.email}} {{user.kindle_mail}} {{user.downloads.count()}} diff --git a/cps/templates/email_edit.html b/cps/templates/email_edit.html index ac1c36d2..59978ea9 100644 --- a/cps/templates/email_edit.html +++ b/cps/templates/email_edit.html @@ -66,7 +66,7 @@ {% if feature_support['gmail'] %} {% endif %} - {{_('Back')}} + {{_('Back')}} {% if g.allow_registration %}
diff --git a/cps/templates/user_edit.html b/cps/templates/user_edit.html index e2b184fc..846ad978 100644 --- a/cps/templates/user_edit.html +++ b/cps/templates/user_edit.html @@ -129,7 +129,7 @@
{{_('Save')}}
{% if not profile %} - {{_('Cancel')}} +
{{_('Cancel')}}
{% endif %} {% if g.user and g.user.role_admin() and not profile and not new_user and not content.role_anonymous() %}
{{_('Delete User')}}
diff --git a/cps/templates/user_table.html b/cps/templates/user_table.html index b8a9d2c2..c538dfa4 100644 --- a/cps/templates/user_table.html +++ b/cps/templates/user_table.html @@ -137,6 +137,9 @@ + {% endblock %} {% block modal %} {{ delete_confirm_modal() }} From 0138294b36923c89292be9ba86f96843dd0b16c1 Mon Sep 17 00:00:00 2001 From: subdiox Date: Sun, 18 Apr 2021 03:20:41 +0900 Subject: [PATCH 07/10] Fix an issue that space key doesn't work intentionally when inverting reading direction --- cps/static/js/kthoom.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cps/static/js/kthoom.js b/cps/static/js/kthoom.js index 56038fc6..613eed2b 100644 --- a/cps/static/js/kthoom.js +++ b/cps/static/js/kthoom.js @@ -532,11 +532,11 @@ function keyHandler(evt) { if (evt.shiftKey && atTop) { evt.preventDefault(); // If it's Shift + Space and the container is at the top of the page - showLeftPage(); + showPrevPage(); } else if (!evt.shiftKey && atBottom) { evt.preventDefault(); // If you're at the bottom of the page and you only pressed space - showRightPage(); + showNextPage(); container.scrollTop(0); } break; From 755eb1405bba48646ccdd48d06a05e50027a8ce2 Mon Sep 17 00:00:00 2001 From: BuildTools Date: Sun, 18 Apr 2021 04:25:45 +0900 Subject: [PATCH 08/10] Fix progress bar direction --- cps/static/css/kthoom.css | 15 ++++++++++++--- cps/static/js/kthoom.js | 30 ++++++++++++++++++++++++------ cps/templates/readcbr.html | 4 ++-- 3 files changed, 38 insertions(+), 11 deletions(-) diff --git a/cps/static/css/kthoom.css b/cps/static/css/kthoom.css index 233cfe94..267a2a84 100644 --- a/cps/static/css/kthoom.css +++ b/cps/static/css/kthoom.css @@ -84,15 +84,24 @@ body { #progress .bar-load, #progress .bar-read { display: flex; - align-items: flex-end; - justify-content: flex-end; position: absolute; top: 0; - left: 0; bottom: 0; transition: width 150ms ease-in-out; } +#progress .from-left { + left: 0; + align-items: flex-end; + justify-content: flex-end; +} + +#progress .from-right { + right: 0; + align-items: flex-start; + justify-content: flex-start; +} + #progress .bar-load { color: #000; background-color: #ccc; diff --git a/cps/static/js/kthoom.js b/cps/static/js/kthoom.js index 613eed2b..f6c1e4d7 100644 --- a/cps/static/js/kthoom.js +++ b/cps/static/js/kthoom.js @@ -171,7 +171,10 @@ kthoom.ImageFile = function(file) { function initProgressClick() { $("#progress").click(function(e) { - var page = Math.max(1, Math.ceil((e.offsetX / $(this).width()) * totalImages)) - 1; + var offset = $(this).offset(); + var x = e.pageX - offset.left; + var rate = settings.direction === 0 ? x / $(this).width() : 1 - x / $(this).width(); + var page = Math.max(1, Math.ceil(rate * totalImages)) - 1; currentImage = page; updatePage(); }); @@ -285,6 +288,22 @@ function updatePage() { } function updateProgress(loadPercentage) { + if (settings.direction === 0) { + $("#progress .bar-read") + .removeClass("from-right") + .addClass("from-left"); + $("#progress .bar-load") + .removeClass("from-right") + .addClass("from-left"); + } else { + $("#progress .bar-read") + .removeClass("from-left") + .addClass("from-right"); + $("#progress .bar-load") + .removeClass("from-left") + .addClass("from-right"); + } + // Set the load/unzip progress if it's passed in if (loadPercentage) { $("#progress .bar-load").css({ width: loadPercentage + "%" }); @@ -526,18 +545,17 @@ function keyHandler(evt) { break; case kthoom.Key.SPACE: var container = $("#mainContent"); - var atTop = container.scrollTop() === 0; - var atBottom = container.scrollTop() >= container[0].scrollHeight - container.height(); + // var atTop = container.scrollTop() === 0; + // var atBottom = container.scrollTop() >= container[0].scrollHeight - container.height(); - if (evt.shiftKey && atTop) { + if (evt.shiftKey) { evt.preventDefault(); // If it's Shift + Space and the container is at the top of the page showPrevPage(); - } else if (!evt.shiftKey && atBottom) { + } else { evt.preventDefault(); // If you're at the bottom of the page and you only pressed space showNextPage(); - container.scrollTop(0); } break; default: diff --git a/cps/templates/readcbr.html b/cps/templates/readcbr.html index 35943b34..5723947e 100644 --- a/cps/templates/readcbr.html +++ b/cps/templates/readcbr.html @@ -60,12 +60,12 @@ Fullscreen
-
+
Loading...
-
+
From 9cc14ac5c7029a3a64bbd5fee59a598cc5fcabb8 Mon Sep 17 00:00:00 2001 From: Ozzie Isaacs Date: Sun, 18 Apr 2021 11:33:14 +0200 Subject: [PATCH 09/10] Fix for #1905 prevent invalid json data in gmail_token --- cps/config_sql.py | 6 ++++-- cps/services/gmail.py | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/cps/config_sql.py b/cps/config_sql.py index 6e13489d..f7419ec9 100644 --- a/cps/config_sql.py +++ b/cps/config_sql.py @@ -20,6 +20,7 @@ from __future__ import division, print_function, unicode_literals import os import sys +import json from sqlalchemy import Column, String, Integer, SmallInteger, Boolean, BLOB, JSON from sqlalchemy.exc import OperationalError @@ -261,7 +262,6 @@ class _ConfigSQL(object): """ new_value = dictionary.get(field, default) if new_value is None: - # log.debug("_ConfigSQL set_from_dictionary field '%s' not found", field) return False if field not in self.__dict__: @@ -278,7 +278,6 @@ class _ConfigSQL(object): if current_value == new_value: return False - # log.debug("_ConfigSQL set_from_dictionary '%s' = %r (was %r)", field, new_value, current_value) setattr(self, field, new_value) return True @@ -383,6 +382,9 @@ def _migrate_table(session, orm_class): log.debug(alter_table) session.execute(alter_table) changed = True + except json.decoder.JSONDecodeError as e: + log.error("Database corrupt column: {}".format(column_name)) + log.debug(e) if changed: try: diff --git a/cps/services/gmail.py b/cps/services/gmail.py index 9524dd75..f85d56b0 100644 --- a/cps/services/gmail.py +++ b/cps/services/gmail.py @@ -53,6 +53,7 @@ def setup_gmail(token): 'expiry': creds.expiry.isoformat(), 'email': user_info } + return {} def get_user_info(credentials): user_info_service = build(serviceName='oauth2', version='v2',credentials=credentials) From 04ac5b69acc3b851f399a5b1af917593032a5ed2 Mon Sep 17 00:00:00 2001 From: Ozzie Isaacs Date: Sun, 18 Apr 2021 12:01:11 +0200 Subject: [PATCH 10/10] Further improvements on user list #1938 --- cps/static/js/table.js | 177 +++++++++++++++++----------------- cps/templates/user_table.html | 19 ++-- 2 files changed, 100 insertions(+), 96 deletions(-) diff --git a/cps/static/js/table.js b/cps/static/js/table.js index d5a070c9..3f3b431f 100644 --- a/cps/static/js/table.js +++ b/cps/static/js/table.js @@ -177,7 +177,6 @@ $(function() { }, }); - $("#domain_allow_submit").click(function(event) { event.preventDefault(); $("#domain_add_allow").ajaxForm(); @@ -388,7 +387,6 @@ $(function() { var target = $(e.relatedTarget).attr('id'); var dataId; $(e.relatedTarget).one('focus', function(e){$(this).blur();}); - //$(e.relatedTarget).blur(); if ($(e.relatedTarget).hasClass("button_head")) { dataId = $('#user-table').bootstrapTable('getSelections').map(a => a.id); } else { @@ -454,18 +452,28 @@ $(function() { $(this).next().text(elText); }); }, - onLoadSuccess: function () { - var guest = $(".editable[data-name='name'][data-value='Guest']"); - guest.editable("disable"); - $(".editable[data-name='locale'][data-pk='"+guest.data("pk")+"']").editable("disable"); - $("input[data-name='admin_role'][data-pk='"+guest.data("pk")+"']").prop("disabled", true); - $("input[data-name='passwd_role'][data-pk='"+guest.data("pk")+"']").prop("disabled", true); - $("input[data-name='edit_shelf_role'][data-pk='"+guest.data("pk")+"']").prop("disabled", true); - $("input[data-name='sidebar_read_and_unread'][data-pk='"+guest.data("pk")+"']").prop("disabled", true); - $(".user-remove[data-pk='"+guest.data("pk")+"']").hide(); + onPostHeader () { + deactivateHeaderButtons(); }, - onSort: function(a, b) { - console.log("huh"); + onLoadSuccess: function () { + loadSuccess(); + var element = $(".header_select"); + element.each(function() { + var item = $(this).parent(); + var parent = item.parent().parent(); + if (parent.prop('nodeName') === "TH") { + item.prependTo(parent); + } + }); + var element = $(".form-check"); + element.each(function() { + var item = $(this).parent(); + var parent = item.parent().parent(); + if (parent.prop('nodeName') === "TH") { + item.prependTo(parent); + } + }); + }, onColumnSwitch: function () { var visible = $("#user-table").bootstrapTable("getVisibleColumns"); @@ -491,7 +499,18 @@ $(function() { $("#user_delete_selection").click(function() { $("#user-table").bootstrapTable("uncheckAll"); }); - + $("#select_locale").on("change",function() { + selectHeader(this, "locale"); + }); + $("#select_default_language").on("change",function() { + selectHeader(this, "default_language"); + }); + $(".check_head").on("change",function() { + var val = $(this).val() === "on"; + var name = $(this).data("name"); + var data = $(this).data("val"); + checkboxHeader(val, name, data); + }); function user_handle (userId) { $.ajax({ method:"post", @@ -505,6 +524,7 @@ $(function() { timeout: 900, success:function(data) { $("#user-table").bootstrapTable("load", data); + loadSuccess(); } }); } @@ -560,10 +580,6 @@ function TableActions (value, row) { ].join(""); } -function editEntry(param) -{ - console.log(param); -} /* Function for deleting domain restrictions */ function RestrictionActions (value, row) { return [ @@ -582,7 +598,7 @@ function EbookActions (value, row) { ].join(""); } -/* Function for deleting books */ +/* Function for deleting Users */ function UserActions (value, row) { return [ "
", @@ -610,33 +626,55 @@ function checkboxFormatter(value, row, index){ return ''; } +function loadSuccess() { + var guest = $(".editable[data-name='name'][data-value='Guest']"); + guest.editable("disable"); + $(".editable[data-name='locale'][data-pk='"+guest.data("pk")+"']").editable("disable"); + $(".editable[data-name='locale'][data-pk='"+guest.data("pk")+"']").hide(); + $("input[data-name='admin_role'][data-pk='"+guest.data("pk")+"']").prop("disabled", true); + $("input[data-name='passwd_role'][data-pk='"+guest.data("pk")+"']").prop("disabled", true); + $("input[data-name='edit_shelf_role'][data-pk='"+guest.data("pk")+"']").prop("disabled", true); + $("input[data-name='sidebar_read_and_unread'][data-pk='"+guest.data("pk")+"']").prop("disabled", true); + $(".user-remove[data-pk='"+guest.data("pk")+"']").hide(); +} + +function handleListServerResponse (data, disableButtons) { + $("#flash_success").remove(); + $("#flash_danger").remove(); + if (!jQuery.isEmptyObject(data)) { + $( ".navbar" ).after( '
' + + '
'+data.message+'
' + + '
'); + } + $.ajax({ + method: "get", + url: window.location.pathname + "/../../ajax/listusers", + async: true, + timeout: 900, + success: function (data) { + $("#user-table").bootstrapTable("load", data); + if (disableButtons) { + deactivateHeaderButtons(); + } + loadSuccess(); + } + }); +} + + function checkboxChange(checkbox, userId, field, field_index) { $.ajax({ method: "post", url: window.location.pathname + "/../../ajax/editlistusers/" + field, data: {"pk": userId, "field_index": field_index, "value": checkbox.checked}, - success: function (data) { - if (!jQuery.isEmptyObject(data)) { - $("#flash_success").remove(); - $("#flash_danger").remove(); - $( ".navbar" ).after( '
' + - '
'+data.message+'
' + - '
'); - } - $.ajax({ - method: "get", - url: window.location.pathname + "/../../ajax/listusers", - async: true, - timeout: 900, - success: function (data) { - $("#user-table").bootstrapTable("load", data); - } - }); - } + error: function(data) { + handleListServerResponse({type:"danger", message:data.responseText}) + }, + success: handleListServerResponse }); } -function deactivateHeaderButtons(e) { +function deactivateHeaderButtons() { $("#user_delete_selection").addClass("disabled"); $("#user_delete_selection").attr("aria-disabled", true); $(".check_head").attr("aria-disabled", true); @@ -655,18 +693,10 @@ function selectHeader(element, field) { method: "post", url: window.location.pathname + "/../../ajax/editlistusers/" + field, data: {"pk": result, "value": element.value}, - success: function () { - $.ajax({ - method: "get", - url: window.location.pathname + "/../../ajax/listusers", - async: true, - timeout: 900, - success: function (data) { - $("#user-table").bootstrapTable("load", data); - deactivateHeaderButtons(); - } - }); - } + error: function (data) { + handleListServerResponse({type:"danger", message:data.responseText}) + }, + success: handleListServerResponse, }); }); } @@ -679,25 +709,12 @@ function checkboxHeader(CheckboxState, field, field_index) { method: "post", url: window.location.pathname + "/../../ajax/editlistusers/" + field, data: {"pk": result, "field_index": field_index, "value": CheckboxState}, - success: function () { - $.ajax({ - method: "get", - url: window.location.pathname + "/../../ajax/listusers", - async: true, - timeout: 900, - success: function (data) { - $("#user-table").bootstrapTable("load", data); - $("#user_delete_selection").addClass("disabled"); - $("#user_delete_selection").attr("aria-disabled", true); - $(".check_head").attr("aria-disabled", true); - $(".check_head").attr("disabled", true); - $(".check_head").prop('checked', false); - $(".button_head").attr("aria-disabled", true); - $(".button_head").addClass("disabled"); - $(".header_select").attr("disabled", true); - } - }); - } + error: function (data) { + handleListServerResponse({type:"danger", message:data.responseText}, true) + }, + success: function (data) { + handleListServerResponse (data, true) + }, }); }); } @@ -712,24 +729,10 @@ function deleteUser(a,b){ method:"post", url: window.location.pathname + "/../../ajax/deleteuser", data: {"userid":b}, - success:function(data) { - $("#flash_success").remove(); - $("#flash_danger").remove(); - if (!jQuery.isEmptyObject(data)) { - $( ".navbar" ).after( '
' + - '
'+data.message+'
' + - '
'); - } - $.ajax({ - method: "get", - url: window.location.pathname + "/../../ajax/listusers", - async: true, - timeout: 900, - success: function (data) { - $("#user-table").bootstrapTable("load", data); - } - }); - } + success: handleListServerResponse, + error: function (data) { + handleListServerResponse({type:"danger", message:data.responseText}) + }, }); } ); diff --git a/cps/templates/user_table.html b/cps/templates/user_table.html index c538dfa4..6cfa09cf 100644 --- a/cps/templates/user_table.html +++ b/cps/templates/user_table.html @@ -23,16 +23,18 @@ data-visible="{{element.get(array_field)}}" data-column="{{value.get(array_field)}}" data-formatter="checkboxFormatter"> -
+
+
-
+
+
{{show_text}} {%- endmacro %} @@ -48,14 +50,13 @@ data-editable-source={{url}} {% if validate %}data-edit-validate="{{ _('This Field is Required') }}"{% endif %}>
- {% for language in languages %} {% endfor %} -

- +
{{ show_text }} {%- endmacro %} @@ -71,13 +72,13 @@ data-editable-source={{url}} {% if validate %}data-edit-validate="{{ _('This Field is Required') }}"{% endif %}>
- {% for translation in translations %} {% endfor %} -

+
{{ show_text }} {%- endmacro %}