1
0
mirror of https://github.com/janeczku/calibre-web synced 2024-11-24 18:47:23 +00:00

Add ability to edit publish date

If a date is not set, default to “0101-01-01”
This commit is contained in:
Jonathan Rehm 2017-07-09 16:27:46 -07:00
parent cf7196ae5e
commit 04b04e200f
3 changed files with 190 additions and 168 deletions

View File

@ -230,6 +230,8 @@ class Data(Base):
class Books(Base): class Books(Base):
__tablename__ = 'books' __tablename__ = 'books'
DEFAULT_PUBDATE = "0101-01-01"
id = Column(Integer, primary_key=True) id = Column(Integer, primary_key=True)
title = Column(String) title = Column(String)
sort = Column(String) sort = Column(String)

View File

@ -52,6 +52,10 @@
<input type="text" class="form-control" name="cover_url" id="cover_url" value=""> <input type="text" class="form-control" name="cover_url" id="cover_url" value="">
</div> </div>
<div class="form-group">
<label for="pubdate">{{_('Published')}}</label>
<input type="date" class="form-control" name="pubdate" id="pubdate" value="{% if book.pubdate %}{{book.pubdate|formatdateinput}}{% endif %}">
</div>
<div class="form-group"> <div class="form-group">
<label for="languages">{{_('Language')}}</label> <label for="languages">{{_('Language')}}</label>
<input type="text" class="form-control typeahead" name="languages" id="languages" value="{% for language in book.languages %}{{language.language_name.strip()}}, {% endfor %}"> <input type="text" class="form-control typeahead" name="languages" id="languages" value="{% for language in book.languages %}{{language.language_name.strip()}}, {% endfor %}">

View File

@ -415,6 +415,14 @@ def formatdate(val):
return format_date(formatdate, format='medium', locale=get_locale()) return format_date(formatdate, format='medium', locale=get_locale())
@app.template_filter('formatdateinput')
def format_date_input(val):
conformed_timestamp = re.sub(r"[:]|([-](?!((\d{2}[:]\d{2})|(\d{4}))$))", '', val)
date_obj = datetime.datetime.strptime(conformed_timestamp[:15], "%Y%m%d %H%M%S")
input_date = date_obj.isoformat().split('T', 1)[0] # Hack to support dates <1900
return '' if input_date == "0101-01-01" else input_date
@app.template_filter('strftime') @app.template_filter('strftime')
def timestamptodate(date, fmt=None): def timestamptodate(date, fmt=None):
date = datetime.datetime.fromtimestamp( date = datetime.datetime.fromtimestamp(
@ -2695,14 +2703,14 @@ def edit_book(book_id):
flash(_(u"Error opening eBook. File does not exist or file is not accessible"), category="error") flash(_(u"Error opening eBook. File does not exist or file is not accessible"), category="error")
return redirect(url_for("index")) return redirect(url_for("index"))
for index in range(0, len(book.languages)): for index in range(0, len(book.languages)):
try: try:
book.languages[index].language_name = LC.parse(book.languages[index].lang_code).get_language_name( book.languages[index].language_name = LC.parse(book.languages[index].lang_code).get_language_name(
get_locale()) get_locale())
except Exception: except Exception:
book.languages[index].language_name = _(isoLanguages.get(part3=book.languages[index].lang_code).name) book.languages[index].language_name = _(isoLanguages.get(part3=book.languages[index].lang_code).name)
for author in book.authors: for author in book.authors:
author_names.append(author.name) author_names.append(author.name)
# Show form # Show form
if request.method != 'POST': if request.method != 'POST':
@ -2710,179 +2718,187 @@ def edit_book(book_id):
title=_(u"edit metadata")) title=_(u"edit metadata"))
# Update book # Update book
edited_books_id = set() edited_books_id = set()
to_save = request.form.to_dict() to_save = request.form.to_dict()
if book.title != to_save["book_title"]: if book.title != to_save["book_title"]:
book.title = to_save["book_title"] book.title = to_save["book_title"]
edited_books_id.add(book.id) edited_books_id.add(book.id)
input_authors = to_save["author_name"].split('&') input_authors = to_save["author_name"].split('&')
input_authors = map(lambda it: it.strip(), input_authors) input_authors = map(lambda it: it.strip(), input_authors)
# we have all author names now # we have all author names now
if input_authors == ['']: if input_authors == ['']:
input_authors = [_(u'unknown')] # prevent empty Author input_authors = [_(u'unknown')] # prevent empty Author
if book.authors: if book.authors:
author0_before_edit = book.authors[0].name author0_before_edit = book.authors[0].name
else:
author0_before_edit = db.Authors(_(u'unknown'),'',0)
modify_database_object(input_authors, book.authors, db.Authors, db.session, 'author')
if book.authors:
if author0_before_edit != book.authors[0].name:
edited_books_id.add(book.id)
book.author_sort = helper.get_sorted_author(input_authors[0])
if to_save["cover_url"] and os.path.splitext(to_save["cover_url"])[1].lower() == ".jpg":
img = requests.get(to_save["cover_url"])
if config.config_use_google_drive:
tmpDir = tempfile.gettempdir()
f = open(os.path.join(tmpDir, "uploaded_cover.jpg"), "wb")
f.write(img.content)
f.close()
gdriveutils.uploadFileToEbooksFolder(Gdrive.Instance().drive, os.path.join(book.path, 'cover.jpg'), os.path.join(tmpDir, f.name))
else:
f = open(os.path.join(config.config_calibre_dir, book.path, "cover.jpg"), "wb")
f.write(img.content)
f.close()
book.has_cover = 1
if book.series_index != to_save["series_index"]:
book.series_index = to_save["series_index"]
if len(book.comments):
book.comments[0].text = to_save["description"]
else:
book.comments.append(db.Comments(text=to_save["description"], book=book.id))
input_tags = to_save["tags"].split(',')
input_tags = map(lambda it: it.strip(), input_tags)
modify_database_object(input_tags, book.tags, db.Tags, db.session, 'tags')
input_series = [to_save["series"].strip()]
input_series = [x for x in input_series if x != '']
modify_database_object(input_series, book.series, db.Series, db.session, 'series')
input_languages = to_save["languages"].split(',')
input_languages = map(lambda it: it.strip().lower(), input_languages)
if to_save["pubdate"]:
try:
book.pubdate = datetime.datetime.strptime(to_save["pubdate"], "%Y-%m-%d")
except ValueError:
book.pubdate = db.Books.DEFAULT_PUBDATE
else:
book.pubdate = db.Books.DEFAULT_PUBDATE
# retranslate displayed text to language codes
languages = db.session.query(db.Languages).all()
input_l = []
for lang in languages:
try:
lang.name = LC.parse(lang.lang_code).get_language_name(get_locale()).lower()
except Exception:
lang.name = _(isoLanguages.get(part3=lang.lang_code).name).lower()
for inp_lang in input_languages:
if inp_lang == lang.name:
input_l.append(lang.lang_code)
modify_database_object(input_l, book.languages, db.Languages, db.session, 'languages')
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:
is_rating = db.session.query(db.Ratings).filter(db.Ratings.rating == ratingx2).first()
if is_rating:
book.ratings.append(is_rating)
else: else:
author0_before_edit = db.Authors(_(u'unknown'),'',0) new_rating = db.Ratings(rating=ratingx2)
modify_database_object(input_authors, book.authors, db.Authors, db.session, 'author') book.ratings.append(new_rating)
if book.authors: if old_rating:
if author0_before_edit != book.authors[0].name: book.ratings.remove(book.ratings[0])
edited_books_id.add(book.id) else:
book.author_sort = helper.get_sorted_author(input_authors[0]) if len(book.ratings) > 0:
book.ratings.remove(book.ratings[0])
if to_save["cover_url"] and os.path.splitext(to_save["cover_url"])[1].lower() == ".jpg": for c in cc:
img = requests.get(to_save["cover_url"]) cc_string = "custom_column_" + str(c.id)
if config.config_use_google_drive: if not c.is_multiple:
tmpDir = tempfile.gettempdir() if len(getattr(book, cc_string)) > 0:
f = open(os.path.join(tmpDir, "uploaded_cover.jpg"), "wb") cc_db_value = getattr(book, cc_string)[0].value
f.write(img.content)
f.close()
gdriveutils.uploadFileToEbooksFolder(Gdrive.Instance().drive, os.path.join(book.path, 'cover.jpg'), os.path.join(tmpDir, f.name))
else:
f = open(os.path.join(config.config_calibre_dir, book.path, "cover.jpg"), "wb")
f.write(img.content)
f.close()
book.has_cover = 1
if book.series_index != to_save["series_index"]:
book.series_index = to_save["series_index"]
if len(book.comments):
book.comments[0].text = to_save["description"]
else: else:
book.comments.append(db.Comments(text=to_save["description"], book=book.id)) cc_db_value = None
if to_save[cc_string].strip():
input_tags = to_save["tags"].split(',') if c.datatype == 'bool':
input_tags = map(lambda it: it.strip(), input_tags) if to_save[cc_string] == 'None':
modify_database_object(input_tags, book.tags, db.Tags, db.session, 'tags') to_save[cc_string] = None
input_series = [to_save["series"].strip()]
input_series = [x for x in input_series if x != '']
modify_database_object(input_series, book.series, db.Series, db.session, 'series')
input_languages = to_save["languages"].split(',')
input_languages = map(lambda it: it.strip().lower(), input_languages)
# retranslate displayed text to language codes
languages = db.session.query(db.Languages).all()
input_l = []
for lang in languages:
try:
lang.name = LC.parse(lang.lang_code).get_language_name(get_locale()).lower()
except Exception:
lang.name = _(isoLanguages.get(part3=lang.lang_code).name).lower()
for inp_lang in input_languages:
if inp_lang == lang.name:
input_l.append(lang.lang_code)
modify_database_object(input_l, book.languages, db.Languages, db.session, 'languages')
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:
is_rating = db.session.query(db.Ratings).filter(db.Ratings.rating == ratingx2).first()
if is_rating:
book.ratings.append(is_rating)
else: else:
new_rating = db.Ratings(rating=ratingx2) to_save[cc_string] = 1 if to_save[cc_string] == 'True' else 0
book.ratings.append(new_rating) if to_save[cc_string] != cc_db_value:
if old_rating: if cc_db_value is not None:
book.ratings.remove(book.ratings[0]) if to_save[cc_string] is not None:
else: setattr(getattr(book, cc_string)[0], 'value', to_save[cc_string])
if len(book.ratings) > 0:
book.ratings.remove(book.ratings[0])
for c in cc:
cc_string = "custom_column_" + str(c.id)
if not c.is_multiple:
if len(getattr(book, cc_string)) > 0:
cc_db_value = getattr(book, cc_string)[0].value
else:
cc_db_value = None
if to_save[cc_string].strip():
if c.datatype == 'bool':
if to_save[cc_string] == 'None':
to_save[cc_string] = None
else: else:
to_save[cc_string] = 1 if to_save[cc_string] == 'True' else 0 del_cc = getattr(book, cc_string)[0]
if to_save[cc_string] != cc_db_value: getattr(book, cc_string).remove(del_cc)
if cc_db_value is not None: db.session.delete(del_cc)
if to_save[cc_string] is not None:
setattr(getattr(book, cc_string)[0], 'value', to_save[cc_string])
else:
del_cc = getattr(book, cc_string)[0]
getattr(book, cc_string).remove(del_cc)
db.session.delete(del_cc)
else:
cc_class = db.cc_classes[c.id]
new_cc = cc_class(value=to_save[cc_string], book=book_id)
db.session.add(new_cc)
elif c.datatype == 'int':
if to_save[cc_string] == 'None':
to_save[cc_string] = None
if to_save[cc_string] != cc_db_value:
if cc_db_value is not None:
if to_save[cc_string] is not None:
setattr(getattr(book, cc_string)[0], 'value', to_save[cc_string])
else:
del_cc = getattr(book, cc_string)[0]
getattr(book, cc_string).remove(del_cc)
db.session.delete(del_cc)
else:
cc_class = db.cc_classes[c.id]
new_cc = cc_class(value=to_save[cc_string], book=book_id)
db.session.add(new_cc)
else: else:
if c.datatype == 'rating': cc_class = db.cc_classes[c.id]
to_save[cc_string] = str(int(float(to_save[cc_string]) * 2)) new_cc = cc_class(value=to_save[cc_string], book=book_id)
if to_save[cc_string].strip() != cc_db_value: db.session.add(new_cc)
if cc_db_value is not None: elif c.datatype == 'int':
# remove old cc_val if to_save[cc_string] == 'None':
del_cc = getattr(book, cc_string)[0] to_save[cc_string] = None
getattr(book, cc_string).remove(del_cc) if to_save[cc_string] != cc_db_value:
if len(del_cc.books) == 0: if cc_db_value is not None:
db.session.delete(del_cc) if to_save[cc_string] is not None:
cc_class = db.cc_classes[c.id] setattr(getattr(book, cc_string)[0], 'value', to_save[cc_string])
new_cc = db.session.query(cc_class).filter( else:
cc_class.value == to_save[cc_string].strip()).first() del_cc = getattr(book, cc_string)[0]
# if no cc val is found add it getattr(book, cc_string).remove(del_cc)
if new_cc is None: db.session.delete(del_cc)
new_cc = cc_class(value=to_save[cc_string].strip()) else:
db.session.add(new_cc) cc_class = db.cc_classes[c.id]
new_cc = db.session.query(cc_class).filter( new_cc = cc_class(value=to_save[cc_string], book=book_id)
cc_class.value == to_save[cc_string].strip()).first() db.session.add(new_cc)
# add cc value to book
getattr(book, cc_string).append(new_cc) else:
else: if c.datatype == 'rating':
to_save[cc_string] = str(int(float(to_save[cc_string]) * 2))
if to_save[cc_string].strip() != cc_db_value:
if cc_db_value is not None: if cc_db_value is not None:
# remove old cc_val # remove old cc_val
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)
if len(del_cc.books) == 0: if len(del_cc.books) == 0:
db.session.delete(del_cc) db.session.delete(del_cc)
else: cc_class = db.cc_classes[c.id]
input_tags = to_save[cc_string].split(',') new_cc = db.session.query(cc_class).filter(
input_tags = map(lambda it: it.strip(), input_tags) cc_class.value == to_save[cc_string].strip()).first()
modify_database_object(input_tags, getattr(book, cc_string),db.cc_classes[c.id], db.session, 'custom') # if no cc val is found add it
db.session.commit() if new_cc is None:
author_names = [] new_cc = cc_class(value=to_save[cc_string].strip())
for author in book.authors: db.session.add(new_cc)
author_names.append(author.name) new_cc = db.session.query(cc_class).filter(
for b in edited_books_id: cc_class.value == to_save[cc_string].strip()).first()
if config.config_use_google_drive: # add cc value to book
helper.update_dir_structure_gdrive(b) getattr(book, cc_string).append(new_cc)
else:
helper.update_dir_stucture(b, config.config_calibre_dir)
if config.config_use_google_drive:
updateGdriveCalibreFromLocal()
if "detail_view" in to_save:
return redirect(url_for('show_book', book_id=book.id))
else: else:
return render_title_template('book_edit.html', book=book, authors=author_names, cc=cc, if cc_db_value is not None:
title=_(u"edit metadata")) # remove old cc_val
del_cc = getattr(book, cc_string)[0]
getattr(book, cc_string).remove(del_cc)
if len(del_cc.books) == 0:
db.session.delete(del_cc)
else:
input_tags = to_save[cc_string].split(',')
input_tags = map(lambda it: it.strip(), input_tags)
modify_database_object(input_tags, getattr(book, cc_string),db.cc_classes[c.id], db.session, 'custom')
db.session.commit()
author_names = []
for author in book.authors:
author_names.append(author.name)
for b in edited_books_id:
if config.config_use_google_drive:
helper.update_dir_structure_gdrive(b)
else:
helper.update_dir_stucture(b, config.config_calibre_dir)
if config.config_use_google_drive:
updateGdriveCalibreFromLocal()
if "detail_view" in to_save:
return redirect(url_for('show_book', book_id=book.id))
else:
return render_title_template('book_edit.html', book=book, authors=author_names, cc=cc,
title=_(u"edit metadata"))
@app.route("/upload", methods=["GET", "POST"]) @app.route("/upload", methods=["GET", "POST"])