resolved merge conflicts

This commit is contained in:
mmonkey 2021-01-04 12:26:46 -06:00
commit 774799f316
52 changed files with 13138 additions and 10959 deletions

View File

@ -105,6 +105,7 @@ def unconfigured(f):
return inner return inner
@admi.before_app_request @admi.before_app_request
def before_request(): def before_request():
if current_user.is_authenticated: if current_user.is_authenticated:
@ -118,8 +119,10 @@ def before_request():
g.config_authors_max = config.config_authors_max g.config_authors_max = config.config_authors_max
g.shelves_access = ub.session.query(ub.Shelf).filter( 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() 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 ( if '/static/' not in request.path and not config.db_configured and \
'admin.basic_configuration', 'login', 'admin.config_pathchooser') and '/static/' not in request.path: request.endpoint not in ('admin.basic_configuration',
'login',
'admin.config_pathchooser'):
return redirect(url_for('admin.basic_configuration')) return redirect(url_for('admin.basic_configuration'))
@ -218,12 +221,12 @@ def configuration():
@login_required @login_required
@admin_required @admin_required
def view_configuration(): def view_configuration():
readColumn = calibre_db.session.query(db.Custom_Columns)\ read_column = calibre_db.session.query(db.Custom_Columns)\
.filter(and_(db.Custom_Columns.datatype == 'bool', db.Custom_Columns.mark_for_delete == 0)).all() .filter(and_(db.Custom_Columns.datatype == 'bool', db.Custom_Columns.mark_for_delete == 0)).all()
restrictColumns= calibre_db.session.query(db.Custom_Columns)\ restrict_columns = calibre_db.session.query(db.Custom_Columns)\
.filter(and_(db.Custom_Columns.datatype == 'text', db.Custom_Columns.mark_for_delete == 0)).all() .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, return render_title_template("config_view_edit.html", conf=config, readColumns=read_column,
restrictColumns=restrictColumns, restrictColumns=restrict_columns,
title=_(u"UI Configuration"), page="uiconfig") title=_(u"UI Configuration"), page="uiconfig")
@ -288,11 +291,7 @@ def edit_domain(allow):
vals = request.form.to_dict() vals = request.form.to_dict()
answer = ub.session.query(ub.Registration).filter(ub.Registration.id == vals['pk']).first() answer = ub.session.query(ub.Registration).filter(ub.Registration.id == vals['pk']).first()
answer.domain = vals['value'].replace('*', '%').replace('?', '_').lower() answer.domain = vals['value'].replace('*', '%').replace('?', '_').lower()
try: return ub.session_commit("Registering Domains edited {}".format(answer.domain))
ub.session.commit()
except OperationalError:
ub.session.rollback()
return ""
@admi.route("/ajax/adddomain/<int:allow>", methods=['POST']) @admi.route("/ajax/adddomain/<int:allow>", methods=['POST'])
@ -305,10 +304,7 @@ def add_domain(allow):
if not check: if not check:
new_domain = ub.Registration(domain=domain_name, allow=allow) new_domain = ub.Registration(domain=domain_name, allow=allow)
ub.session.add(new_domain) ub.session.add(new_domain)
try: ub.session_commit("Registering Domains added {}".format(domain_name))
ub.session.commit()
except OperationalError:
ub.session.rollback()
return "" return ""
@ -319,18 +315,12 @@ def delete_domain():
try: try:
domain_id = request.form.to_dict()['domainid'].replace('*', '%').replace('?', '_').lower() domain_id = request.form.to_dict()['domainid'].replace('*', '%').replace('?', '_').lower()
ub.session.query(ub.Registration).filter(ub.Registration.id == domain_id).delete() ub.session.query(ub.Registration).filter(ub.Registration.id == domain_id).delete()
try: ub.session_commit("Registering Domains deleted {}".format(domain_id))
ub.session.commit()
except OperationalError:
ub.session.rollback()
# If last domain was deleted, add all domains by default # If last domain was deleted, add all domains by default
if not ub.session.query(ub.Registration).filter(ub.Registration.allow == 1).count(): if not ub.session.query(ub.Registration).filter(ub.Registration.allow == 1).count():
new_domain = ub.Registration(domain="%.%", allow=1) new_domain = ub.Registration(domain="%.%", allow=1)
ub.session.add(new_domain) ub.session.add(new_domain)
try: ub.session_commit("Last Registering Domain deleted, added *.* as default")
ub.session.commit()
except OperationalError:
ub.session.rollback()
except KeyError: except KeyError:
pass pass
return "" return ""
@ -347,6 +337,7 @@ def list_domain(allow):
response.headers["Content-Type"] = "application/json; charset=utf-8" response.headers["Content-Type"] = "application/json; charset=utf-8"
return response return response
@admi.route("/ajax/editrestriction/<int:res_type>", defaults={"user_id": 0}, methods=['POST']) @admi.route("/ajax/editrestriction/<int:res_type>", defaults={"user_id": 0}, methods=['POST'])
@admi.route("/ajax/editrestriction/<int:res_type>/<int:user_id>", methods=['POST']) @admi.route("/ajax/editrestriction/<int:res_type>/<int:user_id>", methods=['POST'])
@login_required @login_required
@ -372,10 +363,7 @@ def edit_restriction(res_type, user_id):
elementlist = usr.list_allowed_tags() elementlist = usr.list_allowed_tags()
elementlist[int(element['id'][1:])] = element['Element'] elementlist[int(element['id'][1:])] = element['Element']
usr.allowed_tags = ','.join(elementlist) usr.allowed_tags = ','.join(elementlist)
try: ub.session_commit("Changed allowed tags of user {} to {}".format(usr.nickname, usr.allowed_tags))
ub.session.commit()
except OperationalError:
ub.session.rollback()
if res_type == 3: # CColumn per user if res_type == 3: # CColumn per user
if isinstance(user_id, int): if isinstance(user_id, int):
usr = ub.session.query(ub.User).filter(ub.User.id == int(user_id)).first() usr = ub.session.query(ub.User).filter(ub.User.id == int(user_id)).first()
@ -384,10 +372,7 @@ def edit_restriction(res_type, user_id):
elementlist = usr.list_allowed_column_values() 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) usr.allowed_column_value = ','.join(elementlist)
try: ub.session_commit("Changed allowed columns of user {} to {}".format(usr.nickname, usr.allowed_column_value))
ub.session.commit()
except OperationalError:
ub.session.rollback()
if element['id'].startswith('d'): if element['id'].startswith('d'):
if res_type == 0: # Tags as template if res_type == 0: # Tags as template
elementlist = config.list_denied_tags() elementlist = config.list_denied_tags()
@ -407,10 +392,7 @@ def edit_restriction(res_type, user_id):
elementlist = usr.list_denied_tags() elementlist = usr.list_denied_tags()
elementlist[int(element['id'][1:])] = element['Element'] elementlist[int(element['id'][1:])] = element['Element']
usr.denied_tags = ','.join(elementlist) usr.denied_tags = ','.join(elementlist)
try: ub.session_commit("Changed denied tags of user {} to {}".format(usr.nickname, usr.denied_tags))
ub.session.commit()
except OperationalError:
ub.session.rollback()
if res_type == 3: # CColumn per user if res_type == 3: # CColumn per user
if isinstance(user_id, int): if isinstance(user_id, int):
usr = ub.session.query(ub.User).filter(ub.User.id == int(user_id)).first() usr = ub.session.query(ub.User).filter(ub.User.id == int(user_id)).first()
@ -419,12 +401,10 @@ def edit_restriction(res_type, user_id):
elementlist = usr.list_denied_column_values() 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) usr.denied_column_value = ','.join(elementlist)
try: ub.session_commit("Changed denied columns of user {} to {}".format(usr.nickname, usr.denied_column_value))
ub.session.commit()
except OperationalError:
ub.session.rollback()
return "" return ""
def restriction_addition(element, list_func): def restriction_addition(element, list_func):
elementlist = list_func() elementlist = list_func()
if elementlist == ['']: if elementlist == ['']:
@ -468,16 +448,10 @@ def add_restriction(res_type, user_id):
usr = current_user usr = current_user
if 'submit_allow' in element: if 'submit_allow' in element:
usr.allowed_tags = restriction_addition(element, usr.list_allowed_tags) usr.allowed_tags = restriction_addition(element, usr.list_allowed_tags)
try: ub.session_commit("Changed allowed tags of user {} to {}".format(usr.nickname, usr.list_allowed_tags))
ub.session.commit()
except OperationalError:
ub.session.rollback()
elif 'submit_deny' in element: elif 'submit_deny' in element:
usr.denied_tags = restriction_addition(element, usr.list_denied_tags) usr.denied_tags = restriction_addition(element, usr.list_denied_tags)
try: ub.session_commit("Changed denied tags of user {} to {}".format(usr.nickname, usr.list_denied_tags))
ub.session.commit()
except OperationalError:
ub.session.rollback()
if res_type == 3: # CustomC per user if res_type == 3: # CustomC per user
if isinstance(user_id, int): if isinstance(user_id, int):
usr = ub.session.query(ub.User).filter(ub.User.id == int(user_id)).first() usr = ub.session.query(ub.User).filter(ub.User.id == int(user_id)).first()
@ -485,18 +459,15 @@ def add_restriction(res_type, user_id):
usr = current_user usr = current_user
if 'submit_allow' in element: if 'submit_allow' in element:
usr.allowed_column_value = restriction_addition(element, usr.list_allowed_column_values) usr.allowed_column_value = restriction_addition(element, usr.list_allowed_column_values)
try: ub.session_commit("Changed allowed columns of user {} to {}".format(usr.nickname,
ub.session.commit() usr.list_allowed_column_values))
except OperationalError:
ub.session.rollback()
elif 'submit_deny' in element: elif 'submit_deny' in element:
usr.denied_column_value = restriction_addition(element, usr.list_denied_column_values) usr.denied_column_value = restriction_addition(element, usr.list_denied_column_values)
try: ub.session_commit("Changed denied columns of user {} to {}".format(usr.nickname,
ub.session.commit() usr.list_denied_column_values))
except OperationalError:
ub.session.rollback()
return "" return ""
@admi.route("/ajax/deleterestriction/<int:res_type>", defaults={"user_id": 0}, methods=['POST']) @admi.route("/ajax/deleterestriction/<int:res_type>", defaults={"user_id": 0}, methods=['POST'])
@admi.route("/ajax/deleterestriction/<int:res_type>/<int:user_id>", methods=['POST']) @admi.route("/ajax/deleterestriction/<int:res_type>/<int:user_id>", methods=['POST'])
@login_required @login_required
@ -524,16 +495,10 @@ def delete_restriction(res_type, user_id):
usr = current_user usr = current_user
if element['id'].startswith('a'): if element['id'].startswith('a'):
usr.allowed_tags = restriction_deletion(element, usr.list_allowed_tags) usr.allowed_tags = restriction_deletion(element, usr.list_allowed_tags)
try: ub.session_commit("Deleted allowed tags of user {}: {}".format(usr.nickname, usr.list_allowed_tags))
ub.session.commit()
except OperationalError:
ub.session.rollback()
elif element['id'].startswith('d'): elif element['id'].startswith('d'):
usr.denied_tags = restriction_deletion(element, usr.list_denied_tags) usr.denied_tags = restriction_deletion(element, usr.list_denied_tags)
try: ub.session_commit("Deleted denied tags of user {}: {}".format(usr.nickname, usr.list_allowed_tags))
ub.session.commit()
except OperationalError:
ub.session.rollback()
elif res_type == 3: # Columns per user elif res_type == 3: # Columns per user
if isinstance(user_id, int): if isinstance(user_id, int):
usr = ub.session.query(ub.User).filter(ub.User.id == int(user_id)).first() usr = ub.session.query(ub.User).filter(ub.User.id == int(user_id)).first()
@ -541,18 +506,16 @@ def delete_restriction(res_type, user_id):
usr = current_user usr = current_user
if element['id'].startswith('a'): if element['id'].startswith('a'):
usr.allowed_column_value = restriction_deletion(element, usr.list_allowed_column_values) usr.allowed_column_value = restriction_deletion(element, usr.list_allowed_column_values)
try: ub.session_commit("Deleted allowed columns of user {}: {}".format(usr.nickname,
ub.session.commit() usr.list_allowed_column_values))
except OperationalError:
ub.session.rollback()
elif element['id'].startswith('d'): elif element['id'].startswith('d'):
usr.denied_column_value = restriction_deletion(element, usr.list_denied_column_values) usr.denied_column_value = restriction_deletion(element, usr.list_denied_column_values)
try: ub.session_commit("Deleted denied columns of user {}: {}".format(usr.nickname,
ub.session.commit() usr.list_denied_column_values))
except OperationalError:
ub.session.rollback()
return "" return ""
@admi.route("/ajax/listrestriction/<int:res_type>", defaults={"user_id": 0}) @admi.route("/ajax/listrestriction/<int:res_type>", defaults={"user_id": 0})
@admi.route("/ajax/listrestriction/<int:res_type>/<int:user_id>") @admi.route("/ajax/listrestriction/<int:res_type>/<int:user_id>")
@login_required @login_required
@ -597,6 +560,7 @@ def list_restriction(res_type, user_id):
response.headers["Content-Type"] = "application/json; charset=utf-8" response.headers["Content-Type"] = "application/json; charset=utf-8"
return response return response
@admi.route("/basicconfig/pathchooser/") @admi.route("/basicconfig/pathchooser/")
@unconfigured @unconfigured
def config_pathchooser(): def config_pathchooser():
@ -604,12 +568,14 @@ def config_pathchooser():
return pathchooser() return pathchooser()
abort(403) abort(403)
@admi.route("/ajax/pathchooser/") @admi.route("/ajax/pathchooser/")
@login_required @login_required
@admin_required @admin_required
def ajax_pathchooser(): def ajax_pathchooser():
return pathchooser() return pathchooser()
def pathchooser(): def pathchooser():
browse_for = "folder" browse_for = "folder"
folder_only = request.args.get('folder', False) == "true" folder_only = request.args.get('folder', False) == "true"
@ -622,12 +588,12 @@ def pathchooser():
else: else:
oldfile = "" oldfile = ""
abs = False absolute = False
if os.path.isdir(path): if os.path.isdir(path):
# if os.path.isabs(path): # if os.path.isabs(path):
cwd = os.path.realpath(path) cwd = os.path.realpath(path)
abs = True absolute = True
# else: # else:
# cwd = os.path.relpath(path) # cwd = os.path.relpath(path)
else: else:
@ -635,7 +601,7 @@ def pathchooser():
cwd = os.path.normpath(os.path.realpath(cwd)) cwd = os.path.normpath(os.path.realpath(cwd))
parentdir = os.path.dirname(cwd) parentdir = os.path.dirname(cwd)
if not abs: if not absolute:
if os.path.realpath(cwd) == os.path.realpath("/"): if os.path.realpath(cwd) == os.path.realpath("/"):
cwd = os.path.relpath(cwd) cwd = os.path.relpath(cwd)
else: else:
@ -722,8 +688,8 @@ def _configuration_gdrive_helper(to_save):
config.config_use_google_drive = False config.config_use_google_drive = False
gdrive_secrets = {} gdrive_secrets = {}
gdriveError = gdriveutils.get_error_text(gdrive_secrets) 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 gdriveError: 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: with open(gdriveutils.CLIENT_SECRETS, 'r') as settings:
gdrive_secrets = json.load(settings)['web'] gdrive_secrets = json.load(settings)['web']
if not gdrive_secrets: if not gdrive_secrets:
@ -735,10 +701,11 @@ def _configuration_gdrive_helper(to_save):
) )
# always show google drive settings, but in case of error deny support # 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"): if _config_string(to_save, "config_google_drive_folder"):
gdriveutils.deleteDatabaseOnChange() gdriveutils.deleteDatabaseOnChange()
return gdriveError return gdrive_error
def _configuration_oauth_helper(to_save): def _configuration_oauth_helper(to_save):
active_oauths = 0 active_oauths = 0
@ -761,22 +728,24 @@ def _configuration_oauth_helper(to_save):
"active": element["active"]}) "active": element["active"]})
return reboot_required return reboot_required
def _configuration_logfile_helper(to_save, gdriveError):
def _configuration_logfile_helper(to_save, gdrive_error):
reboot_required = False reboot_required = False
reboot_required |= _config_int(to_save, "config_log_level") reboot_required |= _config_int(to_save, "config_log_level")
reboot_required |= _config_string(to_save, "config_logfile") reboot_required |= _config_string(to_save, "config_logfile")
if not logger.is_valid_logfile(config.config_logfile): if not logger.is_valid_logfile(config.config_logfile):
return reboot_required, \ 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_checkbox_int(to_save, "config_access_log")
reboot_required |= _config_string(to_save, "config_access_logfile") reboot_required |= _config_string(to_save, "config_access_logfile")
if not logger.is_valid_logfile(config.config_access_logfile): if not logger.is_valid_logfile(config.config_access_logfile):
return reboot_required, \ 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 return reboot_required, None
def _configuration_ldap_helper(to_save, gdriveError):
def _configuration_ldap_helper(to_save, gdrive_error):
reboot_required = False reboot_required = False
reboot_required |= _config_string(to_save, "config_ldap_provider_url") reboot_required |= _config_string(to_save, "config_ldap_provider_url")
reboot_required |= _config_int(to_save, "config_ldap_port") reboot_required |= _config_int(to_save, "config_ldap_port")
@ -803,33 +772,33 @@ def _configuration_ldap_helper(to_save, gdriveError):
or not config.config_ldap_dn \ or not config.config_ldap_dn \
or not config.config_ldap_user_object: or not config.config_ldap_user_object:
return reboot_required, _configuration_result(_('Please Enter a LDAP Provider, ' 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_ANONYMOUS:
if config.config_ldap_authentication > constants.LDAP_AUTH_UNAUTHENTICATE: if config.config_ldap_authentication > constants.LDAP_AUTH_UNAUTHENTICATE:
if not config.config_ldap_serv_username or not bool(config.config_ldap_serv_password): 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', return reboot_required, _configuration_result('Please Enter a LDAP Service Account and Password',
gdriveError) gdrive_error)
else: else:
if not config.config_ldap_serv_username: 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:
if config.config_ldap_group_object_filter.count("%s") != 1: if config.config_ldap_group_object_filter.count("%s") != 1:
return reboot_required, \ return reboot_required, \
_configuration_result(_('LDAP Group Object Filter Needs to Have One "%s" Format Identifier'), _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(")"): 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'), return reboot_required, _configuration_result(_('LDAP Group Object Filter Has Unmatched Parenthesis'),
gdriveError) gdrive_error)
if config.config_ldap_user_object.count("%s") != 1: if config.config_ldap_user_object.count("%s") != 1:
return reboot_required, \ return reboot_required, \
_configuration_result(_('LDAP User Object Filter needs to Have One "%s" Format Identifier'), _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(")"): 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'), return reboot_required, _configuration_result(_('LDAP User Object Filter Has Unmatched Parenthesis'),
gdriveError) gdrive_error)
if to_save["ldap_import_user_filter"] == '0': if to_save["ldap_import_user_filter"] == '0':
config.config_ldap_member_user_object = "" config.config_ldap_member_user_object = ""
@ -837,10 +806,10 @@ def _configuration_ldap_helper(to_save, gdriveError):
if config.config_ldap_member_user_object.count("%s") != 1: if config.config_ldap_member_user_object.count("%s") != 1:
return reboot_required, \ return reboot_required, \
_configuration_result(_('LDAP Member User Filter needs to Have One "%s" Format Identifier'), _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(")"): 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'), 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 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 if not (os.path.isfile(config.config_ldap_cacert_path) and
@ -849,7 +818,7 @@ def _configuration_ldap_helper(to_save, gdriveError):
return reboot_required, \ return reboot_required, \
_configuration_result(_('LDAP CACertificate, Certificate or Key Location is not Valid, ' _configuration_result(_('LDAP CACertificate, Certificate or Key Location is not Valid, '
'Please Enter Correct Path'), 'Please Enter Correct Path'),
gdriveError) gdrive_error)
return reboot_required, None return reboot_required, None
@ -857,7 +826,7 @@ def _configuration_update_helper(configured):
reboot_required = False reboot_required = False
db_change = False db_change = False
to_save = request.form.to_dict() to_save = request.form.to_dict()
gdriveError = None gdrive_error = None
to_save['config_calibre_dir'] = re.sub(r'[\\/]metadata\.db$', to_save['config_calibre_dir'] = re.sub(r'[\\/]metadata\.db$',
'', '',
@ -866,21 +835,21 @@ def _configuration_update_helper(configured):
try: try:
db_change |= _config_string(to_save, "config_calibre_dir") db_change |= _config_string(to_save, "config_calibre_dir")
# Google drive setup # gdrive_error drive setup
gdriveError = _configuration_gdrive_helper(to_save) gdrive_error = _configuration_gdrive_helper(to_save)
reboot_required |= _config_int(to_save, "config_port") reboot_required |= _config_int(to_save, "config_port")
reboot_required |= _config_string(to_save, "config_keyfile") reboot_required |= _config_string(to_save, "config_keyfile")
if config.config_keyfile and not os.path.isfile(config.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'), return _configuration_result(_('Keyfile Location is not Valid, Please Enter Correct Path'),
gdriveError, gdrive_error,
configured) configured)
reboot_required |= _config_string(to_save, "config_certfile") reboot_required |= _config_string(to_save, "config_certfile")
if config.config_certfile and not os.path.isfile(config.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'), return _configuration_result(_('Certfile Location is not Valid, Please Enter Correct Path'),
gdriveError, gdrive_error,
configured) configured)
_config_checkbox_int(to_save, "config_uploading") _config_checkbox_int(to_save, "config_uploading")
@ -907,7 +876,7 @@ def _configuration_update_helper(configured):
# LDAP configurator, # LDAP configurator,
if config.config_login_type == constants.LOGIN_LDAP: 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: if message:
return message return message
reboot_required |= reboot reboot_required |= reboot
@ -937,7 +906,7 @@ def _configuration_update_helper(configured):
if config.config_login_type == constants.LOGIN_OAUTH: if config.config_login_type == constants.LOGIN_OAUTH:
reboot_required |= _configuration_oauth_helper(to_save) 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: if message:
return message return message
reboot_required |= reboot reboot_required |= reboot
@ -946,10 +915,10 @@ def _configuration_update_helper(configured):
if "config_rarfile_location" in to_save: if "config_rarfile_location" in to_save:
unrar_status = helper.check_unrar(config.config_rarfile_location) unrar_status = helper.check_unrar(config.config_rarfile_location)
if unrar_status: if unrar_status:
return _configuration_result(unrar_status, gdriveError, configured) return _configuration_result(unrar_status, gdrive_error, configured)
except (OperationalError, InvalidRequestError): except (OperationalError, InvalidRequestError):
ub.session.rollback() 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: try:
metadata_db = os.path.join(config.config_calibre_dir, "metadata.db") metadata_db = os.path.join(config.config_calibre_dir, "metadata.db")
@ -957,12 +926,12 @@ def _configuration_update_helper(configured):
gdriveutils.downloadFile(None, "metadata.db", metadata_db) gdriveutils.downloadFile(None, "metadata.db", metadata_db)
db_change = True db_change = True
except Exception as e: except Exception as e:
return _configuration_result('%s' % e, gdriveError, configured) return _configuration_result('%s' % e, gdrive_error, configured)
if db_change: if db_change:
if not calibre_db.setup_db(config, ub.app_DB_path): if not calibre_db.setup_db(config, ub.app_DB_path):
return _configuration_result(_('DB Location is not Valid, Please Enter Correct Path'), return _configuration_result(_('DB Location is not Valid, Please Enter Correct Path'),
gdriveError, gdrive_error,
configured) configured)
if not os.access(os.path.join(config.config_calibre_dir, "metadata.db"), os.W_OK): if not os.access(os.path.join(config.config_calibre_dir, "metadata.db"), os.W_OK):
flash(_(u"DB is not Writeable"), category="warning") flash(_(u"DB is not Writeable"), category="warning")
@ -972,16 +941,16 @@ def _configuration_update_helper(configured):
if reboot_required: if reboot_required:
web_server.stop(True) 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() gdrive_authenticate = not is_gdrive_ready()
gdrivefolders = [] gdrivefolders = []
if gdriveError is None: if gdrive_error is None:
gdriveError = gdriveutils.get_error_text() gdrive_error = gdriveutils.get_error_text()
if gdriveError: if gdrive_error:
gdriveError = _(gdriveError) gdrive_error = _(gdrive_error)
else: else:
# if config.config_use_google_drive and\ # if config.config_use_google_drive and\
if not gdrive_authenticate and gdrive_support: if not gdrive_authenticate and gdrive_support:
@ -994,10 +963,16 @@ def _configuration_result(error_flash=None, gdriveError=None, configured=True):
flash(error_flash, category="error") flash(error_flash, category="error")
show_login_button = False show_login_button = False
return render_title_template("config_edit.html", config=config, provider=oauthblueprints, return render_title_template("config_edit.html",
show_back_button=show_back_button, show_login_button=show_login_button, config=config,
show_authenticate_google_drive=gdrive_authenticate, filepicker=configured, provider=oauthblueprints,
gdriveError=gdriveError, gdrivefolders=gdrivefolders, feature_support=feature_support, 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") title=_(u"Basic Configuration"), page="config")
@ -1042,10 +1017,7 @@ def _handle_new_user(to_save, content,languages, translations, kobo_support):
content.allowed_column_value = config.config_allowed_column_value content.allowed_column_value = config.config_allowed_column_value
content.denied_column_value = config.config_denied_column_value content.denied_column_value = config.config_denied_column_value
ub.session.add(content) ub.session.add(content)
try:
ub.session.commit() ub.session.commit()
except OperationalError:
ub.session.rollback()
flash(_(u"User '%(user)s' created", user=content.nickname), category="success") flash(_(u"User '%(user)s' created", user=content.nickname), category="success")
return redirect(url_for('admin.admin')) return redirect(url_for('admin.admin'))
except IntegrityError: except IntegrityError:
@ -1061,10 +1033,7 @@ def _handle_edit_user(to_save, content,languages, translations, kobo_support):
if ub.session.query(ub.User).filter(ub.User.role.op('&')(constants.ROLE_ADMIN) == constants.ROLE_ADMIN, if ub.session.query(ub.User).filter(ub.User.role.op('&')(constants.ROLE_ADMIN) == constants.ROLE_ADMIN,
ub.User.id != content.id).count(): ub.User.id != content.id).count():
ub.session.query(ub.User).filter(ub.User.id == content.id).delete() ub.session.query(ub.User).filter(ub.User.id == content.id).delete()
try: ub.session_commit()
ub.session.commit()
except OperationalError:
ub.session.rollback()
flash(_(u"User '%(nick)s' deleted", nick=content.nickname), category="success") flash(_(u"User '%(nick)s' deleted", nick=content.nickname), category="success")
return redirect(url_for('admin.admin')) return redirect(url_for('admin.admin'))
else: else:
@ -1072,8 +1041,7 @@ def _handle_edit_user(to_save, content,languages, translations, kobo_support):
return redirect(url_for('admin.admin')) return redirect(url_for('admin.admin'))
else: else:
if not ub.session.query(ub.User).filter(ub.User.role.op('&')(constants.ROLE_ADMIN) == constants.ROLE_ADMIN, 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 \ ub.User.id != content.id).count() and 'admin_role' not in to_save:
not 'admin_role' in to_save:
flash(_(u"No admin user remaining, can't remove admin role", nick=content.nickname), category="error") flash(_(u"No admin user remaining, can't remove admin role", nick=content.nickname), category="error")
return redirect(url_for('admin.admin')) return redirect(url_for('admin.admin'))
@ -1092,7 +1060,7 @@ def _handle_edit_user(to_save, content,languages, translations, kobo_support):
value = element['visibility'] value = element['visibility']
if value in val and not content.check_visibility(value): if value in val and not content.check_visibility(value):
content.sidebar_view |= 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 content.sidebar_view &= ~value
if "Show_detail_random" in to_save: if "Show_detail_random" in to_save:
@ -1139,10 +1107,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: if "kindle_mail" in to_save and to_save["kindle_mail"] != content.kindle_mail:
content.kindle_mail = to_save["kindle_mail"] content.kindle_mail = to_save["kindle_mail"]
try: try:
try: ub.session_commit()
ub.session.commit()
except OperationalError:
ub.session.rollback()
flash(_(u"User '%(nick)s' updated", nick=content.nickname), category="success") flash(_(u"User '%(nick)s' updated", nick=content.nickname), category="success")
except IntegrityError: except IntegrityError:
ub.session.rollback() ub.session.rollback()
@ -1264,9 +1229,8 @@ def reset_user_password(user_id):
@login_required @login_required
@admin_required @admin_required
def view_logfile(): def view_logfile():
logfiles = {} logfiles = {0: logger.get_logfile(config.config_logfile),
logfiles[0] = logger.get_logfile(config.config_logfile) 1: logger.get_accesslogfile(config.config_access_logfile)}
logfiles[1] = logger.get_accesslogfile(config.config_access_logfile)
return render_title_template("logviewer.html", return render_title_template("logviewer.html",
title=_(u"Logfile viewer"), title=_(u"Logfile viewer"),
accesslog_enable=config.config_access_log, accesslog_enable=config.config_access_log,
@ -1290,6 +1254,7 @@ def send_logfile(logtype):
else: else:
return "" return ""
@admi.route("/admin/logdownload/<int:logtype>") @admi.route("/admin/logdownload/<int:logtype>")
@login_required @login_required
@admin_required @admin_required
@ -1407,7 +1372,7 @@ def import_ldap_users():
kindlemail = '' kindlemail = ''
if 'mail' in user_data: if 'mail' in user_data:
useremail = user_data['mail'][0].decode('utf-8') 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') kindlemail = user_data['mail'][1].decode('utf-8')
else: else:
@ -1445,19 +1410,21 @@ def import_ldap_users():
def extract_user_data_from_field(user, field): 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: if match:
return match.group(1) return match.group(1)
else: else:
raise Exception("Could Not Parse LDAP User: {}".format(user)) 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: if match:
return match.group(1) return match.group(1)
else: else:
raise Exception("Could Not Parse LDAP Userfield: {}", user) 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) return extract_user_data_from_field(user, dynamic_field)

View File

@ -275,7 +275,7 @@ class _ConfigSQL(object):
def toDict(self): def toDict(self):
storage = {} storage = {}
for k, v in self.__dict__.items(): 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 storage[k] = v
return storage return storage

View File

@ -21,7 +21,12 @@ import shutil
import glob import glob
import zipfile import zipfile
import json import json
import io from io import BytesIO
try:
from StringIO import StringIO
except ImportError:
from io import StringIO
import os import os
from flask import send_file from flask import send_file
@ -32,11 +37,12 @@ from .about import collect_stats
log = logger.create() log = logger.create()
def assemble_logfiles(file_name): def assemble_logfiles(file_name):
log_list = glob.glob(file_name + '*') log_list = sorted(glob.glob(file_name + '*'), reverse=True)
wfd = io.StringIO() wfd = StringIO()
for f in log_list: for f in log_list:
with open(f, 'r') as fd: with open(f, 'r') as fd:
shutil.copyfileobj(fd, wfd) shutil.copyfileobj(fd, wfd)
wfd.seek(0)
return send_file(wfd, return send_file(wfd,
as_attachment=True, as_attachment=True,
attachment_filename=os.path.basename(file_name)) 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]: for element in [logger.LOG_TO_STDOUT, logger.LOG_TO_STDERR]:
if element in file_list: if element in file_list:
file_list.remove(element) file_list.remove(element)
memory_zip = io.BytesIO() memory_zip = BytesIO()
with zipfile.ZipFile(memory_zip, 'w', compression=zipfile.ZIP_DEFLATED) as zf: with zipfile.ZipFile(memory_zip, 'w', compression=zipfile.ZIP_DEFLATED) as zf:
zf.writestr('settings.txt', json.dumps(config.toDict())) zf.writestr('settings.txt', json.dumps(config.toDict()))
zf.writestr('libs.txt', json.dumps(collect_stats())) zf.writestr('libs.txt', json.dumps(collect_stats()))

View File

@ -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.BookShelf).filter(ub.BookShelf.book_id == book_id).delete()
ub.session.query(ub.ReadBook).filter(ub.ReadBook.book_id == book_id).delete() ub.session.query(ub.ReadBook).filter(ub.ReadBook.book_id == book_id).delete()
ub.delete_download(book_id) ub.delete_download(book_id)
ub.session.commit() ub.session_commit()
# check if only this book links to: # check if only this book links to:
# author, language, series, tags, custom columns # author, language, series, tags, custom columns

View File

@ -462,10 +462,7 @@ def HandleTagCreate():
items_unknown_to_calibre = add_items_to_shelf(items, shelf) items_unknown_to_calibre = add_items_to_shelf(items, shelf)
if items_unknown_to_calibre: if items_unknown_to_calibre:
log.debug("Received request to add unknown books to a collection. Silently ignoring items.") log.debug("Received request to add unknown books to a collection. Silently ignoring items.")
try: ub.session_commit()
ub.session.commit()
except OperationalError:
ub.session.rollback()
return make_response(jsonify(str(shelf.uuid)), 201) return make_response(jsonify(str(shelf.uuid)), 201)
@ -497,10 +494,7 @@ def HandleTagUpdate(tag_id):
shelf.name = name shelf.name = name
ub.session.merge(shelf) ub.session.merge(shelf)
try: ub.session_commit()
ub.session.commit()
except OperationalError:
ub.session.rollback()
return make_response(' ', 200) 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.") log.debug("Received request to add an unknown book to a collection. Silently ignoring item.")
ub.session.merge(shelf) ub.session.merge(shelf)
try: ub.session_commit()
ub.session.commit()
except OperationalError:
ub.session.rollback()
return make_response('', 201) return make_response('', 201)
@ -596,10 +586,7 @@ def HandleTagRemoveItem(tag_id):
shelf.books.filter(ub.BookShelf.book_id == book.id).delete() shelf.books.filter(ub.BookShelf.book_id == book.id).delete()
except KeyError: except KeyError:
items_unknown_to_calibre.append(item) items_unknown_to_calibre.append(item)
try: ub.session_commit()
ub.session.commit()
except OperationalError:
ub.session.rollback()
if items_unknown_to_calibre: if items_unknown_to_calibre:
log.debug("Received request to remove an unknown book to a collecition. Silently ignoring item.") 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 "ChangedTag": tag
}) })
sync_token.tags_last_modified = new_tags_last_modified sync_token.tags_last_modified = new_tags_last_modified
try: ub.session_commit()
ub.session.commit()
except OperationalError:
ub.session.rollback()
# Creates a Kobo "Tag" object from a ub.Shelf object # 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") abort(400, description="Malformed request data is missing 'ReadingStates' key")
ub.session.merge(kobo_reading_state) ub.session.merge(kobo_reading_state)
try: ub.session_commit()
ub.session.commit()
except OperationalError:
ub.session.rollback()
return jsonify({ return jsonify({
"RequestResult": "Success", "RequestResult": "Success",
"UpdateResults": [update_results_response], "UpdateResults": [update_results_response],
@ -770,10 +751,7 @@ def get_or_create_reading_state(book_id):
kobo_reading_state.statistics = ub.KoboStatistics() kobo_reading_state.statistics = ub.KoboStatistics()
book_read.kobo_reading_state = kobo_reading_state book_read.kobo_reading_state = kobo_reading_state
ub.session.add(book_read) ub.session.add(book_read)
try: ub.session_commit()
ub.session.commit()
except OperationalError:
ub.session.rollback()
return book_read.kobo_reading_state return book_read.kobo_reading_state
@ -876,11 +854,7 @@ def HandleBookDeletionRequest(book_uuid):
archived_book.last_modified = datetime.datetime.utcnow() archived_book.last_modified = datetime.datetime.utcnow()
ub.session.merge(archived_book) ub.session.merge(archived_book)
try: ub.session_commit()
ub.session.commit()
except OperationalError:
ub.session.rollback()
return ("", 204) return ("", 204)

View File

@ -148,10 +148,7 @@ def generate_auth_token(user_id):
auth_token.token_type = 1 auth_token.token_type = 1
ub.session.add(auth_token) ub.session.add(auth_token)
try: ub.session_commit()
ub.session.commit()
except OperationalError:
ub.session.rollback()
return render_title_template( return render_title_template(
"generate_kobo_auth_url.html", "generate_kobo_auth_url.html",
title=_(u"Kobo Setup"), title=_(u"Kobo Setup"),
@ -168,8 +165,5 @@ def delete_auth_token(user_id):
# Invalidate any prevously generated Kobo Auth token for this user. # Invalidate any prevously generated Kobo Auth token for this user.
ub.session.query(ub.RemoteAuthToken).filter(ub.RemoteAuthToken.user_id == user_id)\ ub.session.query(ub.RemoteAuthToken).filter(ub.RemoteAuthToken.user_id == user_id)\
.filter(ub.RemoteAuthToken.token_type==1).delete() .filter(ub.RemoteAuthToken.token_type==1).delete()
try:
ub.session.commit() return ub.session_commit()
except OperationalError:
ub.session.rollback()
return ""

View File

@ -49,6 +49,13 @@ class _Logger(logging.Logger):
else: else:
self.error(message, stacklevel=2, *args, **kwargs) 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): def get(name=None):
return logging.getLogger(name) return logging.getLogger(name)

View File

@ -85,11 +85,7 @@ def register_user_with_oauth(user=None):
except NoResultFound: except NoResultFound:
# no found, return error # no found, return error
return return
try: ub.session_commit("User {} with OAuth for provider {} registered".format(user.nickname, oauth_key))
ub.session.commit()
except Exception as e:
log.debug_or_exception(e)
ub.session.rollback()
def logout_oauth_user(): def logout_oauth_user():
@ -101,19 +97,12 @@ def logout_oauth_user():
if ub.oauth_support: if ub.oauth_support:
oauthblueprints = [] oauthblueprints = []
if not ub.session.query(ub.OAuthProvider).count(): if not ub.session.query(ub.OAuthProvider).count():
for provider in ("github", "google"):
oauthProvider = ub.OAuthProvider() oauthProvider = ub.OAuthProvider()
oauthProvider.provider_name = "github" oauthProvider.provider_name = provider
oauthProvider.active = False oauthProvider.active = False
ub.session.add(oauthProvider) ub.session.add(oauthProvider)
ub.session.commit() ub.session_commit("{} Blueprint Created".format(provider))
oauthProvider = ub.OAuthProvider()
oauthProvider.provider_name = "google"
oauthProvider.active = False
ub.session.add(oauthProvider)
try:
ub.session.commit()
except OperationalError:
ub.session.rollback()
oauth_ids = ub.session.query(ub.OAuthProvider).all() oauth_ids = ub.session.query(ub.OAuthProvider).all()
ele1 = dict(provider_name='github', ele1 = dict(provider_name='github',
@ -203,12 +192,8 @@ if ub.oauth_support:
provider_user_id=provider_user_id, provider_user_id=provider_user_id,
token=token, token=token,
) )
try:
ub.session.add(oauth_entry) ub.session.add(oauth_entry)
ub.session.commit() ub.session_commit()
except Exception as e:
log.debug_or_exception(e)
ub.session.rollback()
# Disable Flask-Dance's default behavior for saving the OAuth token # Disable Flask-Dance's default behavior for saving the OAuth token
# Value differrs depending on flask-dance version # Value differrs depending on flask-dance version

View File

@ -59,8 +59,7 @@ def remote_login_required(f):
def remote_login(): def remote_login():
auth_token = ub.RemoteAuthToken() auth_token = ub.RemoteAuthToken()
ub.session.add(auth_token) 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) 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) 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, 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')) return redirect(url_for('web.index'))
# Token expired # Token expired
if datetime.now() > auth_token.expiration: elif datetime.now() > auth_token.expiration:
ub.session.delete(auth_token) ub.session.delete(auth_token)
ub.session.commit() ub.session_commit()
flash(_(u"Token has expired"), category="error") flash(_(u"Token has expired"), category="error")
log.error(u"Remote Login token expired") log.error(u"Remote Login token expired")
@ -91,7 +90,7 @@ def verify_token(token):
# Update token with user information # Update token with user information
auth_token.user_id = current_user.id auth_token.user_id = current_user.id
auth_token.verified = True auth_token.verified = True
ub.session.commit() ub.session_commit()
flash(_(u"Success! Please return to your device"), category="success") flash(_(u"Success! Please return to your device"), category="success")
log.debug(u"Remote Login token for userid %s verified", auth_token.user_id) log.debug(u"Remote Login token for userid %s verified", auth_token.user_id)
@ -114,7 +113,7 @@ def token_verified():
# Token expired # Token expired
elif datetime.now() > auth_token.expiration: elif datetime.now() > auth_token.expiration:
ub.session.delete(auth_token) ub.session.delete(auth_token)
ub.session.commit() ub.session_commit()
data['status'] = 'error' data['status'] = 'error'
data['message'] = _(u"Token has expired") data['message'] = _(u"Token has expired")
@ -127,7 +126,7 @@ def token_verified():
login_user(user) login_user(user)
ub.session.delete(auth_token) ub.session.delete(auth_token)
ub.session.commit() ub.session_commit("User {} logged in via remotelogin, token deleted".format(user.nickname))
data['status'] = 'success' data['status'] = 'success'
log.debug(u"Remote Login for userid %s succeded", user.id) log.debug(u"Remote Login for userid %s succeded", user.id)

View File

@ -27,7 +27,7 @@ import sys
from flask import Blueprint, request, flash, redirect, url_for from flask import Blueprint, request, flash, redirect, url_for
from flask_babel import gettext as _ from flask_babel import gettext as _
from flask_login import login_required, current_user 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 sqlalchemy.exc import OperationalError, InvalidRequestError
from . import logger, ub, calibre_db, db from . import logger, ub, calibre_db, db
@ -221,61 +221,60 @@ def remove_from_shelf(shelf_id, book_id):
@login_required @login_required
def create_shelf(): def create_shelf():
shelf = ub.Shelf() shelf = ub.Shelf()
if request.method == "POST": return create_edit_shelf(shelf, title=_(u"Create a Shelf"), page="shelfcreate")
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")
@shelf.route("/shelf/edit/<int:shelf_id>", methods=["GET", "POST"]) @shelf.route("/shelf/edit/<int:shelf_id>", methods=["GET", "POST"])
@login_required @login_required
def edit_shelf(shelf_id): def edit_shelf(shelf_id):
shelf = ub.session.query(ub.Shelf).filter(ub.Shelf.id == shelf_id).first() shelf = ub.session.query(ub.Shelf).filter(ub.Shelf.id == shelf_id).first()
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, title, page, shelf_id=False):
if request.method == "POST": if request.method == "POST":
to_save = request.form.to_dict() 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):
shelf.name = to_save["title"]
# 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:
ub.session.commit()
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 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=title, page=page)
is_shelf_name_unique = False
def check_shelf_is_unique(shelf, to_save, shelf_id=False):
if shelf_id:
ident = ub.Shelf.id != shelf_id
else:
ident = true()
if shelf.is_public == 1: if shelf.is_public == 1:
is_shelf_name_unique = ub.session.query(ub.Shelf) \ is_shelf_name_unique = ub.session.query(ub.Shelf) \
.filter((ub.Shelf.name == to_save["title"]) & (ub.Shelf.is_public == 1)) \ .filter((ub.Shelf.name == to_save["title"]) & (ub.Shelf.is_public == 1)) \
.filter(ub.Shelf.id != shelf_id) \ .filter(ident) \
.first() is None .first() is None
if not is_shelf_name_unique: if not is_shelf_name_unique:
@ -285,32 +284,13 @@ def edit_shelf(shelf_id):
is_shelf_name_unique = ub.session.query(ub.Shelf) \ is_shelf_name_unique = ub.session.query(ub.Shelf) \
.filter((ub.Shelf.name == to_save["title"]) & (ub.Shelf.is_public == 0) & .filter((ub.Shelf.name == to_save["title"]) & (ub.Shelf.is_public == 0) &
(ub.Shelf.user_id == int(current_user.id))) \ (ub.Shelf.user_id == int(current_user.id))) \
.filter(ub.Shelf.id != shelf_id)\ .filter(ident) \
.first() is None .first() is None
if not is_shelf_name_unique: if not is_shelf_name_unique:
flash(_(u"A private shelf with the name '%(title)s' already exists.", title=to_save["title"]), flash(_(u"A private shelf with the name '%(title)s' already exists.", title=to_save["title"]),
category="error") category="error")
return is_shelf_name_unique
if is_shelf_name_unique:
shelf.name = to_save["title"]
shelf.last_modified = datetime.utcnow()
if "is_public" in to_save:
shelf.is_public = 1
else:
shelf.is_public = 0
try:
ub.session.commit()
flash(_(u"Shelf %(title)s changed", title=to_save["title"]), category="success")
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"Edit a shelf"), page="shelfedit")
else:
return render_title_template('shelf_edit.html', shelf=shelf, title=_(u"Edit a shelf"), page="shelfedit")
def delete_shelf_helper(cur_shelf): def delete_shelf_helper(cur_shelf):
@ -320,12 +300,7 @@ def delete_shelf_helper(cur_shelf):
ub.session.delete(cur_shelf) ub.session.delete(cur_shelf)
ub.session.query(ub.BookShelf).filter(ub.BookShelf.shelf == shelf_id).delete() 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)) ub.session.add(ub.ShelfArchive(uuid=cur_shelf.uuid, user_id=cur_shelf.user_id))
try: ub.session_commit("successfully deleted Shelf {}".format(cur_shelf.name))
ub.session.commit()
log.info("successfully deleted %s", cur_shelf)
except OperationalError:
ub.session.rollback()
@shelf.route("/shelf/delete/<int:shelf_id>") @shelf.route("/shelf/delete/<int:shelf_id>")
@ -339,11 +314,13 @@ def delete_shelf(shelf_id):
flash(_(u"Settings DB is not Writeable"), category="error") flash(_(u"Settings DB is not Writeable"), category="error")
return redirect(url_for('web.index')) return redirect(url_for('web.index'))
@shelf.route("/simpleshelf/<int:shelf_id>") @shelf.route("/simpleshelf/<int:shelf_id>")
@login_required_if_no_ano @login_required_if_no_ano
def show_simpleshelf(shelf_id): def show_simpleshelf(shelf_id):
return render_show_shelf(2, shelf_id, 1, None) return render_show_shelf(2, shelf_id, 1, None)
@shelf.route("/shelf/<int:shelf_id>", defaults={"sort_param": "order", 'page': 1}) @shelf.route("/shelf/<int:shelf_id>", defaults={"sort_param": "order", 'page': 1})
@shelf.route("/shelf/<int:shelf_id>/<sort_param>", defaults={'page': 1}) @shelf.route("/shelf/<int:shelf_id>/<sort_param>", defaults={'page': 1})
@shelf.route("/shelf/<int:shelf_id>/<sort_param>/<int:page>") @shelf.route("/shelf/<int:shelf_id>/<sort_param>/<int:page>")
@ -381,6 +358,7 @@ def order_shelf(shelf_id):
title=_(u"Change order of Shelf: '%(name)s'", name=shelf.name), title=_(u"Change order of Shelf: '%(name)s'", name=shelf.name),
shelf=shelf, page="shelforder") shelf=shelf, page="shelforder")
def change_shelf_order(shelf_id, order): def change_shelf_order(shelf_id, order):
result = calibre_db.session.query(db.Books).join(ub.BookShelf,ub.BookShelf.book_id == db.Books.id)\ 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() .filter(ub.BookShelf.shelf == shelf_id).order_by(*order).all()
@ -388,10 +366,8 @@ def change_shelf_order(shelf_id, order):
book = ub.session.query(ub.BookShelf).filter(ub.BookShelf.shelf == shelf_id) \ book = ub.session.query(ub.BookShelf).filter(ub.BookShelf.shelf == shelf_id) \
.filter(ub.BookShelf.book_id == entry.id).first() .filter(ub.BookShelf.book_id == entry.id).first()
book.order = index book.order = index
try: ub.session_commit("Shelf-id:{} - Order changed".format(shelf_id))
ub.session.commit()
except OperationalError:
ub.session.rollback()
def render_show_shelf(shelf_type, shelf_id, page_no, sort_param): 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() shelf = ub.session.query(ub.Shelf).filter(ub.Shelf.id == shelf_id).first()

View File

@ -411,19 +411,6 @@ bitjs.archive = bitjs.archive || {};
return "unrar.js"; 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 * Untarrer
* @extends {bitjs.archive.Unarchiver} * @extends {bitjs.archive.Unarchiver}

View File

@ -14,10 +14,10 @@
/* global VM_FIXEDGLOBALSIZE, VM_GLOBALMEMSIZE, MAXWINMASK, VM_GLOBALMEMADDR, MAXWINSIZE */ /* global VM_FIXEDGLOBALSIZE, VM_GLOBALMEMSIZE, MAXWINMASK, VM_GLOBALMEMADDR, MAXWINSIZE */
// This file expects to be invoked as a Worker (see onmessage below). // 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("../io/bytebuffer.js");
importScripts("archive.js"); importScripts("archive.js");
importScripts("rarvm.js");*/ importScripts("rarvm.js");
// Progress variables. // Progress variables.
var currentFilename = ""; var currentFilename = "";
@ -29,21 +29,19 @@ var totalFilesInArchive = 0;
// Helper functions. // Helper functions.
var info = function(str) { var info = function(str) {
console.log(str); postMessage(new bitjs.archive.UnarchiveInfoEvent(str));
// postMessage(new bitjs.archive.UnarchiveInfoEvent(str));
}; };
var err = function(str) { var err = function(str) {
console.log(str); postMessage(new bitjs.archive.UnarchiveErrorEvent(str));
// postMessage(new bitjs.archive.UnarchiveErrorEvent(str));
}; };
var postProgress = function() { var postProgress = function() {
/*postMessage(new bitjs.archive.UnarchiveProgressEvent( postMessage(new bitjs.archive.UnarchiveProgressEvent(
currentFilename, currentFilename,
currentFileNumber, currentFileNumber,
currentBytesUnarchivedInFile, currentBytesUnarchivedInFile,
currentBytesUnarchived, currentBytesUnarchived,
totalUncompressedBytesInArchive, totalUncompressedBytesInArchive,
totalFilesInArchive));*/ totalFilesInArchive));
}; };
// shows a byte value as its hex representation // shows a byte value as its hex representation
@ -1300,7 +1298,7 @@ var unrar = function(arrayBuffer) {
totalUncompressedBytesInArchive = 0; totalUncompressedBytesInArchive = 0;
totalFilesInArchive = 0; totalFilesInArchive = 0;
//postMessage(new bitjs.archive.UnarchiveStartEvent()); postMessage(new bitjs.archive.UnarchiveStartEvent());
var bstream = new bitjs.io.BitStream(arrayBuffer, false /* rtl */); var bstream = new bitjs.io.BitStream(arrayBuffer, false /* rtl */);
var header = new RarVolumeHeader(bstream); var header = new RarVolumeHeader(bstream);
@ -1350,7 +1348,7 @@ var unrar = function(arrayBuffer) {
localfile.unrar(); localfile.unrar();
if (localfile.isValid) { if (localfile.isValid) {
// postMessage(new bitjs.archive.UnarchiveExtractEvent(localfile)); postMessage(new bitjs.archive.UnarchiveExtractEvent(localfile));
postProgress(); postProgress();
} }
} }
@ -1360,7 +1358,7 @@ var unrar = function(arrayBuffer) {
} else { } else {
err("Invalid RAR file"); err("Invalid RAR file");
} }
// postMessage(new bitjs.archive.UnarchiveFinishEvent()); postMessage(new bitjs.archive.UnarchiveFinishEvent());
}; };
// event.data.file has the ArrayBuffer. // event.data.file has the ArrayBuffer.

View File

@ -162,15 +162,10 @@ function initProgressClick() {
function loadFromArrayBuffer(ab) { function loadFromArrayBuffer(ab) {
var start = (new Date).getTime(); var start = (new Date).getTime();
var h = new Uint8Array(ab, 0, 10); var h = new Uint8Array(ab, 0, 10);
unrar5(ab);
var pathToBitJS = "../../static/js/archive/"; var pathToBitJS = "../../static/js/archive/";
var lastCompletion = 0; var lastCompletion = 0;
/*if (h[0] === 0x52 && h[1] === 0x61 && h[2] === 0x72 && h[3] === 0x21) { //Rar! 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); unarchiver = new bitjs.archive.Unrarrer(ab, pathToBitJS);
} else {
unarchiver = new bitjs.archive.Unrarrer5(ab, pathToBitJS);
}
} else if (h[0] === 80 && h[1] === 75) { //PK (Zip) } else if (h[0] === 80 && h[1] === 75) { //PK (Zip)
unarchiver = new bitjs.archive.Unzipper(ab, pathToBitJS); unarchiver = new bitjs.archive.Unzipper(ab, pathToBitJS);
} else if (h[0] === 255 && h[1] === 216) { // JPEG } else if (h[0] === 255 && h[1] === 216) { // JPEG
@ -234,7 +229,7 @@ function loadFromArrayBuffer(ab) {
unarchiver.start(); unarchiver.start();
} else { } else {
alert("Some error"); alert("Some error");
}*/ }
} }
function scrollTocToActive() { function scrollTocToActive() {

View File

@ -66,9 +66,15 @@ class TaskConvert(CalibreTask):
# if we're sending to kindle after converting, create a one-off task and run it immediately # 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 # todo: figure out how to incorporate this into the progress
try: try:
worker_thread.add(self.user, TaskEmail(self.settings['subject'], self.results["path"], worker_thread.add(self.user, TaskEmail(self.settings['subject'],
filename, self.settings, self.kindle_mail, self.results["path"],
self.settings['subject'], self.settings['body'], internal=True)) filename,
self.settings,
self.kindle_mail,
self.settings['subject'],
self.settings['body'],
internal=True)
)
except Exception as e: except Exception as e:
return self._handleError(str(e)) return self._handleError(str(e))

View File

@ -44,7 +44,7 @@ class EmailBase:
def send(self, strg): def send(self, strg):
"""Send `strg' to the server.""" """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: if hasattr(self, 'sock') and self.sock:
try: try:
if self.transferSize: if self.transferSize:

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -49,6 +49,7 @@ from werkzeug.security import generate_password_hash
from . import cli, constants, logger from . import cli, constants, logger
log = logger.create()
session = None session = None
app_DB_path = None app_DB_path = None
@ -729,3 +730,13 @@ def dispose():
old_session.bind.dispose() old_session.bind.dispose()
except Exception: except Exception:
pass 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 ""

View File

@ -136,10 +136,7 @@ def bookmark(book_id, book_format):
ub.Bookmark.book_id == book_id, ub.Bookmark.book_id == book_id,
ub.Bookmark.format == book_format)).delete() ub.Bookmark.format == book_format)).delete()
if not bookmark_key: if not bookmark_key:
try: ub.session_commit()
ub.session.commit()
except OperationalError:
ub.session.rollback()
return "", 204 return "", 204
lbookmark = ub.Bookmark(user_id=current_user.id, lbookmark = ub.Bookmark(user_id=current_user.id,
@ -147,10 +144,7 @@ def bookmark(book_id, book_format):
format=book_format, format=book_format,
bookmark_key=bookmark_key) bookmark_key=bookmark_key)
ub.session.merge(lbookmark) ub.session.merge(lbookmark)
try: ub.session_commit("Bookmark for user {} in book {} created".format(current_user.id, book_id))
ub.session.commit()
except OperationalError:
ub.session.rollback()
return "", 201 return "", 201
@ -175,10 +169,7 @@ def toggle_read(book_id):
kobo_reading_state.statistics = ub.KoboStatistics() kobo_reading_state.statistics = ub.KoboStatistics()
book.kobo_reading_state = kobo_reading_state book.kobo_reading_state = kobo_reading_state
ub.session.merge(book) ub.session.merge(book)
try: ub.session_commit("Book {} readbit toggled".format(book_id))
ub.session.commit()
except OperationalError:
ub.session.rollback()
else: else:
try: try:
calibre_db.update_title_sort(config) calibre_db.update_title_sort(config)
@ -212,10 +203,7 @@ def toggle_archived(book_id):
archived_book = ub.ArchivedBook(user_id=current_user.id, book_id=book_id) archived_book = ub.ArchivedBook(user_id=current_user.id, book_id=book_id)
archived_book.is_archived = True archived_book.is_archived = True
ub.session.merge(archived_book) ub.session.merge(archived_book)
try: ub.session_commit("Book {} archivebit toggled".format(book_id))
ub.session.commit()
except OperationalError:
ub.session.rollback()
return "" return ""

File diff suppressed because it is too large Load Diff