Commit 8acd1f1f authored by Ozzie Isaacs's avatar Ozzie Isaacs

Code refactoring and improved error handling for edit user list

Update teststatus
parent 665210e5
This diff is collapsed.
...@@ -105,8 +105,8 @@ def _extract_Cover_from_archive(original_file_extension, tmp_file_name, rarExecu ...@@ -105,8 +105,8 @@ def _extract_Cover_from_archive(original_file_extension, tmp_file_name, rarExecu
if extension in COVER_EXTENSIONS: if extension in COVER_EXTENSIONS:
cover_data = cf.read(name) cover_data = cf.read(name)
break break
except Exception as e: except Exception as ex:
log.debug('Rarfile failed with error: %s', e) log.debug('Rarfile failed with error: %s', ex)
return cover_data return cover_data
......
...@@ -544,8 +544,8 @@ class CalibreDB(): ...@@ -544,8 +544,8 @@ class CalibreDB():
conn = cls.engine.connect() conn = cls.engine.connect()
# conn.text_factory = lambda b: b.decode(errors = 'ignore') possible fix for #1302 # conn.text_factory = lambda b: b.decode(errors = 'ignore') possible fix for #1302
except Exception as e: except Exception as ex:
config.invalidate(e) config.invalidate(ex)
return False return False
config.db_configured = True config.db_configured = True
...@@ -646,8 +646,8 @@ class CalibreDB(): ...@@ -646,8 +646,8 @@ class CalibreDB():
pagination = Pagination(page, pagesize, pagination = Pagination(page, pagesize,
len(query.all())) len(query.all()))
entries = query.order_by(*order).offset(off).limit(pagesize).all() entries = query.order_by(*order).offset(off).limit(pagesize).all()
except Exception as e: except Exception as ex:
log.debug_or_exception(e) log.debug_or_exception(ex)
#for book in entries: #for book in entries:
# book = self.order_authors(book) # book = self.order_authors(book)
return entries, randm, pagination return entries, randm, pagination
...@@ -791,7 +791,7 @@ class CalibreDB(): ...@@ -791,7 +791,7 @@ class CalibreDB():
def lcase(s): def lcase(s):
try: try:
return unidecode.unidecode(s.lower()) return unidecode.unidecode(s.lower())
except Exception as e: except Exception as ex:
log = logger.create() log = logger.create()
log.debug_or_exception(e) log.debug_or_exception(ex)
return s.lower() return s.lower()
...@@ -336,8 +336,8 @@ def delete_book(book_id, book_format, jsonResponse): ...@@ -336,8 +336,8 @@ def delete_book(book_id, book_format, jsonResponse):
calibre_db.session.query(db.Data).filter(db.Data.book == book.id).\ calibre_db.session.query(db.Data).filter(db.Data.book == book.id).\
filter(db.Data.format == book_format).delete() filter(db.Data.format == book_format).delete()
calibre_db.session.commit() calibre_db.session.commit()
except Exception as e: except Exception as ex:
log.debug_or_exception(e) log.debug_or_exception(ex)
calibre_db.session.rollback() calibre_db.session.rollback()
else: else:
# book not found # book not found
...@@ -726,10 +726,10 @@ def edit_book(book_id): ...@@ -726,10 +726,10 @@ def edit_book(book_id):
edited_books_id = None edited_books_id = None
# handle book title # handle book title
modif_date |= handle_title_on_edit(book, to_save["book_title"]) title_change = handle_title_on_edit(book, to_save["book_title"])
input_authors, change = handle_author_on_edit(book, to_save["author_name"]) input_authors, authorchange = handle_author_on_edit(book, to_save["author_name"])
if change: if authorchange or title_change:
edited_books_id = book.id edited_books_id = book.id
modif_date = True modif_date = True
...@@ -801,8 +801,8 @@ def edit_book(book_id): ...@@ -801,8 +801,8 @@ def edit_book(book_id):
calibre_db.session.rollback() calibre_db.session.rollback()
flash(error, category="error") flash(error, category="error")
return render_edit_book(book_id) return render_edit_book(book_id)
except Exception as e: except Exception as ex:
log.debug_or_exception(e) log.debug_or_exception(ex)
calibre_db.session.rollback() calibre_db.session.rollback()
flash(_("Error editing book, please check logfile for details"), category="error") flash(_("Error editing book, please check logfile for details"), category="error")
return redirect(url_for('web.show_book', book_id=book.id)) return redirect(url_for('web.show_book', book_id=book.id))
......
...@@ -155,6 +155,6 @@ def on_received_watch_confirmation(): ...@@ -155,6 +155,6 @@ def on_received_watch_confirmation():
# prevent error on windows, as os.rename does on existing files, also allow cross hdd move # prevent error on windows, as os.rename does on existing files, also allow cross hdd move
move(os.path.join(tmp_dir, "tmp_metadata.db"), dbpath) move(os.path.join(tmp_dir, "tmp_metadata.db"), dbpath)
calibre_db.reconnect_db(config, ub.app_DB_path) calibre_db.reconnect_db(config, ub.app_DB_path)
except Exception as e: except Exception as ex:
log.debug_or_exception(e) log.debug_or_exception(ex)
return '' return ''
...@@ -202,8 +202,8 @@ def getDrive(drive=None, gauth=None): ...@@ -202,8 +202,8 @@ def getDrive(drive=None, gauth=None):
gauth.Refresh() gauth.Refresh()
except RefreshError as e: except RefreshError as e:
log.error("Google Drive error: %s", e) log.error("Google Drive error: %s", e)
except Exception as e: except Exception as ex:
log.debug_or_exception(e) log.debug_or_exception(ex)
else: else:
# Initialize the saved creds # Initialize the saved creds
gauth.Authorize() gauth.Authorize()
...@@ -497,8 +497,8 @@ def getChangeById (drive, change_id): ...@@ -497,8 +497,8 @@ def getChangeById (drive, change_id):
except (errors.HttpError) as error: except (errors.HttpError) as error:
log.error(error) log.error(error)
return None return None
except Exception as e: except Exception as ex:
log.error(e) log.error(ex)
return None return None
......
...@@ -35,7 +35,7 @@ from babel.units import format_unit ...@@ -35,7 +35,7 @@ from babel.units import format_unit
from flask import send_from_directory, make_response, redirect, abort, url_for from flask import send_from_directory, make_response, redirect, abort, url_for
from flask_babel import gettext as _ from flask_babel import gettext as _
from flask_login import current_user from flask_login import current_user
from sqlalchemy.sql.expression import true, false, and_, text from sqlalchemy.sql.expression import true, false, and_, text, func
from werkzeug.datastructures import Headers from werkzeug.datastructures import Headers
from werkzeug.security import generate_password_hash from werkzeug.security import generate_password_hash
...@@ -504,6 +504,31 @@ def uniq(inpt): ...@@ -504,6 +504,31 @@ def uniq(inpt):
output.append(x) output.append(x)
return output return output
def check_email(email):
email = valid_email(email)
if ub.session.query(ub.User).filter(func.lower(ub.User.email) == email.lower()).first():
log.error(u"Found an existing account for this e-mail address")
raise Exception(_(u"Found an existing account for this e-mail address"))
return email
def check_username(username):
username = username.strip()
if ub.session.query(ub.User).filter(func.lower(ub.User.name) == username.lower()).scalar():
log.error(u"This username is already taken")
raise Exception (_(u"This username is already taken"))
return username
def valid_email(email):
email = email.strip()
# Regex according to https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/email#validation
if not re.search(r"^[\w.!#$%&'*+\\/=?^_`{|}~-]+@[\w](?:[\w-]{0,61}[\w])?(?:\.[\w](?:[\w-]{0,61}[\w])?)*$",
email):
log.error(u"Invalid e-mail address format")
raise Exception(_(u"Invalid e-mail address format"))
return email
# ################################# External interface ################################# # ################################# External interface #################################
...@@ -551,8 +576,8 @@ def get_book_cover_internal(book, use_generic_cover_on_failure): ...@@ -551,8 +576,8 @@ def get_book_cover_internal(book, use_generic_cover_on_failure):
else: else:
log.error('%s/cover.jpg not found on Google Drive', book.path) log.error('%s/cover.jpg not found on Google Drive', book.path)
return get_cover_on_failure(use_generic_cover_on_failure) return get_cover_on_failure(use_generic_cover_on_failure)
except Exception as e: except Exception as ex:
log.debug_or_exception(e) log.debug_or_exception(ex)
return get_cover_on_failure(use_generic_cover_on_failure) return get_cover_on_failure(use_generic_cover_on_failure)
else: else:
cover_file_path = os.path.join(config.config_calibre_dir, book.path) cover_file_path = os.path.join(config.config_calibre_dir, book.path)
......
...@@ -262,8 +262,8 @@ def generate_sync_response(sync_token, sync_results, set_cont=False): ...@@ -262,8 +262,8 @@ def generate_sync_response(sync_token, sync_results, set_cont=False):
extra_headers["x-kobo-sync-mode"] = store_response.headers.get("x-kobo-sync-mode") extra_headers["x-kobo-sync-mode"] = store_response.headers.get("x-kobo-sync-mode")
extra_headers["x-kobo-recent-reads"] = store_response.headers.get("x-kobo-recent-reads") extra_headers["x-kobo-recent-reads"] = store_response.headers.get("x-kobo-recent-reads")
except Exception as e: except Exception as ex:
log.error("Failed to receive or parse response from Kobo's sync endpoint: " + str(e)) log.error("Failed to receive or parse response from Kobo's sync endpoint: {}".format(ex))
if set_cont: if set_cont:
extra_headers["x-kobo-sync"] = "continue" extra_headers["x-kobo-sync"] = "continue"
sync_token.to_headers(extra_headers) sync_token.to_headers(extra_headers)
......
...@@ -147,8 +147,8 @@ def bind_oauth_or_register(provider_id, provider_user_id, redirect_url, provider ...@@ -147,8 +147,8 @@ def bind_oauth_or_register(provider_id, provider_user_id, redirect_url, provider
ub.session.commit() ub.session.commit()
flash(_(u"Link to %(oauth)s Succeeded", oauth=provider_name), category="success") flash(_(u"Link to %(oauth)s Succeeded", oauth=provider_name), category="success")
return redirect(url_for('web.profile')) return redirect(url_for('web.profile'))
except Exception as e: except Exception as ex:
log.debug_or_exception(e) log.debug_or_exception(ex)
ub.session.rollback() ub.session.rollback()
else: else:
flash(_(u"Login failed, No User Linked With OAuth Account"), category="error") flash(_(u"Login failed, No User Linked With OAuth Account"), category="error")
...@@ -194,8 +194,8 @@ def unlink_oauth(provider): ...@@ -194,8 +194,8 @@ def unlink_oauth(provider):
ub.session.commit() ub.session.commit()
logout_oauth_user() logout_oauth_user()
flash(_(u"Unlink to %(oauth)s Succeeded", oauth=oauth_check[provider]), category="success") flash(_(u"Unlink to %(oauth)s Succeeded", oauth=oauth_check[provider]), category="success")
except Exception as e: except Exception as ex:
log.debug_or_exception(e) log.debug_or_exception(ex)
ub.session.rollback() ub.session.rollback()
flash(_(u"Unlink to %(oauth)s Failed", oauth=oauth_check[provider]), category="error") flash(_(u"Unlink to %(oauth)s Failed", oauth=oauth_check[provider]), category="error")
except NoResultFound: except NoResultFound:
......
...@@ -159,9 +159,9 @@ class CalibreTask: ...@@ -159,9 +159,9 @@ class CalibreTask:
# catch any unhandled exceptions in a task and automatically fail it # catch any unhandled exceptions in a task and automatically fail it
try: try:
self.run(*args) self.run(*args)
except Exception as e: except Exception as ex:
self._handleError(str(e)) self._handleError(str(ex))
log.debug_or_exception(e) log.debug_or_exception(ex)
self.end_time = datetime.now() self.end_time = datetime.now()
......
...@@ -255,13 +255,13 @@ def create_edit_shelf(shelf, title, page, shelf_id=False): ...@@ -255,13 +255,13 @@ def create_edit_shelf(shelf, title, page, shelf_id=False):
log.info(u"Shelf {} {}".format(to_save["title"], shelf_action)) log.info(u"Shelf {} {}".format(to_save["title"], shelf_action))
flash(flash_text, category="success") flash(flash_text, category="success")
return redirect(url_for('shelf.show_shelf', shelf_id=shelf.id)) return redirect(url_for('shelf.show_shelf', shelf_id=shelf.id))
except (OperationalError, InvalidRequestError) as e: except (OperationalError, InvalidRequestError) as ex:
ub.session.rollback() ub.session.rollback()
log.debug_or_exception(e) log.debug_or_exception(ex)
flash(_(u"Settings DB is not Writeable"), category="error") flash(_(u"Settings DB is not Writeable"), category="error")
except Exception as e: except Exception as ex:
ub.session.rollback() ub.session.rollback()
log.debug_or_exception(e) log.debug_or_exception(ex)
flash(_(u"There was an error"), category="error") flash(_(u"There was an error"), category="error")
return render_title_template('shelf_edit.html', shelf=shelf, title=title, page=page) return render_title_template('shelf_edit.html', shelf=shelf, title=title, page=page)
......
...@@ -452,6 +452,17 @@ $(function() { ...@@ -452,6 +452,17 @@ $(function() {
$(this).next().text(elText); $(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);
// ToDo: Disable delete
},
// eslint-disable-next-line no-unused-vars // eslint-disable-next-line no-unused-vars
/*onEditableSave: function (field, row, oldvalue, $el) { /*onEditableSave: function (field, row, oldvalue, $el) {
if (field === "title" || field === "authors") { if (field === "title" || field === "authors") {
...@@ -612,9 +623,9 @@ function singleUserFormatter(value, row) { ...@@ -612,9 +623,9 @@ function singleUserFormatter(value, row) {
function checkboxFormatter(value, row, index){ function checkboxFormatter(value, row, index){
if(value & this.column) if(value & this.column)
return '<input type="checkbox" class="chk" checked onchange="checkboxChange(this, ' + row.id + ', \'' + this.field + '\', ' + this.column + ')">'; return '<input type="checkbox" class="chk" data-pk="' + row.id + '" data-name="' + this.name + '" checked onchange="checkboxChange(this, ' + row.id + ', \'' + this.field + '\', ' + this.column + ')">';
else else
return '<input type="checkbox" class="chk" onchange="checkboxChange(this, ' + row.id + ', \'' + this.field + '\', ' + this.column + ')">'; return '<input type="checkbox" class="chk" data-pk="' + row.id + '" data-name="' + this.name + '" onchange="checkboxChange(this, ' + row.id + ', \'' + this.field + '\', ' + this.column + ')">';
} }
function checkboxChange(checkbox, userId, field, field_index) { function checkboxChange(checkbox, userId, field, field_index) {
...@@ -622,6 +633,11 @@ function checkboxChange(checkbox, userId, field, field_index) { ...@@ -622,6 +633,11 @@ function checkboxChange(checkbox, userId, field, field_index) {
method:"post", method:"post",
url: window.location.pathname + "/../../ajax/editlistusers/" + field, url: window.location.pathname + "/../../ajax/editlistusers/" + field,
data: {"pk":userId, "field_index":field_index, "value": checkbox.checked} data: {"pk":userId, "field_index":field_index, "value": checkbox.checked}
/*<div className="editable-buttons">
<button type="button" className="btn btn-default btn-sm editable-cancel"><i
className="glyphicon glyphicon-remove"></i></button>
</div>*/
/*<div className="editable-error-block help-block" style="">Text to show</div>*/
}); });
$.ajax({ $.ajax({
method:"get", method:"get",
......
...@@ -75,8 +75,8 @@ class TaskConvert(CalibreTask): ...@@ -75,8 +75,8 @@ class TaskConvert(CalibreTask):
self.settings['body'], self.settings['body'],
internal=True) internal=True)
) )
except Exception as e: except Exception as ex:
return self._handleError(str(e)) return self._handleError(str(ex))
def _convert_ebook_format(self): def _convert_ebook_format(self):
error_message = None error_message = None
......
...@@ -158,9 +158,9 @@ class TaskEmail(CalibreTask): ...@@ -158,9 +158,9 @@ class TaskEmail(CalibreTask):
except socket.error as e: except socket.error as e:
log.debug_or_exception(e) log.debug_or_exception(e)
self._handleError(u'Socket Error sending email: {}'.format(e.strerror)) self._handleError(u'Socket Error sending email: {}'.format(e.strerror))
except Exception as e: except Exception as ex:
log.debug_or_exception(e) log.debug_or_exception(ex)
self._handleError(u'Error sending email: {}'.format(e)) self._handleError(u'Error sending email: {}'.format(ex))
def send_standard_email(self, msg): def send_standard_email(self, msg):
......
...@@ -43,6 +43,7 @@ ...@@ -43,6 +43,7 @@
data-visible="{{visiblility.get(parameter)}}" data-visible="{{visiblility.get(parameter)}}"
data-editable-type="select" data-editable-type="select"
data-edit="true" data-edit="true"
data-sortable="true"
data-editable-url="{{ url_for('admin.edit_list_user', param=parameter)}}" data-editable-url="{{ url_for('admin.edit_list_user', param=parameter)}}"
data-editable-source={{url}} data-editable-source={{url}}
{% if validate %}data-edit-validate="{{ _('This Field is Required') }}"{% endif %}> {% if validate %}data-edit-validate="{{ _('This Field is Required') }}"{% endif %}>
...@@ -65,6 +66,7 @@ ...@@ -65,6 +66,7 @@
data-visible="{{visiblility.get(parameter)}}" data-visible="{{visiblility.get(parameter)}}"
data-editable-type="select" data-editable-type="select"
data-edit="true" data-edit="true"
data-sortable="true"
data-editable-url="{{ url_for('admin.edit_list_user', param=parameter)}}" data-editable-url="{{ url_for('admin.edit_list_user', param=parameter)}}"
data-editable-source={{url}} data-editable-source={{url}}
{% if validate %}data-edit-validate="{{ _('This Field is Required') }}"{% endif %}> {% if validate %}data-edit-validate="{{ _('This Field is Required') }}"{% endif %}>
...@@ -101,7 +103,7 @@ ...@@ -101,7 +103,7 @@
<th data-name="id" data-field="id" id="id" data-visible="false" data-switchable="false"></th> <th data-name="id" data-field="id" id="id" data-visible="false" data-switchable="false"></th>
{{ user_table_row('name', _('Enter Username'), _('Username'), true) }} {{ user_table_row('name', _('Enter Username'), _('Username'), true) }}
{{ user_table_row('email', _('Enter E-mail Address'), _('E-mail Address'), true) }} {{ user_table_row('email', _('Enter E-mail Address'), _('E-mail Address'), true) }}
{{ user_table_row('kindle_mail', _('Enter Kindle E-mail Address'), _('Kindle E-mail'), true) }} {{ user_table_row('kindle_mail', _('Enter Kindle E-mail Address'), _('Kindle E-mail'), false) }}
{{ user_select_translations('locale', url_for('admin.table_get_locale'), _('Locale'), true) }} {{ user_select_translations('locale', url_for('admin.table_get_locale'), _('Locale'), true) }}
{{ user_select_languages('default_language', url_for('admin.table_get_default_lang'), _('Visible Book Languages'), true) }} {{ user_select_languages('default_language', url_for('admin.table_get_default_lang'), _('Visible Book Languages'), true) }}
{{ user_table_row('denied_tags', _("Edit Denied Tags"), _("Denied Tags"), false, true, 0) }} {{ user_table_row('denied_tags', _("Edit Denied Tags"), _("Denied Tags"), false, true, 0) }}
......
...@@ -117,8 +117,8 @@ def parse_xmp(pdf_file): ...@@ -117,8 +117,8 @@ def parse_xmp(pdf_file):
""" """
try: try:
xmp_info = pdf_file.getXmpMetadata() xmp_info = pdf_file.getXmpMetadata()
except Exception as e: except Exception as ex:
log.debug('Can not read XMP metadata %e', e) log.debug('Can not read XMP metadata {}'.format(ex))
return None return None
if xmp_info: if xmp_info:
...@@ -162,8 +162,8 @@ def parse_xmp(pdf_file): ...@@ -162,8 +162,8 @@ def parse_xmp(pdf_file):
""" """
try: try:
xmp_info = pdf_file.getXmpMetadata() xmp_info = pdf_file.getXmpMetadata()
except Exception as e: except Exception as ex:
log.debug('Can not read XMP metadata', e) log.debug('Can not read XMP metadata {}'.format(ex))
return None return None
if xmp_info: if xmp_info:
......
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment