1
0
mirror of https://github.com/janeczku/calibre-web.git synced 2024-11-30 09:07:17 +02:00
This commit is contained in:
Ozzieisaacs 2020-04-20 18:56:39 +02:00
parent 24c743d23d
commit 95ca1e6a9d
2 changed files with 98 additions and 59 deletions

View File

@ -22,7 +22,7 @@
from __future__ import division, print_function, unicode_literals from __future__ import division, print_function, unicode_literals
import os import os
import datetime from datetime import datetime
import json import json
from shutil import move, copyfile from shutil import move, copyfile
from uuid import uuid4 from uuid import uuid4
@ -47,7 +47,7 @@ def modify_database_object(input_elements, db_book_object, db_object, db_session
# passing input_elements not as a list may lead to undesired results # passing input_elements not as a list may lead to undesired results
if not isinstance(input_elements, list): if not isinstance(input_elements, list):
raise TypeError(str(input_elements) + " should be passed as a list") raise TypeError(str(input_elements) + " should be passed as a list")
changed = False
input_elements = [x for x in input_elements if x != ''] input_elements = [x for x in input_elements if x != '']
# we have all input element (authors, series, tags) names now # we have all input element (authors, series, tags) names now
# 1. search for elements to remove # 1. search for elements to remove
@ -88,6 +88,7 @@ def modify_database_object(input_elements, db_book_object, db_object, db_session
if len(del_elements) > 0: if len(del_elements) > 0:
for del_element in del_elements: for del_element in del_elements:
db_book_object.remove(del_element) db_book_object.remove(del_element)
changed = True
if len(del_element.books) == 0: if len(del_element.books) == 0:
db_session.delete(del_element) db_session.delete(del_element)
# if there are elements to add, we add them now! # if there are elements to add, we add them now!
@ -114,49 +115,48 @@ def modify_database_object(input_elements, db_book_object, db_object, db_session
else: # db_type should be tag or language else: # db_type should be tag or language
new_element = db_object(add_element) new_element = db_object(add_element)
if db_element is None: if db_element is None:
changed = True
db_session.add(new_element) db_session.add(new_element)
db_book_object.append(new_element) db_book_object.append(new_element)
else: else:
if db_type == 'custom': if db_type == 'custom':
if db_element.value != add_element: if db_element.value != add_element:
new_element.value = add_element new_element.value = add_element
# new_element = db_element
elif db_type == 'languages': elif db_type == 'languages':
if db_element.lang_code != add_element: if db_element.lang_code != add_element:
db_element.lang_code = add_element db_element.lang_code = add_element
# new_element = db_element
elif db_type == 'series': elif db_type == 'series':
if db_element.name != add_element: if db_element.name != add_element:
db_element.name = add_element # = add_element # new_element = db_object(add_element, add_element) db_element.name = add_element
db_element.sort = add_element db_element.sort = add_element
# new_element = db_element
elif db_type == 'author': elif db_type == 'author':
if db_element.name != add_element: if db_element.name != add_element:
db_element.name = add_element db_element.name = add_element
db_element.sort = add_element.replace('|', ',') db_element.sort = add_element.replace('|', ',')
# new_element = db_element
elif db_type == 'publisher': elif db_type == 'publisher':
if db_element.name != add_element: if db_element.name != add_element:
db_element.name = add_element db_element.name = add_element
db_element.sort = None db_element.sort = None
# new_element = db_element
elif db_element.name != add_element: elif db_element.name != add_element:
db_element.name = add_element db_element.name = add_element
# new_element = db_element
# add element to book # add element to book
changed = True
db_book_object.append(db_element) db_book_object.append(db_element)
return changed
def modify_identifiers(input_identifiers, db_identifiers, db_session): def modify_identifiers(input_identifiers, db_identifiers, db_session):
"""Modify Identifiers to match input information. """Modify Identifiers to match input information.
input_identifiers is a list of read-to-persist Identifiers objects. input_identifiers is a list of read-to-persist Identifiers objects.
db_identifiers is a list of already persisted list of Identifiers objects.""" db_identifiers is a list of already persisted list of Identifiers objects."""
changed = False
input_dict = dict([ (identifier.type.lower(), identifier) for identifier in input_identifiers ]) input_dict = dict([ (identifier.type.lower(), identifier) for identifier in input_identifiers ])
db_dict = dict([ (identifier.type.lower(), identifier) for identifier in db_identifiers ]) db_dict = dict([ (identifier.type.lower(), identifier) for identifier in db_identifiers ])
# delete db identifiers not present in input or modify them with input val # delete db identifiers not present in input or modify them with input val
for identifier_type, identifier in db_dict.items(): for identifier_type, identifier in db_dict.items():
if identifier_type not in input_dict.keys(): if identifier_type not in input_dict.keys():
db_session.delete(identifier) db_session.delete(identifier)
changed = True
else: else:
input_identifier = input_dict[identifier_type] input_identifier = input_dict[identifier_type]
identifier.type = input_identifier.type identifier.type = input_identifier.type
@ -165,6 +165,8 @@ def modify_identifiers(input_identifiers, db_identifiers, db_session):
for identifier_type, identifier in input_dict.items(): for identifier_type, identifier in input_dict.items():
if identifier_type not in db_dict.keys(): if identifier_type not in db_dict.keys():
db_session.add(identifier) db_session.add(identifier)
changed = True
return changed
@editbook.route("/delete/<int:book_id>/", defaults={'book_format': ""}) @editbook.route("/delete/<int:book_id>/", defaults={'book_format': ""})
@ -266,7 +268,53 @@ def render_edit_book(book_id):
source_formats=valid_source_formats) source_formats=valid_source_formats)
def edit_book_ratings(to_save, book):
changed = False
if to_save["rating"].strip():
old_rating = False
if len(book.ratings) > 0:
old_rating = book.ratings[0].rating
ratingx2 = int(float(to_save["rating"]) * 2)
if ratingx2 != old_rating:
changed = True
is_rating = db.session.query(db.Ratings).filter(db.Ratings.rating == ratingx2).first()
if is_rating:
book.ratings.append(is_rating)
else:
new_rating = db.Ratings(rating=ratingx2)
book.ratings.append(new_rating)
if old_rating:
book.ratings.remove(book.ratings[0])
else:
if len(book.ratings) > 0:
book.ratings.remove(book.ratings[0])
changed = True
return changed
def edit_book_languages(to_save, book):
input_languages = to_save["languages"].split(',')
unknown_languages = []
input_l = isoLanguages.get_language_codes(get_locale(), input_languages, unknown_languages)
for l in unknown_languages:
log.error('%s is not a valid language', l)
flash(_(u"%(langname)s is not a valid language", langname=l), category="error")
return modify_database_object(list(input_l), book.languages, db.Languages, db.session, 'languages')
def edit_book_publisher(to_save, book):
changed = False
if to_save["publisher"]:
publisher = to_save["publisher"].rstrip().strip()
if len(book.publishers) == 0 or (len(book.publishers) > 0 and publisher != book.publishers[0].name):
changed |= modify_database_object([publisher], book.publishers, db.Publishers, db.session, 'publisher')
elif len(book.publishers):
changed |= modify_database_object([], book.publishers, db.Publishers, db.session, 'publisher')
return changed
def edit_cc_data(book_id, book, to_save): def edit_cc_data(book_id, book, to_save):
changed = False
cc = db.session.query(db.Custom_Columns).filter(db.Custom_Columns.datatype.notin_(db.cc_exceptions)).all() cc = db.session.query(db.Custom_Columns).filter(db.Custom_Columns.datatype.notin_(db.cc_exceptions)).all()
for c in cc: for c in cc:
cc_string = "custom_column_" + str(c.id) cc_string = "custom_column_" + str(c.id)
@ -286,14 +334,17 @@ def edit_cc_data(book_id, book, to_save):
if cc_db_value is not None: if cc_db_value is not None:
if to_save[cc_string] is not None: if to_save[cc_string] is not None:
setattr(getattr(book, cc_string)[0], 'value', to_save[cc_string]) setattr(getattr(book, cc_string)[0], 'value', to_save[cc_string])
changed = True
else: else:
del_cc = getattr(book, cc_string)[0] del_cc = getattr(book, cc_string)[0]
getattr(book, cc_string).remove(del_cc) getattr(book, cc_string).remove(del_cc)
db.session.delete(del_cc) db.session.delete(del_cc)
changed = True
else: else:
cc_class = db.cc_classes[c.id] cc_class = db.cc_classes[c.id]
new_cc = cc_class(value=to_save[cc_string], book=book_id) new_cc = cc_class(value=to_save[cc_string], book=book_id)
db.session.add(new_cc) db.session.add(new_cc)
changed = True
else: else:
if c.datatype == 'rating': if c.datatype == 'rating':
@ -305,6 +356,7 @@ def edit_cc_data(book_id, book, to_save):
getattr(book, cc_string).remove(del_cc) getattr(book, cc_string).remove(del_cc)
if len(del_cc.books) == 0: if len(del_cc.books) == 0:
db.session.delete(del_cc) db.session.delete(del_cc)
changed = True
cc_class = db.cc_classes[c.id] cc_class = db.cc_classes[c.id]
new_cc = db.session.query(cc_class).filter( new_cc = db.session.query(cc_class).filter(
cc_class.value == to_save[cc_string].strip()).first() cc_class.value == to_save[cc_string].strip()).first()
@ -312,6 +364,7 @@ def edit_cc_data(book_id, book, to_save):
if new_cc is None: if new_cc is None:
new_cc = cc_class(value=to_save[cc_string].strip()) new_cc = cc_class(value=to_save[cc_string].strip())
db.session.add(new_cc) db.session.add(new_cc)
changed = True
db.session.flush() db.session.flush()
new_cc = db.session.query(cc_class).filter( new_cc = db.session.query(cc_class).filter(
cc_class.value == to_save[cc_string].strip()).first() cc_class.value == to_save[cc_string].strip()).first()
@ -324,12 +377,13 @@ def edit_cc_data(book_id, book, to_save):
getattr(book, cc_string).remove(del_cc) getattr(book, cc_string).remove(del_cc)
if not del_cc.books or len(del_cc.books) == 0: if not del_cc.books or len(del_cc.books) == 0:
db.session.delete(del_cc) db.session.delete(del_cc)
changed = True
else: else:
input_tags = to_save[cc_string].split(',') input_tags = to_save[cc_string].split(',')
input_tags = list(map(lambda it: it.strip(), input_tags)) input_tags = list(map(lambda it: it.strip(), input_tags))
modify_database_object(input_tags, getattr(book, cc_string), db.cc_classes[c.id], db.session, changed |= modify_database_object(input_tags, getattr(book, cc_string), db.cc_classes[c.id], db.session,
'custom') 'custom')
return cc return changed
def upload_single_file(request, book, book_id): def upload_single_file(request, book, book_id):
# Check and handle Uploaded file # Check and handle Uploaded file
@ -404,6 +458,7 @@ def upload_cover(request, book):
@login_required_if_no_ano @login_required_if_no_ano
@edit_required @edit_required
def edit_book(book_id): def edit_book(book_id):
modif_date = False
# Show form # Show form
if request.method != 'POST': if request.method != 'POST':
return render_edit_book(book_id) return render_edit_book(book_id)
@ -421,6 +476,7 @@ def edit_book(book_id):
meta = upload_single_file(request, book, book_id) meta = upload_single_file(request, book, book_id)
if upload_cover(request, book) is True: if upload_cover(request, book) is True:
book.has_cover = 1 book.has_cover = 1
modif_date = True
try: try:
to_save = request.form.to_dict() to_save = request.form.to_dict()
merge_metadata(to_save, meta) merge_metadata(to_save, meta)
@ -432,6 +488,7 @@ def edit_book(book_id):
to_save["book_title"] = _(u'Unknown') to_save["book_title"] = _(u'Unknown')
book.title = to_save["book_title"].rstrip().strip() book.title = to_save["book_title"].rstrip().strip()
edited_books_id = book.id edited_books_id = book.id
modif_date = True
# handle author(s) # handle author(s)
input_authors = to_save["author_name"].split('&') input_authors = to_save["author_name"].split('&')
@ -440,7 +497,7 @@ def edit_book(book_id):
if input_authors == ['']: if input_authors == ['']:
input_authors = [_(u'Unknown')] # prevent empty Author input_authors = [_(u'Unknown')] # prevent empty Author
modify_database_object(input_authors, book.authors, db.Authors, db.session, 'author') modif_date |= modify_database_object(input_authors, book.authors, db.Authors, db.session, 'author')
# Search for each author if author is in database, if not, authorname and sorted authorname is generated new # Search for each author if author is in database, if not, authorname and sorted authorname is generated new
# everything then is assembled for sorted author field in database # everything then is assembled for sorted author field in database
@ -456,7 +513,7 @@ def edit_book(book_id):
if book.author_sort != sort_authors: if book.author_sort != sort_authors:
edited_books_id = book.id edited_books_id = book.id
book.author_sort = sort_authors book.author_sort = sort_authors
modif_date = True
if config.config_use_google_drive: if config.config_use_google_drive:
gdriveutils.updateGdriveCalibreFromLocal() gdriveutils.updateGdriveCalibreFromLocal()
@ -469,79 +526,60 @@ def edit_book(book_id):
if to_save["cover_url"]: if to_save["cover_url"]:
if helper.save_cover_from_url(to_save["cover_url"], book.path) is True: if helper.save_cover_from_url(to_save["cover_url"], book.path) is True:
book.has_cover = 1 book.has_cover = 1
modif_date = True
else: else:
flash(_(u"Cover is not a jpg file, can't save"), category="error") flash(_(u"Cover is not a jpg file, can't save"), category="error")
if book.series_index != to_save["series_index"]: if book.series_index != to_save["series_index"]:
book.series_index = to_save["series_index"] book.series_index = to_save["series_index"]
modif_date = True
# Handle book comments/description # Handle book comments/description
if len(book.comments): if len(book.comments):
book.comments[0].text = to_save["description"] if book.comments[0].text != to_save["description"]:
book.comments[0].text = to_save["description"]
modif_date = True
else: else:
book.comments.append(db.Comments(text=to_save["description"], book=book.id)) if to_save["description"]:
book.comments.append(db.Comments(text=to_save["description"], book=book.id))
modif_date = True
# Handle identifiers # Handle identifiers
input_identifiers = identifier_list(to_save, book) input_identifiers = identifier_list(to_save, book)
modify_identifiers(input_identifiers, book.identifiers, db.session) modif_date |= modify_identifiers(input_identifiers, book.identifiers, db.session)
# Handle book tags # Handle book tags
input_tags = to_save["tags"].split(',') input_tags = to_save["tags"].split(',')
input_tags = list(map(lambda it: it.strip(), input_tags)) input_tags = list(map(lambda it: it.strip(), input_tags))
modify_database_object(input_tags, book.tags, db.Tags, db.session, 'tags') modif_date |= modify_database_object(input_tags, book.tags, db.Tags, db.session, 'tags')
# Handle book series # Handle book series
input_series = [to_save["series"].strip()] input_series = [to_save["series"].strip()]
input_series = [x for x in input_series if x != ''] input_series = [x for x in input_series if x != '']
modify_database_object(input_series, book.series, db.Series, db.session, 'series') modif_date |= modify_database_object(input_series, book.series, db.Series, db.session, 'series')
if to_save["pubdate"]: if to_save["pubdate"]:
try: try:
book.pubdate = datetime.datetime.strptime(to_save["pubdate"], "%Y-%m-%d") book.pubdate = datetime.strptime(to_save["pubdate"], "%Y-%m-%d")
except ValueError: except ValueError:
book.pubdate = db.Books.DEFAULT_PUBDATE book.pubdate = db.Books.DEFAULT_PUBDATE
else: else:
book.pubdate = db.Books.DEFAULT_PUBDATE book.pubdate = db.Books.DEFAULT_PUBDATE
if to_save["publisher"]: # handle book publisher
publisher = to_save["publisher"].rstrip().strip() modif_date |= edit_book_publisher(to_save, book)
if len(book.publishers) == 0 or (len(book.publishers) > 0 and publisher != book.publishers[0].name):
modify_database_object([publisher], book.publishers, db.Publishers, db.session, 'publisher')
elif len(book.publishers):
modify_database_object([], book.publishers, db.Publishers, db.session, 'publisher')
# handle book languages # handle book languages
input_languages = to_save["languages"].split(',') modif_date |= edit_book_languages(to_save, book)
unknown_languages = []
input_l = isoLanguages.get_language_codes(get_locale(), input_languages, unknown_languages)
for l in unknown_languages:
log.error('%s is not a valid language', l)
flash(_(u"%(langname)s is not a valid language", langname=l), category="error")
modify_database_object(list(input_l), book.languages, db.Languages, db.session, 'languages')
# handle book ratings # handle book ratings
if to_save["rating"].strip(): modif_date |= edit_book_ratings(to_save, book)
old_rating = False
if len(book.ratings) > 0:
old_rating = book.ratings[0].rating
ratingx2 = int(float(to_save["rating"]) * 2)
if ratingx2 != old_rating:
is_rating = db.session.query(db.Ratings).filter(db.Ratings.rating == ratingx2).first()
if is_rating:
book.ratings.append(is_rating)
else:
new_rating = db.Ratings(rating=ratingx2)
book.ratings.append(new_rating)
if old_rating:
book.ratings.remove(book.ratings[0])
else:
if len(book.ratings) > 0:
book.ratings.remove(book.ratings[0])
# handle cc data # handle cc data
edit_cc_data(book_id, book, to_save) modif_date |= edit_cc_data(book_id, book, to_save)
if modif_date:
book.last_modified = datetime.utcnow()
db.session.commit() db.session.commit()
if config.config_use_google_drive: if config.config_use_google_drive:
gdriveutils.updateGdriveCalibreFromLocal() gdriveutils.updateGdriveCalibreFromLocal()
@ -703,8 +741,9 @@ def upload():
# combine path and normalize path from windows systems # combine path and normalize path from windows systems
path = os.path.join(author_dir, title_dir).replace('\\', '/') path = os.path.join(author_dir, title_dir).replace('\\', '/')
db_book = db.Books(title, "", db_author.sort, datetime.datetime.now(), datetime.datetime(101, 1, 1), # Calibre adds books with utc as timezone
series_index, datetime.datetime.now(), path, has_cover, db_author, [], db_language) db_book = db.Books(title, "", db_author.sort, datetime.utcnow(), datetime(101, 1, 1),
series_index, datetime.utcnow(), path, has_cover, db_author, [], db_language)
db_book.authors.append(db_author) db_book.authors.append(db_author)
if db_series: if db_series:
db_book.series.append(db_series) db_book.series.append(db_series)

View File

@ -23,7 +23,7 @@
from __future__ import division, print_function, unicode_literals from __future__ import division, print_function, unicode_literals
import os import os
import base64 import base64
import datetime from datetime import datetime
import json import json
import mimetypes import mimetypes
import traceback import traceback
@ -967,14 +967,14 @@ def advanced_search():
if pub_start: if pub_start:
try: try:
searchterm.extend([_(u"Published after ") + searchterm.extend([_(u"Published after ") +
format_date(datetime.datetime.strptime(pub_start, "%Y-%m-%d"), format_date(datetime.strptime(pub_start, "%Y-%m-%d"),
format='medium', locale=get_locale())]) format='medium', locale=get_locale())])
except ValueError: except ValueError:
pub_start = u"" pub_start = u""
if pub_end: if pub_end:
try: try:
searchterm.extend([_(u"Published before ") + searchterm.extend([_(u"Published before ") +
format_date(datetime.datetime.strptime(pub_end, "%Y-%m-%d"), format_date(datetime.strptime(pub_end, "%Y-%m-%d"),
format='medium', locale=get_locale())]) format='medium', locale=get_locale())])
except ValueError: except ValueError:
pub_start = u"" pub_start = u""
@ -1358,7 +1358,7 @@ def verify_token(token):
return redirect(url_for('web.index')) return redirect(url_for('web.index'))
# Token expired # Token expired
if datetime.datetime.now() > auth_token.expiration: if datetime.now() > auth_token.expiration:
ub.session.delete(auth_token) ub.session.delete(auth_token)
ub.session.commit() ub.session.commit()
@ -1390,7 +1390,7 @@ def token_verified():
data['message'] = _(u"Token not found") data['message'] = _(u"Token not found")
# Token expired # Token expired
elif datetime.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()