From 04b04e200f64a0789d2b6664ab8de5eb1eca9b14 Mon Sep 17 00:00:00 2001 From: Jonathan Rehm Date: Sun, 9 Jul 2017 16:27:46 -0700 Subject: [PATCH] Add ability to edit publish date MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If a date is not set, default to “0101-01-01” --- cps/db.py | 2 + cps/templates/book_edit.html | 4 + cps/web.py | 344 ++++++++++++++++++----------------- 3 files changed, 186 insertions(+), 164 deletions(-) diff --git a/cps/db.py b/cps/db.py index 713fef34..615d2d34 100755 --- a/cps/db.py +++ b/cps/db.py @@ -230,6 +230,8 @@ class Data(Base): class Books(Base): __tablename__ = 'books' + DEFAULT_PUBDATE = "0101-01-01" + id = Column(Integer, primary_key=True) title = Column(String) sort = Column(String) diff --git a/cps/templates/book_edit.html b/cps/templates/book_edit.html index 4eb5b00e..ac207e8a 100644 --- a/cps/templates/book_edit.html +++ b/cps/templates/book_edit.html @@ -52,6 +52,10 @@ +
+ + +
diff --git a/cps/web.py b/cps/web.py index 4fc78635..adb7fb87 100755 --- a/cps/web.py +++ b/cps/web.py @@ -415,6 +415,14 @@ def formatdate(val): 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') def timestamptodate(date, fmt=None): 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") return redirect(url_for("index")) - for index in range(0, len(book.languages)): - try: - book.languages[index].language_name = LC.parse(book.languages[index].lang_code).get_language_name( - get_locale()) - except Exception: - book.languages[index].language_name = _(isoLanguages.get(part3=book.languages[index].lang_code).name) - for author in book.authors: - author_names.append(author.name) + for index in range(0, len(book.languages)): + try: + book.languages[index].language_name = LC.parse(book.languages[index].lang_code).get_language_name( + get_locale()) + except Exception: + book.languages[index].language_name = _(isoLanguages.get(part3=book.languages[index].lang_code).name) + for author in book.authors: + author_names.append(author.name) # Show form if request.method != 'POST': @@ -2710,179 +2718,187 @@ def edit_book(book_id): title=_(u"edit metadata")) # Update book - edited_books_id = set() - to_save = request.form.to_dict() - if book.title != to_save["book_title"]: - book.title = to_save["book_title"] - edited_books_id.add(book.id) - input_authors = to_save["author_name"].split('&') - input_authors = map(lambda it: it.strip(), input_authors) - # we have all author names now - if input_authors == ['']: - input_authors = [_(u'unknown')] # prevent empty Author - if book.authors: - 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 + edited_books_id = set() + to_save = request.form.to_dict() + if book.title != to_save["book_title"]: + book.title = to_save["book_title"] + edited_books_id.add(book.id) + input_authors = to_save["author_name"].split('&') + input_authors = map(lambda it: it.strip(), input_authors) + # we have all author names now + if input_authors == ['']: + input_authors = [_(u'unknown')] # prevent empty Author + if book.authors: + 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 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)) + 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_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_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) + 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: - 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]) + 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 - 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 + # 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: + 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]) + + 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: - 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 + to_save[cc_string] = 1 if to_save[cc_string] == 'True' else 0 + 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: - to_save[cc_string] = 1 if to_save[cc_string] == 'True' else 0 - 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) - 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) - + del_cc = getattr(book, cc_string)[0] + getattr(book, cc_string).remove(del_cc) + db.session.delete(del_cc) 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: - # 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) - cc_class = db.cc_classes[c.id] - new_cc = db.session.query(cc_class).filter( - cc_class.value == to_save[cc_string].strip()).first() - # if no cc val is found add it - if new_cc is None: - new_cc = cc_class(value=to_save[cc_string].strip()) - db.session.add(new_cc) - new_cc = db.session.query(cc_class).filter( - cc_class.value == to_save[cc_string].strip()).first() - # add cc value to book - getattr(book, cc_string).append(new_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: + 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: # 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)) + cc_class = db.cc_classes[c.id] + new_cc = db.session.query(cc_class).filter( + cc_class.value == to_save[cc_string].strip()).first() + # if no cc val is found add it + if new_cc is None: + new_cc = cc_class(value=to_save[cc_string].strip()) + db.session.add(new_cc) + new_cc = db.session.query(cc_class).filter( + cc_class.value == to_save[cc_string].strip()).first() + # add cc value to book + getattr(book, cc_string).append(new_cc) else: - return render_title_template('book_edit.html', book=book, authors=author_names, cc=cc, - title=_(u"edit metadata")) + if cc_db_value is not None: + # 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"])