From 623372387d02edc32691dc2b374d25630bd5d629 Mon Sep 17 00:00:00 2001 From: ElQuimm <50202052+ElQuimm@users.noreply.github.com> Date: Wed, 23 Dec 2020 13:45:19 +0100 Subject: [PATCH 1/8] Update italian message.po Merry Christmas and Happy Holidays :-) --- cps/translations/it/LC_MESSAGES/messages.po | 64 ++++++++++----------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/cps/translations/it/LC_MESSAGES/messages.po b/cps/translations/it/LC_MESSAGES/messages.po index e336e029..47932cca 100644 --- a/cps/translations/it/LC_MESSAGES/messages.po +++ b/cps/translations/it/LC_MESSAGES/messages.po @@ -111,15 +111,15 @@ msgstr "LDAP User Object Filter contiene una parentesi senza la corrispettiva" #: cps/admin.py:619 #, python-format msgid "LDAP Member User Filter needs to Have One \"%s\" Format Identifier" -msgstr "" +msgstr "LDAP Member User Filter deve avere un \"%s\" Format Identifier" #: cps/admin.py:622 msgid "LDAP Member User Filter Has Unmatched Parenthesis" -msgstr "" +msgstr "LDAP Member User Filter contiene una parentesi senza la corrispettiva" #: cps/admin.py:630 msgid "LDAP CACertificate, Certificate or Key Location is not Valid, Please Enter Correct Path" -msgstr "" +msgstr "LDAP CACertificate, il certificato o la posizione della chiave non sono corretti, per favore indica il percorso corretto" #: cps/admin.py:656 msgid "Keyfile Location is not Valid, Please Enter Correct Path" @@ -205,7 +205,7 @@ msgstr "Si è verificato un errore imprevisto." #: cps/admin.py:944 msgid "Edit E-mail Server Settings" -msgstr "Modifica le impostazioni SMTP" +msgstr "Modifica le impostazioni del server e-mail" #: cps/admin.py:973 #, python-format @@ -560,7 +560,7 @@ msgid "Unknown Status" msgstr "Stato sconosciuto" #: cps/kobo_auth.py:130 -msgid "PLease access calibre-web from non localhost to get valid api_endpoint for kobo device" +msgid "Please access calibre-web from non localhost to get valid api_endpoint for kobo device" msgstr "Per favore, per ottenere un valido api-endpoint per Kobo, accedi a Calibre-web non da localhost" #: cps/kobo_auth.py:133 cps/kobo_auth.py:153 @@ -907,7 +907,7 @@ msgstr "Almeno un utente LDAP non è stato trovato nel database" #: cps/web.py:394 msgid "{} User Successfully Imported" -msgstr "" +msgstr "{} utente importato con successo" #: cps/templates/index.html:5 cps/web.py:691 msgid "Discover (Random Books)" @@ -1165,7 +1165,7 @@ msgstr "Downloads" #: cps/templates/admin.html:16 cps/templates/layout.html:77 msgid "Admin" -msgstr "Amministratore" +msgstr "Amministrazione" #: cps/templates/admin.html:17 cps/templates/login.html:12 #: cps/templates/login.html:13 cps/templates/user_edit.html:22 @@ -1211,7 +1211,7 @@ msgstr "Importa gli utenti LDAP" #: cps/templates/admin.html:53 msgid "E-mail Server Settings" -msgstr "Configurazione server SMTP" +msgstr "Configurazione server e-mail" #: cps/templates/admin.html:57 cps/templates/email_edit.html:11 msgid "SMTP Hostname" @@ -1295,7 +1295,7 @@ msgstr "Amministrazione" #: cps/templates/admin.html:144 msgid "Download Debug Package" -msgstr "" +msgstr "Scarica Debug Package" #: cps/templates/admin.html:145 msgid "View Logs" @@ -1374,32 +1374,32 @@ msgstr "Nella libreria" #: cps/templates/author.html:26 cps/templates/index.html:65 #: cps/templates/search.html:29 msgid "Sort according to book date, newest first" -msgstr "" +msgstr "Ordina secondo la data dei libri, prima i più recenti" #: cps/templates/author.html:27 cps/templates/index.html:66 #: cps/templates/search.html:30 msgid "Sort according to book date, oldest first" -msgstr "" +msgstr "Ordina secondo la data dei libri, prima i più vecchi" #: cps/templates/author.html:28 cps/templates/index.html:67 #: cps/templates/search.html:31 msgid "Sort title in alphabetical order" -msgstr "" +msgstr "Ordina i titoli in ordine alfabetico" #: cps/templates/author.html:29 cps/templates/index.html:68 #: cps/templates/search.html:32 msgid "Sort title in reverse alphabetical order" -msgstr "" +msgstr "Ordina i titoli in ordine alfabetico inverso" #: cps/templates/author.html:30 cps/templates/index.html:71 #: cps/templates/search.html:35 msgid "Sort according to publishing date, newest first" -msgstr "" +msgstr "Ordina secondo la data di pubblicazione, prima i più recenti" #: cps/templates/author.html:31 cps/templates/index.html:72 #: cps/templates/search.html:36 msgid "Sort according to publishing date, oldest first" -msgstr "" +msgstr "Ordina secondo la data di pubblicazione, prima i più vecchi" #: cps/templates/author.html:54 cps/templates/author.html:114 #: cps/templates/discover.html:27 cps/templates/index.html:26 @@ -1648,7 +1648,7 @@ msgstr "Indica gli editori" #: cps/templates/book_table.html:70 cps/templates/modal_dialogs.html:46 msgid "Are you really sure?" -msgstr "Sei davvero sicuro?" +msgstr "Sei veramente sicuro?" #: cps/templates/book_table.html:74 msgid "Books with Title will be merged from:" @@ -1712,7 +1712,7 @@ msgstr "Porta del server" #: cps/templates/config_edit.html:93 msgid "SSL certfile location (leave it empty for non-SSL Servers)" -msgstr "Percorso del file di certificato SSL (lascia vuoto per una configurazione del server senza SSL)" +msgstr "Percorso del file del certificato SSL (lascia vuoto per una configurazione del server senza SSL)" #: cps/templates/config_edit.html:100 msgid "SSL Keyfile location (leave it empty for non-SSL Servers)" @@ -1853,15 +1853,15 @@ msgstr "SSL" #: cps/templates/config_edit.html:267 msgid "LDAP CACertificate Path (Only needed for Client Certificate Authentication)" -msgstr "" +msgstr "Percorso del CACertificate LDAP (necessario unicamente in caso di Client Certificate Authentication)" #: cps/templates/config_edit.html:274 msgid "LDAP Certificate Path (Only needed for Client Certificate Authentication)" -msgstr "" +msgstr "Percorso del certificato LDAP (necessario unicamente in caso di Client Certificate Authentication)" #: cps/templates/config_edit.html:281 msgid "LDAP Keyfile Path (Only needed for Client Certificate Authentication)" -msgstr "" +msgstr "Percorso della chiave LDAP (necessario unicamente in caso di Client Certificate Authentication)" #: cps/templates/config_edit.html:290 msgid "LDAP Authentication" @@ -1893,7 +1893,7 @@ msgstr "LDAP Distinguished Name (DN)" #: cps/templates/config_edit.html:314 msgid "LDAP User Object Filter" -msgstr "LDAP User object filter" +msgstr "LDAP User Object Filter" #: cps/templates/config_edit.html:319 msgid "LDAP Server is OpenLDAP?" @@ -1917,19 +1917,19 @@ msgstr "LDAP Group Members Field" #: cps/templates/config_edit.html:335 msgid "LDAP Member User Filter Detection" -msgstr "" +msgstr "LDAP Member User Filter Detection" #: cps/templates/config_edit.html:337 msgid "Autodetect" -msgstr "" +msgstr "Autodetect" #: cps/templates/config_edit.html:338 msgid "Custom Filter" -msgstr "" +msgstr "Filtro personalizzato" #: cps/templates/config_edit.html:343 msgid "LDAP Member User Filter" -msgstr "" +msgstr "LDAP Member User Filter" #: cps/templates/config_edit.html:354 #, python-format @@ -2191,19 +2191,19 @@ msgstr "Ritorna alla pagina principale" #: cps/templates/index.html:69 cps/templates/search.html:33 msgid "Sort authors in alphabetical order" -msgstr "" +msgstr "Ordina gli autori in ordine alfabetico" #: cps/templates/index.html:70 cps/templates/search.html:34 msgid "Sort authors in reverse alphabetical order" -msgstr "" +msgstr "Ordina gli autori in ordine alfabetico inverso" #: cps/templates/index.html:74 msgid "Sort ascending according to series index" -msgstr "" +msgstr "Ordina in ordine ascendente secondo l'indice della serie" #: cps/templates/index.html:75 msgid "Sort descending according to series index" -msgstr "" +msgstr "Ordina in ordine discendente secondo l'indice della serie" #: cps/templates/index.xml:6 msgid "Start" @@ -2365,11 +2365,11 @@ msgstr "Mostra il log di accesso: " #: cps/templates/logviewer.html:18 msgid "Download Calibre-Web Log" -msgstr "" +msgstr "Scarica il log di Calibre-Web" #: cps/templates/logviewer.html:21 msgid "Download Access Log" -msgstr "" +msgstr "Scarica il log di accesso" #: cps/templates/modal_dialogs.html:6 msgid "Select Allowed/Denied Tags" @@ -2653,7 +2653,7 @@ msgstr "Serie in questa libreria" #: cps/templates/stats.html:29 msgid "System Statistics" -msgstr "" +msgstr "Statistiche del sistema" #: cps/templates/stats.html:33 msgid "Program Library" From 682c3b834fbe0f540097bde34a3bae728edb4c44 Mon Sep 17 00:00:00 2001 From: OzzieIsaacs Date: Sat, 2 Jan 2021 15:32:06 +0100 Subject: [PATCH 2/8] Revert unrar5 experiment --- cps/static/js/archive/archive.js | 13 ------------- cps/static/js/archive/unrar.js | 20 +++++++++----------- cps/static/js/kthoom.js | 11 +++-------- 3 files changed, 12 insertions(+), 32 deletions(-) diff --git a/cps/static/js/archive/archive.js b/cps/static/js/archive/archive.js index 06c05624..cb76321f 100644 --- a/cps/static/js/archive/archive.js +++ b/cps/static/js/archive/archive.js @@ -411,19 +411,6 @@ bitjs.archive = bitjs.archive || {}; return "unrar.js"; }; - /** - * Unrarrer5 - * @extends {bitjs.archive.Unarchiver} - * @constructor - */ - bitjs.archive.Unrarrer5 = function(arrayBuffer, optPathToBitJS) { - bitjs.base(this, arrayBuffer, optPathToBitJS); - }; - bitjs.inherits(bitjs.archive.Unrarrer5, bitjs.archive.Unarchiver); - bitjs.archive.Unrarrer5.prototype.getScriptFileName = function() { - return "unrar5.js"; - }; - /** * Untarrer * @extends {bitjs.archive.Unarchiver} diff --git a/cps/static/js/archive/unrar.js b/cps/static/js/archive/unrar.js index 3e2a45af..fadb791e 100644 --- a/cps/static/js/archive/unrar.js +++ b/cps/static/js/archive/unrar.js @@ -14,10 +14,10 @@ /* global VM_FIXEDGLOBALSIZE, VM_GLOBALMEMSIZE, MAXWINMASK, VM_GLOBALMEMADDR, MAXWINSIZE */ // This file expects to be invoked as a Worker (see onmessage below). -/*importScripts("../io/bitstream.js"); +importScripts("../io/bitstream.js"); importScripts("../io/bytebuffer.js"); importScripts("archive.js"); -importScripts("rarvm.js");*/ +importScripts("rarvm.js"); // Progress variables. var currentFilename = ""; @@ -29,21 +29,19 @@ var totalFilesInArchive = 0; // Helper functions. var info = function(str) { - console.log(str); - // postMessage(new bitjs.archive.UnarchiveInfoEvent(str)); + postMessage(new bitjs.archive.UnarchiveInfoEvent(str)); }; var err = function(str) { - console.log(str); - // postMessage(new bitjs.archive.UnarchiveErrorEvent(str)); + postMessage(new bitjs.archive.UnarchiveErrorEvent(str)); }; var postProgress = function() { - /*postMessage(new bitjs.archive.UnarchiveProgressEvent( + postMessage(new bitjs.archive.UnarchiveProgressEvent( currentFilename, currentFileNumber, currentBytesUnarchivedInFile, currentBytesUnarchived, totalUncompressedBytesInArchive, - totalFilesInArchive));*/ + totalFilesInArchive)); }; // shows a byte value as its hex representation @@ -1300,7 +1298,7 @@ var unrar = function(arrayBuffer) { totalUncompressedBytesInArchive = 0; totalFilesInArchive = 0; - //postMessage(new bitjs.archive.UnarchiveStartEvent()); + postMessage(new bitjs.archive.UnarchiveStartEvent()); var bstream = new bitjs.io.BitStream(arrayBuffer, false /* rtl */); var header = new RarVolumeHeader(bstream); @@ -1350,7 +1348,7 @@ var unrar = function(arrayBuffer) { localfile.unrar(); if (localfile.isValid) { - // postMessage(new bitjs.archive.UnarchiveExtractEvent(localfile)); + postMessage(new bitjs.archive.UnarchiveExtractEvent(localfile)); postProgress(); } } @@ -1360,7 +1358,7 @@ var unrar = function(arrayBuffer) { } else { err("Invalid RAR file"); } - // postMessage(new bitjs.archive.UnarchiveFinishEvent()); + postMessage(new bitjs.archive.UnarchiveFinishEvent()); }; // event.data.file has the ArrayBuffer. diff --git a/cps/static/js/kthoom.js b/cps/static/js/kthoom.js index bbb3fead..33a2ac0e 100644 --- a/cps/static/js/kthoom.js +++ b/cps/static/js/kthoom.js @@ -162,15 +162,10 @@ function initProgressClick() { function loadFromArrayBuffer(ab) { var start = (new Date).getTime(); var h = new Uint8Array(ab, 0, 10); - unrar5(ab); var pathToBitJS = "../../static/js/archive/"; var lastCompletion = 0; - /*if (h[0] === 0x52 && h[1] === 0x61 && h[2] === 0x72 && h[3] === 0x21) { //Rar! - if (h[7] === 0x01) { - unarchiver = new bitjs.archive.Unrarrer(ab, pathToBitJS); - } else { - unarchiver = new bitjs.archive.Unrarrer5(ab, pathToBitJS); - } + if (h[0] === 0x52 && h[1] === 0x61 && h[2] === 0x72 && h[3] === 0x21) { //Rar! + unarchiver = new bitjs.archive.Unrarrer(ab, pathToBitJS); } else if (h[0] === 80 && h[1] === 75) { //PK (Zip) unarchiver = new bitjs.archive.Unzipper(ab, pathToBitJS); } else if (h[0] === 255 && h[1] === 216) { // JPEG @@ -234,7 +229,7 @@ function loadFromArrayBuffer(ab) { unarchiver.start(); } else { alert("Some error"); - }*/ + } } function scrollTocToActive() { From 4578af7a6d4f9c6f1bff660dd83c50712faed6ea Mon Sep 17 00:00:00 2001 From: Ozzieisaacs Date: Sat, 2 Jan 2021 20:38:11 +0100 Subject: [PATCH 3/8] Fix export of logfiles (#1794) --- cps/debug_info.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/cps/debug_info.py b/cps/debug_info.py index aae97001..8f0cdeee 100644 --- a/cps/debug_info.py +++ b/cps/debug_info.py @@ -21,7 +21,12 @@ import shutil import glob import zipfile import json -import io +from io import BytesIO +try: + from StringIO import StringIO +except ImportError: + from io import StringIO + import os from flask import send_file @@ -32,11 +37,12 @@ from .about import collect_stats log = logger.create() def assemble_logfiles(file_name): - log_list = glob.glob(file_name + '*') - wfd = io.StringIO() + log_list = sorted(glob.glob(file_name + '*'), reverse=True) + wfd = StringIO() for f in log_list: with open(f, 'r') as fd: shutil.copyfileobj(fd, wfd) + wfd.seek(0) return send_file(wfd, as_attachment=True, attachment_filename=os.path.basename(file_name)) @@ -47,7 +53,7 @@ def send_debug(): for element in [logger.LOG_TO_STDOUT, logger.LOG_TO_STDERR]: if element in file_list: file_list.remove(element) - memory_zip = io.BytesIO() + memory_zip = BytesIO() with zipfile.ZipFile(memory_zip, 'w', compression=zipfile.ZIP_DEFLATED) as zf: zf.writestr('settings.txt', json.dumps(config.toDict())) zf.writestr('libs.txt', json.dumps(collect_stats())) From 5cce01215fe03cdb81d31c36df9c3f4199ae7f41 Mon Sep 17 00:00:00 2001 From: Ozzieisaacs Date: Sun, 3 Jan 2021 09:53:34 +0100 Subject: [PATCH 4/8] Code refactoring ub.session.commit() Code cosmentics admin.py --- cps/admin.py | 327 ++++++++++++++++++++------------------------- cps/editbooks.py | 2 +- cps/kobo.py | 45 ++----- cps/kobo_auth.py | 12 +- cps/oauth_bb.py | 33 ++--- cps/remotelogin.py | 13 +- cps/shelf.py | 12 +- cps/ub.py | 13 +- cps/web.py | 20 +-- 9 files changed, 195 insertions(+), 282 deletions(-) diff --git a/cps/admin.py b/cps/admin.py index 33939ef9..328ee606 100644 --- a/cps/admin.py +++ b/cps/admin.py @@ -105,6 +105,7 @@ def unconfigured(f): return inner + @admi.before_app_request def before_request(): if current_user.is_authenticated: @@ -118,8 +119,10 @@ def before_request(): g.config_authors_max = config.config_authors_max g.shelves_access = ub.session.query(ub.Shelf).filter( or_(ub.Shelf.is_public == 1, ub.Shelf.user_id == current_user.id)).order_by(ub.Shelf.name).all() - if not config.db_configured and request.endpoint not in ( - 'admin.basic_configuration', 'login', 'admin.config_pathchooser') and '/static/' not in request.path: + if '/static/' not in request.path and not config.db_configured and \ + request.endpoint not in ('admin.basic_configuration', + 'login', + 'admin.config_pathchooser'): return redirect(url_for('admin.basic_configuration')) @@ -201,12 +204,12 @@ def configuration(): @login_required @admin_required def view_configuration(): - readColumn = calibre_db.session.query(db.Custom_Columns)\ - .filter(and_(db.Custom_Columns.datatype == 'bool', db.Custom_Columns.mark_for_delete == 0)).all() - restrictColumns= calibre_db.session.query(db.Custom_Columns)\ - .filter(and_(db.Custom_Columns.datatype == 'text', db.Custom_Columns.mark_for_delete == 0)).all() - return render_title_template("config_view_edit.html", conf=config, readColumns=readColumn, - restrictColumns=restrictColumns, + read_column = calibre_db.session.query(db.Custom_Columns)\ + .filter(and_(db.Custom_Columns.datatype == 'bool', db.Custom_Columns.mark_for_delete == 0)).all() + restrict_columns = calibre_db.session.query(db.Custom_Columns)\ + .filter(and_(db.Custom_Columns.datatype == 'text', db.Custom_Columns.mark_for_delete == 0)).all() + return render_title_template("config_view_edit.html", conf=config, readColumns=read_column, + restrictColumns=restrict_columns, title=_(u"UI Configuration"), page="uiconfig") @@ -248,7 +251,7 @@ def update_view_configuration(): @admi.route("/ajax/loaddialogtexts/") @login_required def load_dialogtexts(element_id): - texts = { "header": "", "main": "" } + texts = {"header": "", "main": ""} if element_id == "config_delete_kobo_token": texts["main"] = _('Do you really want to delete the Kobo Token?') elif element_id == "btndeletedomain": @@ -271,11 +274,7 @@ def edit_domain(allow): vals = request.form.to_dict() answer = ub.session.query(ub.Registration).filter(ub.Registration.id == vals['pk']).first() answer.domain = vals['value'].replace('*', '%').replace('?', '_').lower() - try: - ub.session.commit() - except OperationalError: - ub.session.rollback() - return "" + return ub.session_commit("Registering Domains edited {}".format(answer.domain)) @admi.route("/ajax/adddomain/", methods=['POST']) @@ -288,10 +287,7 @@ def add_domain(allow): if not check: new_domain = ub.Registration(domain=domain_name, allow=allow) ub.session.add(new_domain) - try: - ub.session.commit() - except OperationalError: - ub.session.rollback() + ub.session_commit("Registering Domains added {}".format(domain_name)) return "" @@ -302,18 +298,12 @@ def delete_domain(): try: domain_id = request.form.to_dict()['domainid'].replace('*', '%').replace('?', '_').lower() ub.session.query(ub.Registration).filter(ub.Registration.id == domain_id).delete() - try: - ub.session.commit() - except OperationalError: - ub.session.rollback() + ub.session_commit("Registering Domains deleted {}".format(domain_id)) # If last domain was deleted, add all domains by default - if not ub.session.query(ub.Registration).filter(ub.Registration.allow==1).count(): - new_domain = ub.Registration(domain="%.%",allow=1) + if not ub.session.query(ub.Registration).filter(ub.Registration.allow == 1).count(): + new_domain = ub.Registration(domain="%.%", allow=1) ub.session.add(new_domain) - try: - ub.session.commit() - except OperationalError: - ub.session.rollback() + ub.session_commit("Last Registering Domain deleted, added *.* as default") except KeyError: pass return "" @@ -330,7 +320,8 @@ def list_domain(allow): response.headers["Content-Type"] = "application/json; charset=utf-8" return response -@admi.route("/ajax/editrestriction/", defaults={"user_id":0}, methods=['POST']) + +@admi.route("/ajax/editrestriction/", defaults={"user_id": 0}, methods=['POST']) @admi.route("/ajax/editrestriction//", methods=['POST']) @login_required @admin_required @@ -339,12 +330,12 @@ def edit_restriction(res_type, user_id): if element['id'].startswith('a'): if res_type == 0: # Tags as template elementlist = config.list_allowed_tags() - elementlist[int(element['id'][1:])]=element['Element'] + elementlist[int(element['id'][1:])] = element['Element'] config.config_allowed_tags = ','.join(elementlist) config.save() if res_type == 1: # CustomC elementlist = config.list_allowed_column_values() - elementlist[int(element['id'][1:])]=element['Element'] + elementlist[int(element['id'][1:])] = element['Element'] config.config_allowed_column_value = ','.join(elementlist) config.save() if res_type == 2: # Tags per user @@ -353,33 +344,27 @@ def edit_restriction(res_type, user_id): else: usr = current_user elementlist = usr.list_allowed_tags() - elementlist[int(element['id'][1:])]=element['Element'] + elementlist[int(element['id'][1:])] = element['Element'] usr.allowed_tags = ','.join(elementlist) - try: - ub.session.commit() - except OperationalError: - ub.session.rollback() + ub.session_commit("Changed allowed tags of user {} to {}".format(usr.nickname, usr.allowed_tags)) if res_type == 3: # CColumn per user if isinstance(user_id, int): usr = ub.session.query(ub.User).filter(ub.User.id == int(user_id)).first() else: usr = current_user elementlist = usr.list_allowed_column_values() - elementlist[int(element['id'][1:])]=element['Element'] + elementlist[int(element['id'][1:])] = element['Element'] usr.allowed_column_value = ','.join(elementlist) - try: - ub.session.commit() - except OperationalError: - ub.session.rollback() + ub.session_commit("Changed allowed columns of user {} to {}".format(usr.nickname, usr.allowed_column_value)) if element['id'].startswith('d'): if res_type == 0: # Tags as template elementlist = config.list_denied_tags() - elementlist[int(element['id'][1:])]=element['Element'] + elementlist[int(element['id'][1:])] = element['Element'] config.config_denied_tags = ','.join(elementlist) config.save() if res_type == 1: # CustomC elementlist = config.list_denied_column_values() - elementlist[int(element['id'][1:])]=element['Element'] + elementlist[int(element['id'][1:])] = element['Element'] config.config_denied_column_value = ','.join(elementlist) config.save() if res_type == 2: # Tags per user @@ -388,26 +373,21 @@ def edit_restriction(res_type, user_id): else: usr = current_user elementlist = usr.list_denied_tags() - elementlist[int(element['id'][1:])]=element['Element'] + elementlist[int(element['id'][1:])] = element['Element'] usr.denied_tags = ','.join(elementlist) - try: - ub.session.commit() - except OperationalError: - ub.session.rollback() + ub.session_commit("Changed denied tags of user {} to {}".format(usr.nickname, usr.denied_tags)) if res_type == 3: # CColumn per user if isinstance(user_id, int): usr = ub.session.query(ub.User).filter(ub.User.id == int(user_id)).first() else: usr = current_user elementlist = usr.list_denied_column_values() - elementlist[int(element['id'][1:])]=element['Element'] + elementlist[int(element['id'][1:])] = element['Element'] usr.denied_column_value = ','.join(elementlist) - try: - ub.session.commit() - except OperationalError: - ub.session.rollback() + ub.session_commit("Changed denied columns of user {} to {}".format(usr.nickname, usr.denied_column_value)) return "" + def restriction_addition(element, list_func): elementlist = list_func() if elementlist == ['']: @@ -424,7 +404,7 @@ def restriction_deletion(element, list_func): return ','.join(elementlist) -@admi.route("/ajax/addrestriction/", defaults={"user_id":0}, methods=['POST']) +@admi.route("/ajax/addrestriction/", defaults={"user_id": 0}, methods=['POST']) @admi.route("/ajax/addrestriction//", methods=['POST']) @login_required @admin_required @@ -451,16 +431,10 @@ def add_restriction(res_type, user_id): usr = current_user if 'submit_allow' in element: usr.allowed_tags = restriction_addition(element, usr.list_allowed_tags) - try: - ub.session.commit() - except OperationalError: - ub.session.rollback() + ub.session_commit("Changed allowed tags of user {} to {}".format(usr.nickname, usr.list_allowed_tags)) elif 'submit_deny' in element: usr.denied_tags = restriction_addition(element, usr.list_denied_tags) - try: - ub.session.commit() - except OperationalError: - ub.session.rollback() + ub.session_commit("Changed denied tags of user {} to {}".format(usr.nickname, usr.list_denied_tags)) if res_type == 3: # CustomC per user if isinstance(user_id, int): usr = ub.session.query(ub.User).filter(ub.User.id == int(user_id)).first() @@ -468,19 +442,16 @@ def add_restriction(res_type, user_id): usr = current_user if 'submit_allow' in element: usr.allowed_column_value = restriction_addition(element, usr.list_allowed_column_values) - try: - ub.session.commit() - except OperationalError: - ub.session.rollback() + ub.session_commit("Changed allowed columns of user {} to {}".format(usr.nickname, + usr.list_allowed_column_values)) elif 'submit_deny' in element: usr.denied_column_value = restriction_addition(element, usr.list_denied_column_values) - try: - ub.session.commit() - except OperationalError: - ub.session.rollback() + ub.session_commit("Changed denied columns of user {} to {}".format(usr.nickname, + usr.list_denied_column_values)) return "" -@admi.route("/ajax/deleterestriction/", defaults={"user_id":0}, methods=['POST']) + +@admi.route("/ajax/deleterestriction/", defaults={"user_id": 0}, methods=['POST']) @admi.route("/ajax/deleterestriction//", methods=['POST']) @login_required @admin_required @@ -507,16 +478,10 @@ def delete_restriction(res_type, user_id): usr = current_user if element['id'].startswith('a'): usr.allowed_tags = restriction_deletion(element, usr.list_allowed_tags) - try: - ub.session.commit() - except OperationalError: - ub.session.rollback() + ub.session_commit("Deleted allowed tags of user {}: {}".format(usr.nickname, usr.list_allowed_tags)) elif element['id'].startswith('d'): usr.denied_tags = restriction_deletion(element, usr.list_denied_tags) - try: - ub.session.commit() - except OperationalError: - ub.session.rollback() + ub.session_commit("Deleted denied tags of user {}: {}".format(usr.nickname, usr.list_allowed_tags)) elif res_type == 3: # Columns per user if isinstance(user_id, int): usr = ub.session.query(ub.User).filter(ub.User.id == int(user_id)).first() @@ -524,62 +489,61 @@ def delete_restriction(res_type, user_id): usr = current_user if element['id'].startswith('a'): usr.allowed_column_value = restriction_deletion(element, usr.list_allowed_column_values) - try: - ub.session.commit() - except OperationalError: - ub.session.rollback() + ub.session_commit("Deleted allowed columns of user {}: {}".format(usr.nickname, + usr.list_allowed_column_values)) + elif element['id'].startswith('d'): usr.denied_column_value = restriction_deletion(element, usr.list_denied_column_values) - try: - ub.session.commit() - except OperationalError: - ub.session.rollback() + ub.session_commit("Deleted denied columns of user {}: {}".format(usr.nickname, + usr.list_denied_column_values)) return "" -@admi.route("/ajax/listrestriction/", defaults={"user_id":0}) + +@admi.route("/ajax/listrestriction/", defaults={"user_id": 0}) @admi.route("/ajax/listrestriction//") @login_required @admin_required def list_restriction(res_type, user_id): if res_type == 0: # Tags as template restrict = [{'Element': x, 'type':_('Deny'), 'id': 'd'+str(i) } - for i,x in enumerate(config.list_denied_tags()) if x != '' ] - allow = [{'Element': x, 'type':_('Allow'), 'id': 'a'+str(i) } - for i,x in enumerate(config.list_allowed_tags()) if x != ''] + for i,x in enumerate(config.list_denied_tags()) if x != ''] + allow = [{'Element': x, 'type': _('Allow'), 'id': 'a'+str(i)} + for i, x in enumerate(config.list_allowed_tags()) if x != ''] json_dumps = restrict + allow elif res_type == 1: # CustomC as template - restrict = [{'Element': x, 'type':_('Deny'), 'id': 'd'+str(i) } - for i,x in enumerate(config.list_denied_column_values()) if x != '' ] - allow = [{'Element': x, 'type':_('Allow'), 'id': 'a'+str(i) } - for i,x in enumerate(config.list_allowed_column_values()) if x != ''] + restrict = [{'Element': x, 'type': _('Deny'), 'id': 'd'+str(i)} + for i, x in enumerate(config.list_denied_column_values()) if x != ''] + allow = [{'Element': x, 'type': _('Allow'), 'id': 'a'+str(i)} + for i, x in enumerate(config.list_allowed_column_values()) if x != ''] json_dumps = restrict + allow elif res_type == 2: # Tags per user if isinstance(user_id, int): usr = ub.session.query(ub.User).filter(ub.User.id == user_id).first() else: usr = current_user - restrict = [{'Element': x, 'type':_('Deny'), 'id': 'd'+str(i) } - for i,x in enumerate(usr.list_denied_tags()) if x != '' ] - allow = [{'Element': x, 'type':_('Allow'), 'id': 'a'+str(i) } - for i,x in enumerate(usr.list_allowed_tags()) if x != ''] + restrict = [{'Element': x, 'type': _('Deny'), 'id': 'd'+str(i)} + for i, x in enumerate(usr.list_denied_tags()) if x != ''] + allow = [{'Element': x, 'type': _('Allow'), 'id': 'a'+str(i)} + for i, x in enumerate(usr.list_allowed_tags()) if x != ''] json_dumps = restrict + allow elif res_type == 3: # CustomC per user if isinstance(user_id, int): - usr = ub.session.query(ub.User).filter(ub.User.id==user_id).first() + usr = ub.session.query(ub.User).filter(ub.User.id == user_id).first() else: usr = current_user - restrict = [{'Element': x, 'type':_('Deny'), 'id': 'd'+str(i) } - for i,x in enumerate(usr.list_denied_column_values()) if x != '' ] - allow = [{'Element': x, 'type':_('Allow'), 'id': 'a'+str(i) } - for i,x in enumerate(usr.list_allowed_column_values()) if x != ''] + restrict = [{'Element': x, 'type': _('Deny'), 'id': 'd'+str(i)} + for i, x in enumerate(usr.list_denied_column_values()) if x != ''] + allow = [{'Element': x, 'type': _('Allow'), 'id': 'a'+str(i)} + for i, x in enumerate(usr.list_allowed_column_values()) if x != ''] json_dumps = restrict + allow else: - json_dumps="" + json_dumps = "" js = json.dumps(json_dumps) response = make_response(js.replace("'", '"')) response.headers["Content-Type"] = "application/json; charset=utf-8" return response + @admi.route("/basicconfig/pathchooser/") @unconfigured def config_pathchooser(): @@ -587,12 +551,14 @@ def config_pathchooser(): return pathchooser() abort(403) + @admi.route("/ajax/pathchooser/") @login_required @admin_required def ajax_pathchooser(): return pathchooser() + def pathchooser(): browse_for = "folder" folder_only = request.args.get('folder', False) == "true" @@ -605,20 +571,20 @@ def pathchooser(): else: oldfile = "" - abs = False + absolute = False if os.path.isdir(path): - #if os.path.isabs(path): + # if os.path.isabs(path): cwd = os.path.realpath(path) - abs = True - #else: + absolute = True + # else: # cwd = os.path.relpath(path) else: cwd = os.getcwd() cwd = os.path.normpath(os.path.realpath(cwd)) parentdir = os.path.dirname(cwd) - if not abs: + if not absolute: if os.path.realpath(cwd) == os.path.realpath("/"): cwd = os.path.relpath(cwd) else: @@ -705,8 +671,8 @@ def _configuration_gdrive_helper(to_save): config.config_use_google_drive = False gdrive_secrets = {} - gdriveError = gdriveutils.get_error_text(gdrive_secrets) - if "config_use_google_drive" in to_save and not config.config_use_google_drive and not gdriveError: + gdrive_error = gdriveutils.get_error_text(gdrive_secrets) + if "config_use_google_drive" in to_save and not config.config_use_google_drive and not gdrive_error: with open(gdriveutils.CLIENT_SECRETS, 'r') as settings: gdrive_secrets = json.load(settings)['web'] if not gdrive_secrets: @@ -718,10 +684,11 @@ def _configuration_gdrive_helper(to_save): ) # always show google drive settings, but in case of error deny support - config.config_use_google_drive = (not gdriveError) and ("config_use_google_drive" in to_save) + config.config_use_google_drive = (not gdrive_error) and ("config_use_google_drive" in to_save) if _config_string(to_save, "config_google_drive_folder"): gdriveutils.deleteDatabaseOnChange() - return gdriveError + return gdrive_error + def _configuration_oauth_helper(to_save): active_oauths = 0 @@ -744,22 +711,24 @@ def _configuration_oauth_helper(to_save): "active": element["active"]}) return reboot_required -def _configuration_logfile_helper(to_save, gdriveError): + +def _configuration_logfile_helper(to_save, gdrive_error): reboot_required = False reboot_required |= _config_int(to_save, "config_log_level") reboot_required |= _config_string(to_save, "config_logfile") if not logger.is_valid_logfile(config.config_logfile): return reboot_required, \ - _configuration_result(_('Logfile Location is not Valid, Please Enter Correct Path'), gdriveError) + _configuration_result(_('Logfile Location is not Valid, Please Enter Correct Path'), gdrive_error) reboot_required |= _config_checkbox_int(to_save, "config_access_log") reboot_required |= _config_string(to_save, "config_access_logfile") if not logger.is_valid_logfile(config.config_access_logfile): return reboot_required, \ - _configuration_result(_('Access Logfile Location is not Valid, Please Enter Correct Path'), gdriveError) + _configuration_result(_('Access Logfile Location is not Valid, Please Enter Correct Path'), gdrive_error) return reboot_required, None -def _configuration_ldap_helper(to_save, gdriveError): + +def _configuration_ldap_helper(to_save, gdrive_error): reboot_required = False reboot_required |= _config_string(to_save, "config_ldap_provider_url") reboot_required |= _config_int(to_save, "config_ldap_port") @@ -786,33 +755,33 @@ def _configuration_ldap_helper(to_save, gdriveError): or not config.config_ldap_dn \ or not config.config_ldap_user_object: return reboot_required, _configuration_result(_('Please Enter a LDAP Provider, ' - 'Port, DN and User Object Identifier'), gdriveError) + 'Port, DN and User Object Identifier'), gdrive_error) if config.config_ldap_authentication > constants.LDAP_AUTH_ANONYMOUS: if config.config_ldap_authentication > constants.LDAP_AUTH_UNAUTHENTICATE: if not config.config_ldap_serv_username or not bool(config.config_ldap_serv_password): return reboot_required, _configuration_result('Please Enter a LDAP Service Account and Password', - gdriveError) + gdrive_error) else: if not config.config_ldap_serv_username: - return reboot_required, _configuration_result('Please Enter a LDAP Service Account', gdriveError) + return reboot_required, _configuration_result('Please Enter a LDAP Service Account', gdrive_error) if config.config_ldap_group_object_filter: if config.config_ldap_group_object_filter.count("%s") != 1: return reboot_required, \ _configuration_result(_('LDAP Group Object Filter Needs to Have One "%s" Format Identifier'), - gdriveError) + gdrive_error) if config.config_ldap_group_object_filter.count("(") != config.config_ldap_group_object_filter.count(")"): return reboot_required, _configuration_result(_('LDAP Group Object Filter Has Unmatched Parenthesis'), - gdriveError) + gdrive_error) if config.config_ldap_user_object.count("%s") != 1: return reboot_required, \ _configuration_result(_('LDAP User Object Filter needs to Have One "%s" Format Identifier'), - gdriveError) + gdrive_error) if config.config_ldap_user_object.count("(") != config.config_ldap_user_object.count(")"): return reboot_required, _configuration_result(_('LDAP User Object Filter Has Unmatched Parenthesis'), - gdriveError) + gdrive_error) if to_save["ldap_import_user_filter"] == '0': config.config_ldap_member_user_object = "" @@ -820,10 +789,10 @@ def _configuration_ldap_helper(to_save, gdriveError): if config.config_ldap_member_user_object.count("%s") != 1: return reboot_required, \ _configuration_result(_('LDAP Member User Filter needs to Have One "%s" Format Identifier'), - gdriveError) + gdrive_error) if config.config_ldap_member_user_object.count("(") != config.config_ldap_member_user_object.count(")"): return reboot_required, _configuration_result(_('LDAP Member User Filter Has Unmatched Parenthesis'), - gdriveError) + gdrive_error) if config.config_ldap_cacert_path or config.config_ldap_cert_path or config.config_ldap_key_path: if not (os.path.isfile(config.config_ldap_cacert_path) and @@ -832,7 +801,7 @@ def _configuration_ldap_helper(to_save, gdriveError): return reboot_required, \ _configuration_result(_('LDAP CACertificate, Certificate or Key Location is not Valid, ' 'Please Enter Correct Path'), - gdriveError) + gdrive_error) return reboot_required, None @@ -840,7 +809,7 @@ def _configuration_update_helper(configured): reboot_required = False db_change = False to_save = request.form.to_dict() - gdriveError = None + gdrive_error = None to_save['config_calibre_dir'] = re.sub(r'[\\/]metadata\.db$', '', @@ -849,26 +818,26 @@ def _configuration_update_helper(configured): try: db_change |= _config_string(to_save, "config_calibre_dir") - # Google drive setup - gdriveError = _configuration_gdrive_helper(to_save) + # gdrive_error drive setup + gdrive_error = _configuration_gdrive_helper(to_save) reboot_required |= _config_int(to_save, "config_port") reboot_required |= _config_string(to_save, "config_keyfile") if config.config_keyfile and not os.path.isfile(config.config_keyfile): return _configuration_result(_('Keyfile Location is not Valid, Please Enter Correct Path'), - gdriveError, + gdrive_error, configured) reboot_required |= _config_string(to_save, "config_certfile") if config.config_certfile and not os.path.isfile(config.config_certfile): return _configuration_result(_('Certfile Location is not Valid, Please Enter Correct Path'), - gdriveError, + gdrive_error, configured) _config_checkbox_int(to_save, "config_uploading") # Reboot on config_anonbrowse with enabled ldap, as decoraters are changed in this case - reboot_required |= (_config_checkbox_int(to_save, "config_anonbrowse") + reboot_required |= (_config_checkbox_int(to_save, "config_anonbrowse") and config.config_login_type == constants.LOGIN_LDAP) _config_checkbox_int(to_save, "config_public_reg") _config_checkbox_int(to_save, "config_register_email") @@ -888,9 +857,9 @@ def _configuration_update_helper(configured): reboot_required |= _config_int(to_save, "config_login_type") - #LDAP configurator, + # LDAP configurator, if config.config_login_type == constants.LOGIN_LDAP: - reboot, message = _configuration_ldap_helper(to_save, gdriveError) + reboot, message = _configuration_ldap_helper(to_save, gdrive_error) if message: return message reboot_required |= reboot @@ -899,7 +868,7 @@ def _configuration_update_helper(configured): _config_checkbox(to_save, "config_remote_login") if not config.config_remote_login: - ub.session.query(ub.RemoteAuthToken).filter(ub.RemoteAuthToken.token_type==0).delete() + ub.session.query(ub.RemoteAuthToken).filter(ub.RemoteAuthToken.token_type == 0).delete() # Goodreads configuration _config_checkbox(to_save, "config_use_goodreads") @@ -920,7 +889,7 @@ def _configuration_update_helper(configured): if config.config_login_type == constants.LOGIN_OAUTH: reboot_required |= _configuration_oauth_helper(to_save) - reboot, message = _configuration_logfile_helper(to_save, gdriveError) + reboot, message = _configuration_logfile_helper(to_save, gdrive_error) if message: return message reboot_required |= reboot @@ -929,10 +898,10 @@ def _configuration_update_helper(configured): if "config_rarfile_location" in to_save: unrar_status = helper.check_unrar(config.config_rarfile_location) if unrar_status: - return _configuration_result(unrar_status, gdriveError, configured) + return _configuration_result(unrar_status, gdrive_error, configured) except (OperationalError, InvalidRequestError): ub.session.rollback() - _configuration_result(_(u"Settings DB is not Writeable"), gdriveError, configured) + _configuration_result(_(u"Settings DB is not Writeable"), gdrive_error, configured) try: metadata_db = os.path.join(config.config_calibre_dir, "metadata.db") @@ -940,12 +909,12 @@ def _configuration_update_helper(configured): gdriveutils.downloadFile(None, "metadata.db", metadata_db) db_change = True except Exception as e: - return _configuration_result('%s' % e, gdriveError, configured) + return _configuration_result('%s' % e, gdrive_error, configured) if db_change: if not calibre_db.setup_db(config, ub.app_DB_path): return _configuration_result(_('DB Location is not Valid, Please Enter Correct Path'), - gdriveError, + gdrive_error, configured) if not os.access(os.path.join(config.config_calibre_dir, "metadata.db"), os.W_OK): flash(_(u"DB is not Writeable"), category="warning") @@ -955,16 +924,16 @@ def _configuration_update_helper(configured): if reboot_required: web_server.stop(True) - return _configuration_result(None, gdriveError, configured) + return _configuration_result(None, gdrive_error, configured) -def _configuration_result(error_flash=None, gdriveError=None, configured=True): +def _configuration_result(error_flash=None, gdrive_error=None, configured=True): gdrive_authenticate = not is_gdrive_ready() gdrivefolders = [] - if gdriveError is None: - gdriveError = gdriveutils.get_error_text() - if gdriveError: - gdriveError = _(gdriveError) + if gdrive_error is None: + gdrive_error = gdriveutils.get_error_text() + if gdrive_error: + gdrive_error = _(gdrive_error) else: # if config.config_use_google_drive and\ if not gdrive_authenticate and gdrive_support: @@ -977,14 +946,20 @@ def _configuration_result(error_flash=None, gdriveError=None, configured=True): flash(error_flash, category="error") show_login_button = False - return render_title_template("config_edit.html", config=config, provider=oauthblueprints, - show_back_button=show_back_button, show_login_button=show_login_button, - show_authenticate_google_drive=gdrive_authenticate, filepicker=configured, - gdriveError=gdriveError, gdrivefolders=gdrivefolders, feature_support=feature_support, + return render_title_template("config_edit.html", + config=config, + provider=oauthblueprints, + show_back_button=show_back_button, + show_login_button=show_login_button, + show_authenticate_google_drive=gdrive_authenticate, + filepicker=configured, + gdriveError=gdrive_error, + gdrivefolders=gdrivefolders, + feature_support=feature_support, title=_(u"Basic Configuration"), page="config") -def _handle_new_user(to_save, content,languages, translations, kobo_support): +def _handle_new_user(to_save, content, languages, translations, kobo_support): content.default_language = to_save["default_language"] # content.mature_content = "Show_mature_content" in to_save content.locale = to_save.get("locale", content.locale) @@ -1025,10 +1000,7 @@ def _handle_new_user(to_save, content,languages, translations, kobo_support): content.allowed_column_value = config.config_allowed_column_value content.denied_column_value = config.config_denied_column_value ub.session.add(content) - try: - ub.session.commit() - except OperationalError: - ub.session.rollback() + ub.session.commit() flash(_(u"User '%(user)s' created", user=content.nickname), category="success") return redirect(url_for('admin.admin')) except IntegrityError: @@ -1039,15 +1011,12 @@ def _handle_new_user(to_save, content,languages, translations, kobo_support): flash(_(u"Settings DB is not Writeable"), category="error") -def _handle_edit_user(to_save, content,languages, translations, kobo_support): +def _handle_edit_user(to_save, content, languages, translations, kobo_support): if "delete" in to_save: if ub.session.query(ub.User).filter(ub.User.role.op('&')(constants.ROLE_ADMIN) == constants.ROLE_ADMIN, ub.User.id != content.id).count(): ub.session.query(ub.User).filter(ub.User.id == content.id).delete() - try: - ub.session.commit() - except OperationalError: - ub.session.rollback() + ub.session_commit() flash(_(u"User '%(nick)s' deleted", nick=content.nickname), category="success") return redirect(url_for('admin.admin')) else: @@ -1055,8 +1024,7 @@ def _handle_edit_user(to_save, content,languages, translations, kobo_support): return redirect(url_for('admin.admin')) else: if not ub.session.query(ub.User).filter(ub.User.role.op('&')(constants.ROLE_ADMIN) == constants.ROLE_ADMIN, - ub.User.id != content.id).count() and \ - not 'admin_role' in to_save: + ub.User.id != content.id).count() and 'admin_role' not in to_save: flash(_(u"No admin user remaining, can't remove admin role", nick=content.nickname), category="error") return redirect(url_for('admin.admin')) @@ -1075,7 +1043,7 @@ def _handle_edit_user(to_save, content,languages, translations, kobo_support): value = element['visibility'] if value in val and not content.check_visibility(value): content.sidebar_view |= value - elif not value in val and content.check_visibility(value): + elif value not in val and content.check_visibility(value): content.sidebar_view &= ~value if "Show_detail_random" in to_save: @@ -1122,10 +1090,7 @@ def _handle_edit_user(to_save, content,languages, translations, kobo_support): if "kindle_mail" in to_save and to_save["kindle_mail"] != content.kindle_mail: content.kindle_mail = to_save["kindle_mail"] try: - try: - ub.session.commit() - except OperationalError: - ub.session.rollback() + ub.session_commit() flash(_(u"User '%(nick)s' updated", nick=content.nickname), category="success") except IntegrityError: ub.session.rollback() @@ -1247,9 +1212,8 @@ def reset_user_password(user_id): @login_required @admin_required def view_logfile(): - logfiles = {} - logfiles[0] = logger.get_logfile(config.config_logfile) - logfiles[1] = logger.get_accesslogfile(config.config_access_logfile) + logfiles = {0: logger.get_logfile(config.config_logfile), + 1: logger.get_accesslogfile(config.config_access_logfile)} return render_title_template("logviewer.html", title=_(u"Logfile viewer"), accesslog_enable=config.config_access_log, @@ -1273,6 +1237,7 @@ def send_logfile(logtype): else: return "" + @admi.route("/admin/logdownload/") @login_required @admin_required @@ -1332,7 +1297,7 @@ def get_updater_status(): elif request.method == "GET": try: status['status'] = updater_thread.get_update_status() - if status['status'] == -1: + if status['status'] == -1: status['status'] = 7 except Exception: status['status'] = 11 @@ -1390,7 +1355,7 @@ def import_ldap_users(): kindlemail = '' if 'mail' in user_data: useremail = user_data['mail'][0].decode('utf-8') - if (len(user_data['mail']) > 1): + if len(user_data['mail']) > 1: kindlemail = user_data['mail'][1].decode('utf-8') else: @@ -1414,7 +1379,7 @@ def import_ldap_users(): ub.session.add(content) try: ub.session.commit() - imported +=1 + imported += 1 except Exception as e: log.warning("Failed to create LDAP user: %s - %s", user, e) ub.session.rollback() @@ -1428,19 +1393,21 @@ def import_ldap_users(): def extract_user_data_from_field(user, field): - match = re.search(field + "=([\d\s\w-]+)", user, re.IGNORECASE | re.UNICODE) + match = re.search(field + r"=([\d\s\w-]+)", user, re.IGNORECASE | re.UNICODE) if match: return match.group(1) else: raise Exception("Could Not Parse LDAP User: {}".format(user)) -def extract_dynamic_field_from_filter(user, filter): - match = re.search("([a-zA-Z0-9-]+)=%s", filter, re.IGNORECASE | re.UNICODE) + +def extract_dynamic_field_from_filter(user, filtr): + match = re.search("([a-zA-Z0-9-]+)=%s", filtr, re.IGNORECASE | re.UNICODE) if match: return match.group(1) else: raise Exception("Could Not Parse LDAP Userfield: {}", user) -def extract_user_identifier(user, filter): - dynamic_field = extract_dynamic_field_from_filter(user, filter) + +def extract_user_identifier(user, filtr): + dynamic_field = extract_dynamic_field_from_filter(user, filtr) return extract_user_data_from_field(user, dynamic_field) diff --git a/cps/editbooks.py b/cps/editbooks.py index 08ee93b1..b20ec5c8 100644 --- a/cps/editbooks.py +++ b/cps/editbooks.py @@ -240,7 +240,7 @@ def delete_book(book_id, book_format, jsonResponse): ub.session.query(ub.BookShelf).filter(ub.BookShelf.book_id == book_id).delete() ub.session.query(ub.ReadBook).filter(ub.ReadBook.book_id == book_id).delete() ub.delete_download(book_id) - ub.session.commit() + ub.session_commit() # check if only this book links to: # author, language, series, tags, custom columns diff --git a/cps/kobo.py b/cps/kobo.py index 029592fe..df69cd74 100644 --- a/cps/kobo.py +++ b/cps/kobo.py @@ -462,10 +462,7 @@ def HandleTagCreate(): items_unknown_to_calibre = add_items_to_shelf(items, shelf) if items_unknown_to_calibre: log.debug("Received request to add unknown books to a collection. Silently ignoring items.") - try: - ub.session.commit() - except OperationalError: - ub.session.rollback() + ub.session_commit() return make_response(jsonify(str(shelf.uuid)), 201) @@ -497,10 +494,7 @@ def HandleTagUpdate(tag_id): shelf.name = name ub.session.merge(shelf) - try: - ub.session.commit() - except OperationalError: - ub.session.rollback() + ub.session_commit() return make_response(' ', 200) @@ -552,11 +546,7 @@ def HandleTagAddItem(tag_id): log.debug("Received request to add an unknown book to a collection. Silently ignoring item.") ub.session.merge(shelf) - try: - ub.session.commit() - except OperationalError: - ub.session.rollback() - + ub.session_commit() return make_response('', 201) @@ -596,10 +586,7 @@ def HandleTagRemoveItem(tag_id): shelf.books.filter(ub.BookShelf.book_id == book.id).delete() except KeyError: items_unknown_to_calibre.append(item) - try: - ub.session.commit() - except OperationalError: - ub.session.rollback() + ub.session_commit() if items_unknown_to_calibre: log.debug("Received request to remove an unknown book to a collecition. Silently ignoring item.") @@ -645,10 +632,7 @@ def sync_shelves(sync_token, sync_results): "ChangedTag": tag }) sync_token.tags_last_modified = new_tags_last_modified - try: - ub.session.commit() - except OperationalError: - ub.session.rollback() + ub.session_commit() # Creates a Kobo "Tag" object from a ub.Shelf object @@ -729,10 +713,7 @@ def HandleStateRequest(book_uuid): abort(400, description="Malformed request data is missing 'ReadingStates' key") ub.session.merge(kobo_reading_state) - try: - ub.session.commit() - except OperationalError: - ub.session.rollback() + ub.session_commit() return jsonify({ "RequestResult": "Success", "UpdateResults": [update_results_response], @@ -770,10 +751,10 @@ def get_or_create_reading_state(book_id): kobo_reading_state.statistics = ub.KoboStatistics() book_read.kobo_reading_state = kobo_reading_state ub.session.add(book_read) - try: - ub.session.commit() - except OperationalError: - ub.session.rollback() + #try: + # ub.session.commit() + #except OperationalError: + # ub.session.rollback() return book_read.kobo_reading_state @@ -876,11 +857,7 @@ def HandleBookDeletionRequest(book_uuid): archived_book.last_modified = datetime.datetime.utcnow() ub.session.merge(archived_book) - try: - ub.session.commit() - except OperationalError: - ub.session.rollback() - + ub.session_commit() return ("", 204) diff --git a/cps/kobo_auth.py b/cps/kobo_auth.py index 3288bb73..ba35c78b 100644 --- a/cps/kobo_auth.py +++ b/cps/kobo_auth.py @@ -148,10 +148,7 @@ def generate_auth_token(user_id): auth_token.token_type = 1 ub.session.add(auth_token) - try: - ub.session.commit() - except OperationalError: - ub.session.rollback() + ub.session_commit() return render_title_template( "generate_kobo_auth_url.html", title=_(u"Kobo Setup"), @@ -168,8 +165,5 @@ def delete_auth_token(user_id): # Invalidate any prevously generated Kobo Auth token for this user. ub.session.query(ub.RemoteAuthToken).filter(ub.RemoteAuthToken.user_id == user_id)\ .filter(ub.RemoteAuthToken.token_type==1).delete() - try: - ub.session.commit() - except OperationalError: - ub.session.rollback() - return "" + + return ub.session_commit() diff --git a/cps/oauth_bb.py b/cps/oauth_bb.py index cafef3eb..b6474758 100644 --- a/cps/oauth_bb.py +++ b/cps/oauth_bb.py @@ -85,11 +85,7 @@ def register_user_with_oauth(user=None): except NoResultFound: # no found, return error return - try: - ub.session.commit() - except Exception as e: - log.debug_or_exception(e) - ub.session.rollback() + ub.session_commit("User {} with OAuth for provider {} registered".format(user.nickname, oauth_key)) def logout_oauth_user(): @@ -101,19 +97,12 @@ def logout_oauth_user(): if ub.oauth_support: oauthblueprints = [] if not ub.session.query(ub.OAuthProvider).count(): - oauthProvider = ub.OAuthProvider() - oauthProvider.provider_name = "github" - oauthProvider.active = False - ub.session.add(oauthProvider) - ub.session.commit() - oauthProvider = ub.OAuthProvider() - oauthProvider.provider_name = "google" - oauthProvider.active = False - ub.session.add(oauthProvider) - try: - ub.session.commit() - except OperationalError: - ub.session.rollback() + for provider in ("github", "google"): + oauthProvider = ub.OAuthProvider() + oauthProvider.provider_name = provider + oauthProvider.active = False + ub.session.add(oauthProvider) + ub.session_commit("{} Blueprint Created".format(provider)) oauth_ids = ub.session.query(ub.OAuthProvider).all() ele1 = dict(provider_name='github', @@ -203,12 +192,8 @@ if ub.oauth_support: provider_user_id=provider_user_id, token=token, ) - try: - ub.session.add(oauth_entry) - ub.session.commit() - except Exception as e: - log.debug_or_exception(e) - ub.session.rollback() + ub.session.add(oauth_entry) + ub.session_commit() # Disable Flask-Dance's default behavior for saving the OAuth token # Value differrs depending on flask-dance version diff --git a/cps/remotelogin.py b/cps/remotelogin.py index a448e5fc..d9e7388f 100644 --- a/cps/remotelogin.py +++ b/cps/remotelogin.py @@ -59,8 +59,7 @@ def remote_login_required(f): def remote_login(): auth_token = ub.RemoteAuthToken() ub.session.add(auth_token) - ub.session.commit() - + ub.session_commit() verify_url = url_for('remotelogin.verify_token', token=auth_token.auth_token, _external=true) log.debug(u"Remot Login request with token: %s", auth_token.auth_token) return render_title_template('remote_login.html', title=_(u"login"), token=auth_token.auth_token, @@ -80,9 +79,9 @@ def verify_token(token): return redirect(url_for('web.index')) # Token expired - if datetime.now() > auth_token.expiration: + elif datetime.now() > auth_token.expiration: ub.session.delete(auth_token) - ub.session.commit() + ub.session_commit() flash(_(u"Token has expired"), category="error") log.error(u"Remote Login token expired") @@ -91,7 +90,7 @@ def verify_token(token): # Update token with user information auth_token.user_id = current_user.id auth_token.verified = True - ub.session.commit() + ub.session_commit() flash(_(u"Success! Please return to your device"), category="success") log.debug(u"Remote Login token for userid %s verified", auth_token.user_id) @@ -114,7 +113,7 @@ def token_verified(): # Token expired elif datetime.now() > auth_token.expiration: ub.session.delete(auth_token) - ub.session.commit() + ub.session_commit() data['status'] = 'error' data['message'] = _(u"Token has expired") @@ -127,7 +126,7 @@ def token_verified(): login_user(user) ub.session.delete(auth_token) - ub.session.commit() + ub.session_commit("User {} logged in via remotelogin, token deleted".format(user.nickname)) data['status'] = 'success' log.debug(u"Remote Login for userid %s succeded", user.id) diff --git a/cps/shelf.py b/cps/shelf.py index 6dae333c..1088129c 100644 --- a/cps/shelf.py +++ b/cps/shelf.py @@ -320,12 +320,7 @@ def delete_shelf_helper(cur_shelf): ub.session.delete(cur_shelf) ub.session.query(ub.BookShelf).filter(ub.BookShelf.shelf == shelf_id).delete() ub.session.add(ub.ShelfArchive(uuid=cur_shelf.uuid, user_id=cur_shelf.user_id)) - try: - ub.session.commit() - log.info("successfully deleted %s", cur_shelf) - except OperationalError: - ub.session.rollback() - + ub.session_commit("successfully deleted Shelf {}".format(cur_shelf.name)) @shelf.route("/shelf/delete/") @@ -388,10 +383,7 @@ def change_shelf_order(shelf_id, order): book = ub.session.query(ub.BookShelf).filter(ub.BookShelf.shelf == shelf_id) \ .filter(ub.BookShelf.book_id == entry.id).first() book.order = index - try: - ub.session.commit() - except OperationalError: - ub.session.rollback() + ub.session_commit("Shelf-id:{} - Order changed".format(shelf_id)) def render_show_shelf(shelf_type, shelf_id, page_no, sort_param): shelf = ub.session.query(ub.Shelf).filter(ub.Shelf.id == shelf_id).first() diff --git a/cps/ub.py b/cps/ub.py index f11b77b9..03720387 100644 --- a/cps/ub.py +++ b/cps/ub.py @@ -46,8 +46,9 @@ from sqlalchemy.orm.attributes import flag_modified from sqlalchemy.orm import backref, relationship, sessionmaker, Session, scoped_session from werkzeug.security import generate_password_hash -from . import constants +from . import constants, logger +log = logger.create() session = None app_DB_path = None @@ -695,3 +696,13 @@ def dispose(): old_session.bind.dispose() except Exception: pass + +def session_commit(success=None): + try: + session.commit() + if success: + log.info(success) + except (exc.OperationalError, exc.InvalidRequestError) as e: + session.rollback() + log.debug_or_exception(e) + return "" diff --git a/cps/web.py b/cps/web.py index 8a52f97a..82378de8 100644 --- a/cps/web.py +++ b/cps/web.py @@ -135,10 +135,7 @@ def bookmark(book_id, book_format): ub.Bookmark.book_id == book_id, ub.Bookmark.format == book_format)).delete() if not bookmark_key: - try: - ub.session.commit() - except OperationalError: - ub.session.rollback() + ub.session_commit() return "", 204 lbookmark = ub.Bookmark(user_id=current_user.id, @@ -146,10 +143,7 @@ def bookmark(book_id, book_format): format=book_format, bookmark_key=bookmark_key) ub.session.merge(lbookmark) - try: - ub.session.commit() - except OperationalError: - ub.session.rollback() + ub.session_commit("Bookmark for user {} in book {} created".format(current_user.id, book_id)) return "", 201 @@ -174,10 +168,7 @@ def toggle_read(book_id): kobo_reading_state.statistics = ub.KoboStatistics() book.kobo_reading_state = kobo_reading_state ub.session.merge(book) - try: - ub.session.commit() - except OperationalError: - ub.session.rollback() + ub.session_commit("Book {} readbit toggled".format(book_id)) else: try: calibre_db.update_title_sort(config) @@ -211,10 +202,7 @@ def toggle_archived(book_id): archived_book = ub.ArchivedBook(user_id=current_user.id, book_id=book_id) archived_book.is_archived = True ub.session.merge(archived_book) - try: - ub.session.commit() - except OperationalError: - ub.session.rollback() + ub.session_commit("Book {} archivebit toggled".format(book_id)) return "" From cd60db417c827fe37e83dd3cd4e54ab75867ada8 Mon Sep 17 00:00:00 2001 From: Ozzieisaacs Date: Sun, 3 Jan 2021 11:53:06 +0100 Subject: [PATCH 5/8] Code refactor shelf handling --- cps/shelf.py | 126 ++++++++++++++++++++++----------------------------- 1 file changed, 54 insertions(+), 72 deletions(-) diff --git a/cps/shelf.py b/cps/shelf.py index 1088129c..fc4c1cd3 100644 --- a/cps/shelf.py +++ b/cps/shelf.py @@ -27,7 +27,7 @@ import sys from flask import Blueprint, request, flash, redirect, url_for from flask_babel import gettext as _ from flask_login import login_required, current_user -from sqlalchemy.sql.expression import func +from sqlalchemy.sql.expression import func, true from sqlalchemy.exc import OperationalError, InvalidRequestError from . import logger, ub, calibre_db, db @@ -221,96 +221,78 @@ def remove_from_shelf(shelf_id, book_id): @login_required def create_shelf(): shelf = ub.Shelf() - if request.method == "POST": - to_save = request.form.to_dict() - if "is_public" in to_save: - shelf.is_public = 1 - shelf.name = to_save["title"] - shelf.user_id = int(current_user.id) - - is_shelf_name_unique = False - if shelf.is_public == 1: - is_shelf_name_unique = ub.session.query(ub.Shelf) \ - .filter((ub.Shelf.name == to_save["title"]) & (ub.Shelf.is_public == 1)) \ - .first() is None - - if not is_shelf_name_unique: - flash(_(u"A public shelf with the name '%(title)s' already exists.", title=to_save["title"]), - category="error") - else: - is_shelf_name_unique = ub.session.query(ub.Shelf) \ - .filter((ub.Shelf.name == to_save["title"]) & (ub.Shelf.is_public == 0) & - (ub.Shelf.user_id == int(current_user.id)))\ - .first() is None - - if not is_shelf_name_unique: - flash(_(u"A private shelf with the name '%(title)s' already exists.", title=to_save["title"]), - category="error") - - if is_shelf_name_unique: - try: - ub.session.add(shelf) - ub.session.commit() - flash(_(u"Shelf %(title)s created", title=to_save["title"]), category="success") - return redirect(url_for('shelf.show_shelf', shelf_id=shelf.id)) - except (OperationalError, InvalidRequestError): - ub.session.rollback() - flash(_(u"Settings DB is not Writeable"), category="error") - except Exception: - ub.session.rollback() - flash(_(u"There was an error"), category="error") - return render_title_template('shelf_edit.html', shelf=shelf, title=_(u"Create a Shelf"), page="shelfcreate") - else: - return render_title_template('shelf_edit.html', shelf=shelf, title=_(u"Create a Shelf"), page="shelfcreate") + create_edit_shelf(shelf) + return render_title_template('shelf_edit.html', shelf=shelf, title=_(u"Create a Shelf"), page="shelfcreate") @shelf.route("/shelf/edit/", methods=["GET", "POST"]) @login_required def edit_shelf(shelf_id): shelf = ub.session.query(ub.Shelf).filter(ub.Shelf.id == shelf_id).first() + create_edit_shelf(shelf, shelf_id) + return render_title_template('shelf_edit.html', shelf=shelf, title=_(u"Edit a shelf"), page="shelfedit") + + +# if shelf ID is set, we are editing a shelf +def create_edit_shelf(shelf, shelf_id=False): if request.method == "POST": to_save = request.form.to_dict() - - is_shelf_name_unique = False - if shelf.is_public == 1: - is_shelf_name_unique = ub.session.query(ub.Shelf) \ - .filter((ub.Shelf.name == to_save["title"]) & (ub.Shelf.is_public == 1)) \ - .filter(ub.Shelf.id != shelf_id) \ - .first() is None - - if not is_shelf_name_unique: - flash(_(u"A public shelf with the name '%(title)s' already exists.", title=to_save["title"]), - category="error") - else: - is_shelf_name_unique = ub.session.query(ub.Shelf) \ - .filter((ub.Shelf.name == to_save["title"]) & (ub.Shelf.is_public == 0) & - (ub.Shelf.user_id == int(current_user.id)))\ - .filter(ub.Shelf.id != shelf_id)\ - .first() is None - - if not is_shelf_name_unique: - flash(_(u"A private shelf with the name '%(title)s' already exists.", title=to_save["title"]), - category="error") - - if is_shelf_name_unique: - shelf.name = to_save["title"] - shelf.last_modified = datetime.utcnow() + if check_shelf_is_unique(shelf, to_save, shelf_id): if "is_public" in to_save: shelf.is_public = 1 else: shelf.is_public = 0 + shelf.name = to_save["title"] + shelf.last_modified = datetime.utcnow() + if not shelf_id: + shelf.user_id = int(current_user.id) try: + if shelf_id: + ub.session.add(shelf) + shelf_action = "changed" + flash_text = _(u"Shelf %(title)s changed", title=to_save["title"]) + else: + shelf_action = "created" + flash_text = _(u"Shelf %(title)s created", title=to_save["title"]) ub.session.commit() - flash(_(u"Shelf %(title)s changed", title=to_save["title"]), category="success") - except (OperationalError, InvalidRequestError): + log.info(u"Shelf {} {}".format(to_save["title"], shelf_action)) + flash(flash_text, category="success") + return redirect(url_for('shelf.show_shelf', shelf_id=shelf.id)) + except (OperationalError, InvalidRequestError) as e: ub.session.rollback() + log.debug_or_exception(e) flash(_(u"Settings DB is not Writeable"), category="error") - except Exception: + except Exception as e: ub.session.rollback() + log.debug_or_exception(e) flash(_(u"There was an error"), category="error") - return render_title_template('shelf_edit.html', shelf=shelf, title=_(u"Edit a shelf"), page="shelfedit") + + +def check_shelf_is_unique(shelf, to_save, shelf_id=False): + if shelf_id: + ident = ub.Shelf.id != shelf_id else: - return render_title_template('shelf_edit.html', shelf=shelf, title=_(u"Edit a shelf"), page="shelfedit") + ident = true() + if shelf.is_public == 1: + is_shelf_name_unique = ub.session.query(ub.Shelf) \ + .filter((ub.Shelf.name == to_save["title"]) & (ub.Shelf.is_public == 1)) \ + .filter(ident) \ + .first() is None + + if not is_shelf_name_unique: + flash(_(u"A public shelf with the name '%(title)s' already exists.", title=to_save["title"]), + category="error") + else: + is_shelf_name_unique = ub.session.query(ub.Shelf) \ + .filter((ub.Shelf.name == to_save["title"]) & (ub.Shelf.is_public == 0) & + (ub.Shelf.user_id == int(current_user.id))) \ + .filter(ident) \ + .first() is None + + if not is_shelf_name_unique: + flash(_(u"A private shelf with the name '%(title)s' already exists.", title=to_save["title"]), + category="error") + return is_shelf_name_unique def delete_shelf_helper(cur_shelf): From 56388145b5f902355620d5313ec1a91e077447e4 Mon Sep 17 00:00:00 2001 From: OzzieIsaacs Date: Sun, 3 Jan 2021 15:40:17 +0100 Subject: [PATCH 6/8] Fixes from testrun --- cps/kobo.py | 5 +---- cps/shelf.py | 21 ++++++++++++--------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/cps/kobo.py b/cps/kobo.py index df69cd74..06e89112 100644 --- a/cps/kobo.py +++ b/cps/kobo.py @@ -751,10 +751,7 @@ def get_or_create_reading_state(book_id): kobo_reading_state.statistics = ub.KoboStatistics() book_read.kobo_reading_state = kobo_reading_state ub.session.add(book_read) - #try: - # ub.session.commit() - #except OperationalError: - # ub.session.rollback() + ub.session_commit() return book_read.kobo_reading_state diff --git a/cps/shelf.py b/cps/shelf.py index fc4c1cd3..d09f1c2a 100644 --- a/cps/shelf.py +++ b/cps/shelf.py @@ -221,20 +221,18 @@ def remove_from_shelf(shelf_id, book_id): @login_required def create_shelf(): shelf = ub.Shelf() - create_edit_shelf(shelf) - return render_title_template('shelf_edit.html', shelf=shelf, title=_(u"Create a Shelf"), page="shelfcreate") + return create_edit_shelf(shelf, title=_(u"Create a Shelf"), page="shelfcreate") @shelf.route("/shelf/edit/", methods=["GET", "POST"]) @login_required def edit_shelf(shelf_id): shelf = ub.session.query(ub.Shelf).filter(ub.Shelf.id == shelf_id).first() - create_edit_shelf(shelf, shelf_id) - return render_title_template('shelf_edit.html', shelf=shelf, title=_(u"Edit a shelf"), page="shelfedit") + return create_edit_shelf(shelf, title=_(u"Edit a shelf"), page="shelfedit", shelf_id=shelf_id) # if shelf ID is set, we are editing a shelf -def create_edit_shelf(shelf, shelf_id=False): +def create_edit_shelf(shelf, title, page, shelf_id=False): if request.method == "POST": to_save = request.form.to_dict() if check_shelf_is_unique(shelf, to_save, shelf_id): @@ -247,13 +245,13 @@ def create_edit_shelf(shelf, shelf_id=False): if not shelf_id: shelf.user_id = int(current_user.id) try: - if shelf_id: + if not shelf_id: ub.session.add(shelf) - shelf_action = "changed" - flash_text = _(u"Shelf %(title)s changed", title=to_save["title"]) - else: shelf_action = "created" flash_text = _(u"Shelf %(title)s created", title=to_save["title"]) + else: + shelf_action = "changed" + flash_text = _(u"Shelf %(title)s changed", title=to_save["title"]) ub.session.commit() log.info(u"Shelf {} {}".format(to_save["title"], shelf_action)) flash(flash_text, category="success") @@ -266,6 +264,7 @@ def create_edit_shelf(shelf, shelf_id=False): ub.session.rollback() log.debug_or_exception(e) flash(_(u"There was an error"), category="error") + return render_title_template('shelf_edit.html', shelf=shelf, title=title, page=page) def check_shelf_is_unique(shelf, to_save, shelf_id=False): @@ -316,11 +315,13 @@ def delete_shelf(shelf_id): flash(_(u"Settings DB is not Writeable"), category="error") return redirect(url_for('web.index')) + @shelf.route("/simpleshelf/") @login_required_if_no_ano def show_simpleshelf(shelf_id): return render_show_shelf(2, shelf_id, 1, None) + @shelf.route("/shelf/", defaults={"sort_param": "order", 'page': 1}) @shelf.route("/shelf//", defaults={'page': 1}) @shelf.route("/shelf///") @@ -358,6 +359,7 @@ def order_shelf(shelf_id): title=_(u"Change order of Shelf: '%(name)s'", name=shelf.name), shelf=shelf, page="shelforder") + def change_shelf_order(shelf_id, order): result = calibre_db.session.query(db.Books).join(ub.BookShelf,ub.BookShelf.book_id == db.Books.id)\ .filter(ub.BookShelf.shelf == shelf_id).order_by(*order).all() @@ -367,6 +369,7 @@ def change_shelf_order(shelf_id, order): book.order = index ub.session_commit("Shelf-id:{} - Order changed".format(shelf_id)) + def render_show_shelf(shelf_type, shelf_id, page_no, sort_param): shelf = ub.session.query(ub.Shelf).filter(ub.Shelf.id == shelf_id).first() From 760fbbb3570c44ac2893a933aa5ac07a8499b432 Mon Sep 17 00:00:00 2001 From: OzzieIsaacs Date: Sun, 3 Jan 2021 16:41:38 +0100 Subject: [PATCH 7/8] Fix shelf time_created vs. time_last_modified --- cps/shelf.py | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/cps/shelf.py b/cps/shelf.py index d09f1c2a..5c6037ac 100644 --- a/cps/shelf.py +++ b/cps/shelf.py @@ -235,23 +235,22 @@ def edit_shelf(shelf_id): def create_edit_shelf(shelf, title, page, shelf_id=False): if request.method == "POST": to_save = request.form.to_dict() + if "is_public" in to_save: + shelf.is_public = 1 + else: + shelf.is_public = 0 if check_shelf_is_unique(shelf, to_save, shelf_id): - if "is_public" in to_save: - shelf.is_public = 1 - else: - shelf.is_public = 0 shelf.name = to_save["title"] - shelf.last_modified = datetime.utcnow() + # shelf.last_modified = datetime.utcnow() if not shelf_id: shelf.user_id = int(current_user.id) + ub.session.add(shelf) + shelf_action = "created" + flash_text = _(u"Shelf %(title)s created", title=to_save["title"]) + else: + shelf_action = "changed" + flash_text = _(u"Shelf %(title)s changed", title=to_save["title"]) try: - if not shelf_id: - ub.session.add(shelf) - shelf_action = "created" - flash_text = _(u"Shelf %(title)s created", title=to_save["title"]) - else: - shelf_action = "changed" - flash_text = _(u"Shelf %(title)s changed", title=to_save["title"]) ub.session.commit() log.info(u"Shelf {} {}".format(to_save["title"], shelf_action)) flash(flash_text, category="success") From a659f2e49d6413e2285a4473b44d380e09ac543f Mon Sep 17 00:00:00 2001 From: Ozzieisaacs Date: Sun, 3 Jan 2021 19:27:24 +0100 Subject: [PATCH 8/8] Improved logging for emails Removed private data from debug export --- cps/config_sql.py | 2 +- cps/logger.py | 7 +++++++ cps/tasks/convert.py | 12 +++++++++--- cps/tasks/mail.py | 2 +- 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/cps/config_sql.py b/cps/config_sql.py index b1e487f9..f7b300c0 100644 --- a/cps/config_sql.py +++ b/cps/config_sql.py @@ -275,7 +275,7 @@ class _ConfigSQL(object): def toDict(self): storage = {} for k, v in self.__dict__.items(): - if k[0] != '_' or k.endswith("password"): + if k[0] != '_' and not k.endswith("password") and not k.endswith("secret"): storage[k] = v return storage diff --git a/cps/logger.py b/cps/logger.py index a9606cb1..d2a41b71 100644 --- a/cps/logger.py +++ b/cps/logger.py @@ -49,6 +49,13 @@ class _Logger(logging.Logger): else: self.error(message, stacklevel=2, *args, **kwargs) + def debug_no_auth(self, message, *args, **kwargs): + if message.startswith("send: AUTH"): + self.debug(message[:16], stacklevel=2, *args, **kwargs) + else: + self.debug(message, stacklevel=2, *args, **kwargs) + + def get(name=None): return logging.getLogger(name) diff --git a/cps/tasks/convert.py b/cps/tasks/convert.py index 75542b38..d3e74569 100644 --- a/cps/tasks/convert.py +++ b/cps/tasks/convert.py @@ -66,9 +66,15 @@ class TaskConvert(CalibreTask): # if we're sending to kindle after converting, create a one-off task and run it immediately # todo: figure out how to incorporate this into the progress try: - worker_thread.add(self.user, TaskEmail(self.settings['subject'], self.results["path"], - filename, self.settings, self.kindle_mail, - self.settings['subject'], self.settings['body'], internal=True)) + worker_thread.add(self.user, TaskEmail(self.settings['subject'], + self.results["path"], + filename, + self.settings, + self.kindle_mail, + self.settings['subject'], + self.settings['body'], + internal=True) + ) except Exception as e: return self._handleError(str(e)) diff --git a/cps/tasks/mail.py b/cps/tasks/mail.py index 8424f084..4f7ed777 100644 --- a/cps/tasks/mail.py +++ b/cps/tasks/mail.py @@ -44,7 +44,7 @@ class EmailBase: def send(self, strg): """Send `strg' to the server.""" - log.debug('send: %r', strg[:300]) + log.debug_no_auth('send: {}'.format(strg[:300])) if hasattr(self, 'sock') and self.sock: try: if self.transferSize: