Merge branch 'master' of https://github.com/janeczku/calibre-web
This commit is contained in:
commit
09751d8b87
11
cps/admin.py
11
cps/admin.py
|
@ -1186,11 +1186,20 @@ def _db_configuration_update_helper():
|
||||||
if not calibre_db.setup_db(to_save['config_calibre_dir'], ub.app_DB_path):
|
if not calibre_db.setup_db(to_save['config_calibre_dir'], ub.app_DB_path):
|
||||||
return _db_configuration_result(_('DB Location is not Valid, Please Enter Correct Path'),
|
return _db_configuration_result(_('DB Location is not Valid, Please Enter Correct Path'),
|
||||||
gdrive_error)
|
gdrive_error)
|
||||||
|
# if db changed -> delete shelfs, delete download books, delete read books, kobo sync...
|
||||||
|
ub.session.query(ub.Downloads).delete()
|
||||||
|
ub.session.query(ub.ArchivedBook).delete()
|
||||||
|
ub.session.query(ub.ArchivedBook).delete()
|
||||||
|
ub.session.query(ub.ReadBook).delete()
|
||||||
|
ub.session.query(ub.BookShelf).delete()
|
||||||
|
ub.session.query(ub.Bookmark).delete()
|
||||||
|
ub.session.query(ub.KoboReadingState).delete()
|
||||||
|
ub.session.query(ub.KoboStatistics).delete()
|
||||||
|
ub.session.query(ub.KoboSyncedBooks).delete()
|
||||||
_config_string(to_save, "config_calibre_dir")
|
_config_string(to_save, "config_calibre_dir")
|
||||||
calibre_db.update_config(config)
|
calibre_db.update_config(config)
|
||||||
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")
|
||||||
# warning = {'type': "warning", 'message': _(u"DB is not Writeable")}
|
|
||||||
config.save()
|
config.save()
|
||||||
return _db_configuration_result(None, gdrive_error)
|
return _db_configuration_result(None, gdrive_error)
|
||||||
|
|
||||||
|
|
|
@ -550,11 +550,8 @@ class CalibreDB():
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def setup_db(cls, config_calibre_dir, app_db_path):
|
def setup_db(cls, config_calibre_dir, app_db_path):
|
||||||
# cls.config = config
|
|
||||||
cls.dispose()
|
cls.dispose()
|
||||||
|
|
||||||
# toDo: if db changed -> delete shelfs, delete download books, delete read boks, kobo sync??
|
|
||||||
|
|
||||||
if not config_calibre_dir:
|
if not config_calibre_dir:
|
||||||
cls.config.invalidate()
|
cls.config.invalidate()
|
||||||
return False
|
return False
|
||||||
|
|
|
@ -823,7 +823,7 @@ def get_cc_columns(filter_config_custom_read=False):
|
||||||
|
|
||||||
def get_download_link(book_id, book_format, client):
|
def get_download_link(book_id, book_format, client):
|
||||||
book_format = book_format.split(".")[0]
|
book_format = book_format.split(".")[0]
|
||||||
book = calibre_db.get_filtered_book(book_id)
|
book = calibre_db.get_filtered_book(book_id, allow_show_archived=True)
|
||||||
if book:
|
if book:
|
||||||
data1 = calibre_db.get_book_format(book.id, book_format.upper())
|
data1 = calibre_db.get_book_format(book.id, book_format.upper())
|
||||||
else:
|
else:
|
||||||
|
|
27
cps/kobo.py
27
cps/kobo.py
|
@ -355,7 +355,9 @@ def HandleMetadataRequest(book_uuid):
|
||||||
return redirect_or_proxy_request()
|
return redirect_or_proxy_request()
|
||||||
|
|
||||||
metadata = get_metadata(book)
|
metadata = get_metadata(book)
|
||||||
return jsonify([metadata])
|
response = make_response(json.dumps([metadata], ensure_ascii=False))
|
||||||
|
response.headers["Content-Type"] = "application/json; charset=utf-8"
|
||||||
|
return response
|
||||||
|
|
||||||
|
|
||||||
def get_download_url_for_book(book, book_format):
|
def get_download_url_for_book(book, book_format):
|
||||||
|
@ -413,15 +415,12 @@ def get_description(book):
|
||||||
def get_author(book):
|
def get_author(book):
|
||||||
if not book.authors:
|
if not book.authors:
|
||||||
return {"Contributors": None}
|
return {"Contributors": None}
|
||||||
if len(book.authors) > 1:
|
|
||||||
author_list = []
|
author_list = []
|
||||||
autor_roles = []
|
autor_roles = []
|
||||||
for author in book.authors:
|
for author in book.authors:
|
||||||
autor_roles.append({"Name":author.name}) #.encode('unicode-escape').decode('latin-1')
|
autor_roles.append({"Name":author.name}) #.encode('unicode-escape').decode('latin-1')
|
||||||
author_list.append(author.name)
|
author_list.append(author.name)
|
||||||
return {"ContributorRoles": autor_roles, "Contributors":author_list}
|
return {"ContributorRoles": autor_roles, "Contributors":author_list}
|
||||||
return {"ContributorRoles": [{"Name":book.authors[0].name}],
|
|
||||||
"Contributors": book.authors[0].name}
|
|
||||||
|
|
||||||
|
|
||||||
def get_publisher(book):
|
def get_publisher(book):
|
||||||
|
@ -987,6 +986,25 @@ def HandleUserRequest(dummy=None):
|
||||||
return redirect_or_proxy_request()
|
return redirect_or_proxy_request()
|
||||||
|
|
||||||
|
|
||||||
|
@csrf.exempt
|
||||||
|
@kobo.route("/v1/user/loyalty/benefits", methods=["GET"])
|
||||||
|
def handle_benefits():
|
||||||
|
if config.config_kobo_proxy:
|
||||||
|
return redirect_or_proxy_request()
|
||||||
|
else:
|
||||||
|
return make_response(jsonify({"Benefits": {}}))
|
||||||
|
|
||||||
|
|
||||||
|
@csrf.exempt
|
||||||
|
@kobo.route("/v1/analytics/gettests", methods=["GET", "POST"])
|
||||||
|
def handle_getests():
|
||||||
|
if config.config_kobo_proxy:
|
||||||
|
return redirect_or_proxy_request()
|
||||||
|
else:
|
||||||
|
testkey = request.headers.get("X-Kobo-userkey","")
|
||||||
|
return make_response(jsonify({"Result": "Success", "TestKey":testkey, "Tests": {}}))
|
||||||
|
|
||||||
|
|
||||||
@csrf.exempt
|
@csrf.exempt
|
||||||
@kobo.route("/v1/products/<dummy>/prices", methods=["GET", "POST"])
|
@kobo.route("/v1/products/<dummy>/prices", methods=["GET", "POST"])
|
||||||
@kobo.route("/v1/products/<dummy>/recommendations", methods=["GET", "POST"])
|
@kobo.route("/v1/products/<dummy>/recommendations", methods=["GET", "POST"])
|
||||||
|
@ -1002,6 +1020,7 @@ def HandleUserRequest(dummy=None):
|
||||||
@kobo.route("/v1/products/deals", methods=["GET", "POST"])
|
@kobo.route("/v1/products/deals", methods=["GET", "POST"])
|
||||||
@kobo.route("/v1/products", methods=["GET", "POST"])
|
@kobo.route("/v1/products", methods=["GET", "POST"])
|
||||||
@kobo.route("/v1/affiliate", methods=["GET", "POST"])
|
@kobo.route("/v1/affiliate", methods=["GET", "POST"])
|
||||||
|
@kobo.route("/v1/deals", methods=["GET", "POST"])
|
||||||
def HandleProductsRequest(dummy=None):
|
def HandleProductsRequest(dummy=None):
|
||||||
log.debug("Unimplemented Products Request received: %s", request.base_url)
|
log.debug("Unimplemented Products Request received: %s", request.base_url)
|
||||||
return redirect_or_proxy_request()
|
return redirect_or_proxy_request()
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
from flask_login import current_user
|
from flask_login import current_user
|
||||||
from . import ub
|
from . import ub
|
||||||
import datetime
|
import datetime
|
||||||
from sqlalchemy.sql.expression import or_
|
from sqlalchemy.sql.expression import or_, and_
|
||||||
|
|
||||||
# Add the current book id to kobo_synced_books table for current user, if entry is already present,
|
# Add the current book id to kobo_synced_books table for current user, if entry is already present,
|
||||||
# do nothing (safety precaution)
|
# do nothing (safety precaution)
|
||||||
|
@ -42,18 +42,18 @@ def remove_synced_book(book_id):
|
||||||
ub.session_commit()
|
ub.session_commit()
|
||||||
|
|
||||||
|
|
||||||
def add_archived_books(book_id):
|
def change_archived_books(book_id, state=None, message=None):
|
||||||
archived_book = (ub.session.query(ub.ArchivedBook)
|
archived_book = ub.session.query(ub.ArchivedBook).filter(and_(ub.ArchivedBook.user_id == int(current_user.id),
|
||||||
.filter(ub.ArchivedBook.book_id == book_id)
|
ub.ArchivedBook.book_id == book_id)).first()
|
||||||
.filter(ub.ArchivedBook.user_id == current_user.id)
|
|
||||||
.first())
|
|
||||||
if not archived_book:
|
if not archived_book:
|
||||||
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 = state if state else not archived_book.is_archived
|
||||||
archived_book.last_modified = datetime.datetime.utcnow()
|
archived_book.last_modified = datetime.datetime.utcnow()
|
||||||
|
|
||||||
ub.session.merge(archived_book)
|
ub.session.merge(archived_book)
|
||||||
ub.session_commit()
|
ub.session_commit(message)
|
||||||
|
return archived_book.is_archived
|
||||||
|
|
||||||
|
|
||||||
# select all books which are synced by the current user and do not belong to a synced shelf and them to archive
|
# select all books which are synced by the current user and do not belong to a synced shelf and them to archive
|
||||||
|
@ -65,7 +65,7 @@ def update_on_sync_shelfs(user_id):
|
||||||
.filter(or_(ub.Shelf.kobo_sync == 0, ub.Shelf.kobo_sync == None))
|
.filter(or_(ub.Shelf.kobo_sync == 0, ub.Shelf.kobo_sync == None))
|
||||||
.filter(ub.KoboSyncedBooks.user_id == user_id).all())
|
.filter(ub.KoboSyncedBooks.user_id == user_id).all())
|
||||||
for b in books_to_archive:
|
for b in books_to_archive:
|
||||||
add_archived_books(b.book_id)
|
change_archived_books(b.book_id, True)
|
||||||
ub.session.query(ub.KoboSyncedBooks) \
|
ub.session.query(ub.KoboSyncedBooks) \
|
||||||
.filter(ub.KoboSyncedBooks.book_id == b.book_id) \
|
.filter(ub.KoboSyncedBooks.book_id == b.book_id) \
|
||||||
.filter(ub.KoboSyncedBooks.user_id == user_id).delete()
|
.filter(ub.KoboSyncedBooks.user_id == user_id).delete()
|
||||||
|
|
|
@ -182,10 +182,9 @@ class SyncToken:
|
||||||
return b64encode_json(token)
|
return b64encode_json(token)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "{},{},{},{},{},{}".format(self.raw_kobo_store_token,
|
return "{},{},{},{},{},{}".format(self.books_last_created,
|
||||||
self.books_last_created,
|
|
||||||
self.books_last_modified,
|
self.books_last_modified,
|
||||||
self.archive_last_modified,
|
self.archive_last_modified,
|
||||||
self.reading_state_last_modified,
|
self.reading_state_last_modified,
|
||||||
self.tags_last_modified)
|
self.tags_last_modified, self.raw_kobo_store_token)
|
||||||
#self.books_last_id)
|
#self.books_last_id)
|
||||||
|
|
|
@ -284,11 +284,7 @@ $(function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function fillFileTable(path, type, folder, filt) {
|
function fillFileTable(path, type, folder, filt) {
|
||||||
if (window.location.pathname.endsWith("/basicconfig")) {
|
|
||||||
var request_path = "/../basicconfig/pathchooser/";
|
|
||||||
} else {
|
|
||||||
var request_path = "/../../ajax/pathchooser/";
|
var request_path = "/../../ajax/pathchooser/";
|
||||||
}
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
data: {
|
data: {
|
||||||
|
|
|
@ -793,7 +793,7 @@ function handleListServerResponse (data) {
|
||||||
function checkboxChange(checkbox, userId, field, field_index) {
|
function checkboxChange(checkbox, userId, field, field_index) {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
method: "post",
|
method: "post",
|
||||||
url: window.location.pathname + "/../../ajax/editlistusers/" + field,
|
url: getPath() + "/ajax/editlistusers/" + field,
|
||||||
data: {"pk": userId, "field_index": field_index, "value": checkbox.checked},
|
data: {"pk": userId, "field_index": field_index, "value": checkbox.checked},
|
||||||
error: function(data) {
|
error: function(data) {
|
||||||
handleListServerResponse([{type:"danger", message:data.responseText}])
|
handleListServerResponse([{type:"danger", message:data.responseText}])
|
||||||
|
|
20
cps/web.py
20
cps/web.py
|
@ -56,6 +56,7 @@ from .redirect import redirect_back
|
||||||
from .usermanagement import login_required_if_no_ano
|
from .usermanagement import login_required_if_no_ano
|
||||||
from .kobo_sync_status import remove_synced_book
|
from .kobo_sync_status import remove_synced_book
|
||||||
from .render_template import render_title_template
|
from .render_template import render_title_template
|
||||||
|
from .kobo_sync_status import change_archived_books
|
||||||
|
|
||||||
feature_support = {
|
feature_support = {
|
||||||
'ldap': bool(services.ldap),
|
'ldap': bool(services.ldap),
|
||||||
|
@ -190,24 +191,15 @@ def toggle_read(book_id):
|
||||||
return "Custom Column No.{} is not existing in calibre database".format(config.config_read_column), 400
|
return "Custom Column No.{} is not existing in calibre database".format(config.config_read_column), 400
|
||||||
except (OperationalError, InvalidRequestError) as e:
|
except (OperationalError, InvalidRequestError) as e:
|
||||||
calibre_db.session.rollback()
|
calibre_db.session.rollback()
|
||||||
log.error(u"Read status could not set: %e", e)
|
log.error(u"Read status could not set: {}".format(e))
|
||||||
return "Read status could not set: {}".format(e), 400
|
return "Read status could not set: {}".format(e), 400
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
@web.route("/ajax/togglearchived/<int:book_id>", methods=['POST'])
|
@web.route("/ajax/togglearchived/<int:book_id>", methods=['POST'])
|
||||||
@login_required
|
@login_required
|
||||||
def toggle_archived(book_id):
|
def toggle_archived(book_id):
|
||||||
archived_book = ub.session.query(ub.ArchivedBook).filter(and_(ub.ArchivedBook.user_id == int(current_user.id),
|
is_archived = change_archived_books(book_id, message="Book {} archivebit toggled".format(book_id))
|
||||||
ub.ArchivedBook.book_id == book_id)).first()
|
if is_archived:
|
||||||
if archived_book:
|
|
||||||
archived_book.is_archived = not archived_book.is_archived
|
|
||||||
archived_book.last_modified = datetime.utcnow()
|
|
||||||
else:
|
|
||||||
archived_book = ub.ArchivedBook(user_id=current_user.id, book_id=book_id)
|
|
||||||
archived_book.is_archived = True
|
|
||||||
ub.session.merge(archived_book)
|
|
||||||
ub.session_commit("Book {} archivebit toggled".format(book_id))
|
|
||||||
if archived_book.is_archived:
|
|
||||||
remove_synced_book(book_id)
|
remove_synced_book(book_id)
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
@ -801,7 +793,6 @@ def list_books():
|
||||||
|
|
||||||
if sort == "state":
|
if sort == "state":
|
||||||
state = json.loads(request.args.get("state", "[]"))
|
state = json.loads(request.args.get("state", "[]"))
|
||||||
# order = [db.Books.timestamp.asc()] if order == "asc" else [db.Books.timestamp.desc()] # ToDo wrong: sort ticked
|
|
||||||
elif sort == "tags":
|
elif sort == "tags":
|
||||||
order = [db.Tags.name.asc()] if order == "asc" else [db.Tags.name.desc()]
|
order = [db.Tags.name.asc()] if order == "asc" else [db.Tags.name.desc()]
|
||||||
join = db.books_tags_link,db.Books.id == db.books_tags_link.c.book, db.Tags
|
join = db.books_tags_link,db.Books.id == db.books_tags_link.c.book, db.Tags
|
||||||
|
@ -1525,9 +1516,6 @@ def register():
|
||||||
|
|
||||||
@web.route('/login', methods=['GET', 'POST'])
|
@web.route('/login', methods=['GET', 'POST'])
|
||||||
def login():
|
def login():
|
||||||
#if not config.db_configured:
|
|
||||||
# log.debug(u"Redirect to initial configuration")
|
|
||||||
# return redirect(url_for('admin.basic_configuration'))
|
|
||||||
if current_user is not None and current_user.is_authenticated:
|
if current_user is not None and current_user.is_authenticated:
|
||||||
return redirect(url_for('web.index'))
|
return redirect(url_for('web.index'))
|
||||||
if config.config_login_type == constants.LOGIN_LDAP and not services.ldap:
|
if config.config_login_type == constants.LOGIN_LDAP and not services.ldap:
|
||||||
|
|
Loading…
Reference in New Issue
Block a user