Merge branch 'master' of https://github.com/janeczku/calibre-web
This commit is contained in:
commit
2f3f13afb9
|
@ -245,7 +245,7 @@ def list_users():
|
|||
off = int(request.args.get("offset") or 0)
|
||||
limit = int(request.args.get("limit") or 10)
|
||||
search = request.args.get("search")
|
||||
sort = request.args.get("sort", "state")
|
||||
sort = request.args.get("sort", "id")
|
||||
order = request.args.get("order", "").lower()
|
||||
state = None
|
||||
if sort == "state":
|
||||
|
@ -254,7 +254,7 @@ def list_users():
|
|||
if sort != "state" and order:
|
||||
order = text(sort + " " + order)
|
||||
elif not state:
|
||||
order = ub.User.name.desc()
|
||||
order = ub.User.id.asc()
|
||||
|
||||
all_user = ub.session.query(ub.User)
|
||||
if not config.config_anonbrowse:
|
||||
|
@ -371,7 +371,7 @@ def edit_list_user(param):
|
|||
'message':_(u"No admin user remaining, can't remove admin role",
|
||||
nick=user.name)}), mimetype='application/json')
|
||||
user.role &= ~int(vals['field_index'])
|
||||
elif param == 'sidebar_view':
|
||||
elif param.startswith('sidebar'):
|
||||
if user.name == "Guest" and int(vals['field_index']) == constants.SIDEBAR_READ_AND_UNREAD:
|
||||
raise Exception(_("Guest can't have this view"))
|
||||
if vals['value'] == 'true':
|
||||
|
|
|
@ -324,19 +324,19 @@ def delete_book(book_id, book_format, jsonResponse):
|
|||
result, error = helper.delete_book(book, config.config_calibre_dir, book_format=book_format.upper())
|
||||
if not result:
|
||||
if jsonResponse:
|
||||
return json.dumps({"location": url_for("editbook.edit_book"),
|
||||
"type": "alert",
|
||||
return json.dumps([{"location": url_for("editbook.edit_book", book_id=book_id),
|
||||
"type": "danger",
|
||||
"format": "",
|
||||
"error": error}),
|
||||
"message": error}])
|
||||
else:
|
||||
flash(error, category="error")
|
||||
return redirect(url_for('editbook.edit_book', book_id=book_id))
|
||||
if error:
|
||||
if jsonResponse:
|
||||
warning = {"location": url_for("editbook.edit_book"),
|
||||
warning = {"location": url_for("editbook.edit_book", book_id=book_id),
|
||||
"type": "warning",
|
||||
"format": "",
|
||||
"error": error}
|
||||
"message": error}
|
||||
else:
|
||||
flash(error, category="warning")
|
||||
if not book_format:
|
||||
|
@ -348,6 +348,15 @@ def delete_book(book_id, book_format, jsonResponse):
|
|||
except Exception as ex:
|
||||
log.debug_or_exception(ex)
|
||||
calibre_db.session.rollback()
|
||||
if jsonResponse:
|
||||
return json.dumps([{"location": url_for("editbook.edit_book", book_id=book_id),
|
||||
"type": "danger",
|
||||
"format": "",
|
||||
"message": ex}])
|
||||
else:
|
||||
flash(str(ex), category="error")
|
||||
return redirect(url_for('editbook.edit_book', book_id=book_id))
|
||||
|
||||
else:
|
||||
# book not found
|
||||
log.error('Book with id "%s" could not be deleted: not found', book_id)
|
||||
|
|
|
@ -30,6 +30,7 @@ from flask_babel import gettext as _
|
|||
from flask_dance.consumer import oauth_authorized, oauth_error
|
||||
from flask_dance.contrib.github import make_github_blueprint, github
|
||||
from flask_dance.contrib.google import make_google_blueprint, google
|
||||
from oauthlib.oauth2 import TokenExpiredError, InvalidGrantError
|
||||
from flask_login import login_user, current_user, login_required
|
||||
from sqlalchemy.orm.exc import NoResultFound
|
||||
|
||||
|
@ -146,6 +147,7 @@ def bind_oauth_or_register(provider_id, provider_user_id, redirect_url, provider
|
|||
ub.session.add(oauth_entry)
|
||||
ub.session.commit()
|
||||
flash(_(u"Link to %(oauth)s Succeeded", oauth=provider_name), category="success")
|
||||
log.info("Link to {} Succeeded".format(provider_name))
|
||||
return redirect(url_for('web.profile'))
|
||||
except Exception as ex:
|
||||
log.debug_or_exception(ex)
|
||||
|
@ -194,6 +196,7 @@ def unlink_oauth(provider):
|
|||
ub.session.commit()
|
||||
logout_oauth_user()
|
||||
flash(_(u"Unlink to %(oauth)s Succeeded", oauth=oauth_check[provider]), category="success")
|
||||
log.info("Unlink to {} Succeeded".format(oauth_check[provider]))
|
||||
except Exception as ex:
|
||||
log.debug_or_exception(ex)
|
||||
ub.session.rollback()
|
||||
|
@ -257,11 +260,13 @@ if ub.oauth_support:
|
|||
def github_logged_in(blueprint, token):
|
||||
if not token:
|
||||
flash(_(u"Failed to log in with GitHub."), category="error")
|
||||
log.error("Failed to log in with GitHub")
|
||||
return False
|
||||
|
||||
resp = blueprint.session.get("/user")
|
||||
if not resp.ok:
|
||||
flash(_(u"Failed to fetch user info from GitHub."), category="error")
|
||||
log.error("Failed to fetch user info from GitHub")
|
||||
return False
|
||||
|
||||
github_info = resp.json()
|
||||
|
@ -273,11 +278,13 @@ if ub.oauth_support:
|
|||
def google_logged_in(blueprint, token):
|
||||
if not token:
|
||||
flash(_(u"Failed to log in with Google."), category="error")
|
||||
log.error("Failed to log in with Google")
|
||||
return False
|
||||
|
||||
resp = blueprint.session.get("/oauth2/v2/userinfo")
|
||||
if not resp.ok:
|
||||
flash(_(u"Failed to fetch user info from Google."), category="error")
|
||||
log.error("Failed to fetch user info from Google")
|
||||
return False
|
||||
|
||||
google_info = resp.json()
|
||||
|
@ -318,11 +325,16 @@ if ub.oauth_support:
|
|||
def github_login():
|
||||
if not github.authorized:
|
||||
return redirect(url_for('github.login'))
|
||||
account_info = github.get('/user')
|
||||
if account_info.ok:
|
||||
account_info_json = account_info.json()
|
||||
return bind_oauth_or_register(oauthblueprints[0]['id'], account_info_json['id'], 'github.login', 'github')
|
||||
flash(_(u"GitHub Oauth error, please retry later."), category="error")
|
||||
try:
|
||||
account_info = github.get('/user')
|
||||
if account_info.ok:
|
||||
account_info_json = account_info.json()
|
||||
return bind_oauth_or_register(oauthblueprints[0]['id'], account_info_json['id'], 'github.login', 'github')
|
||||
flash(_(u"GitHub Oauth error, please retry later."), category="error")
|
||||
log.error("GitHub Oauth error, please retry later")
|
||||
except (InvalidGrantError, TokenExpiredError) as e:
|
||||
flash(_(u"GitHub Oauth error: {}").format(e), category="error")
|
||||
log.error(e)
|
||||
return redirect(url_for('web.login'))
|
||||
|
||||
|
||||
|
@ -337,11 +349,16 @@ def github_login_unlink():
|
|||
def google_login():
|
||||
if not google.authorized:
|
||||
return redirect(url_for("google.login"))
|
||||
resp = google.get("/oauth2/v2/userinfo")
|
||||
if resp.ok:
|
||||
account_info_json = resp.json()
|
||||
return bind_oauth_or_register(oauthblueprints[1]['id'], account_info_json['id'], 'google.login', 'google')
|
||||
flash(_(u"Google Oauth error, please retry later."), category="error")
|
||||
try:
|
||||
resp = google.get("/oauth2/v2/userinfo")
|
||||
if resp.ok:
|
||||
account_info_json = resp.json()
|
||||
return bind_oauth_or_register(oauthblueprints[1]['id'], account_info_json['id'], 'google.login', 'google')
|
||||
flash(_(u"Google Oauth error, please retry later."), category="error")
|
||||
log.error("Google Oauth error, please retry later")
|
||||
except (InvalidGrantError, TokenExpiredError) as e:
|
||||
flash(_(u"Google Oauth error: {}").format(e), category="error")
|
||||
log.error(e)
|
||||
return redirect(url_for('web.login'))
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
{% extends "layout.html" %}
|
||||
{% macro text_table_row(parameter, edit_text, show_text, validate) -%}
|
||||
<th data-field="{{ parameter }}" id="{{ parameter }}" data-sortable="true"
|
||||
{% macro text_table_row(parameter, edit_text, show_text, validate, sort) -%}
|
||||
<th data-field="{{ parameter }}" id="{{ parameter }}"
|
||||
{% if sort %}data-sortable="true" {% endif %}
|
||||
data-visible = "{{visiblility.get(parameter)}}"
|
||||
{% if g.user.role_edit() %}
|
||||
data-editable-type="text"
|
||||
|
@ -43,16 +44,16 @@
|
|||
<th data-field="state" data-checkbox="true" data-sortable="true"></th>
|
||||
{% endif %}
|
||||
<th data-field="id" id="id" data-visible="false" data-switchable="false"></th>
|
||||
{{ text_table_row('title', _('Enter Title'),_('Title'), true) }}
|
||||
{{ text_table_row('sort', _('Enter Title Sort'),_('Title Sort'), false) }}
|
||||
{{ text_table_row('author_sort', _('Enter Author Sort'),_('Author Sort'), false) }}
|
||||
{{ text_table_row('title', _('Enter Title'),_('Title'), true, true) }}
|
||||
{{ text_table_row('sort', _('Enter Title Sort'),_('Title Sort'), false, true) }}
|
||||
{{ text_table_row('author_sort', _('Enter Author Sort'),_('Author Sort'), false, true) }}
|
||||
{{ text_table_row('authors', _('Enter Authors'),_('Authors'), true) }}
|
||||
{{ text_table_row('tags', _('Enter Categories'),_('Categories'), false) }}
|
||||
{{ text_table_row('series', _('Enter Series'),_('Series'), false) }}
|
||||
{{ text_table_row('tags', _('Enter Categories'),_('Categories'), false, false) }}
|
||||
{{ text_table_row('series', _('Enter Series'),_('Series'), false, false) }}
|
||||
<th data-field="series_index" id="series_index" data-visible="{{visiblility.get('series_index')}}" data-edit-validate="{{ _('This Field is Required') }}" data-sortable="true" {% if g.user.role_edit() %} data-editable-type="number" data-editable-placeholder="1" data-editable-step="0.01" data-editable-min="0" data-editable-url="{{ url_for('editbook.edit_list_book', param='series_index')}}" data-edit="true" data-editable-title="{{_('Enter title')}}"{% endif %}>{{_('Series Index')}}</th>
|
||||
{{ text_table_row('languages', _('Enter Languages'),_('Languages'), false) }}
|
||||
{{ text_table_row('languages', _('Enter Languages'),_('Languages'), false, false) }}
|
||||
<!--th data-field="pubdate" data-type="date" data-visible="{{visiblility.get('pubdate')}}" data-viewformat="dd.mm.yyyy" id="pubdate" data-sortable="true">{{_('Publishing Date')}}</th-->
|
||||
{{ text_table_row('publishers', _('Enter Publishers'),_('Publishers'), false) }}
|
||||
{{ text_table_row('publishers', _('Enter Publishers'),_('Publishers'), false, false) }}
|
||||
{% if g.user.role_delete_books() and g.user.role_edit()%}
|
||||
<th data-align="right" data-formatter="EbookActions" data-switchable="false">{{_('Delete')}}</th>
|
||||
{% endif %}
|
||||
|
|
|
@ -92,7 +92,7 @@
|
|||
{% for message in get_flashed_messages(with_categories=True) %}
|
||||
{%if message[0] == "error" %}
|
||||
<div class="row-fluid text-center" style="margin-top: -20px;">
|
||||
<div id="flash_alert" class="alert alert-danger">{{ message[1] }}</div>
|
||||
<div id="flash_danger" class="alert alert-danger">{{ message[1] }}</div>
|
||||
</div>
|
||||
{%endif%}
|
||||
{%if message[0] == "info" %}
|
||||
|
|
11
cps/web.py
11
cps/web.py
|
@ -26,6 +26,7 @@ from datetime import datetime
|
|||
import json
|
||||
import mimetypes
|
||||
import chardet # dependency of requests
|
||||
import copy
|
||||
|
||||
from babel.dates import format_date
|
||||
from babel import Locale as LC
|
||||
|
@ -756,13 +757,12 @@ def list_books():
|
|||
off = int(request.args.get("offset") or 0)
|
||||
limit = int(request.args.get("limit") or config.config_books_per_page)
|
||||
search = request.args.get("search")
|
||||
sort = request.args.get("sort", "state")
|
||||
sort = request.args.get("sort", "id")
|
||||
order = request.args.get("order", "").lower()
|
||||
state = None
|
||||
|
||||
if sort == "state":
|
||||
state = json.loads(request.args.get("state", "[]"))
|
||||
|
||||
if sort != "state" and order:
|
||||
order = [text(sort + " " + order)]
|
||||
elif not state:
|
||||
|
@ -831,9 +831,12 @@ def author_list():
|
|||
charlist = calibre_db.session.query(func.upper(func.substr(db.Authors.sort, 1, 1)).label('char')) \
|
||||
.join(db.books_authors_link).join(db.Books).filter(calibre_db.common_filters()) \
|
||||
.group_by(func.upper(func.substr(db.Authors.sort, 1, 1))).all()
|
||||
for entry in entries:
|
||||
# If not creating a copy, readonly databases can not display authornames with "|" in it as changing the name
|
||||
# starts a change session
|
||||
autor_copy = copy.deepcopy(entries)
|
||||
for entry in autor_copy:
|
||||
entry.Authors.name = entry.Authors.name.replace('|', ',')
|
||||
return render_title_template('list.html', entries=entries, folder='web.books_list', charlist=charlist,
|
||||
return render_title_template('list.html', entries=autor_copy, folder='web.books_list', charlist=charlist,
|
||||
title=u"Authors", page="authorlist", data='author', order=order_no)
|
||||
else:
|
||||
abort(404)
|
||||
|
|
|
@ -26,7 +26,7 @@ python-ldap>=3.0.0,<3.4.0
|
|||
Flask-SimpleLDAP>=1.4.0,<1.5.0
|
||||
|
||||
#oauth
|
||||
Flask-Dance>=1.4.0,<3.1.0
|
||||
Flask-Dance>=1.4.0,<4.1.0
|
||||
SQLAlchemy-Utils>=0.33.5,<0.38.0
|
||||
|
||||
# extracting metadata
|
||||
|
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user