diff --git a/cps/db.py b/cps/db.py index d8709335..dc985167 100644 --- a/cps/db.py +++ b/cps/db.py @@ -39,9 +39,8 @@ except ImportError: from sqlalchemy.pool import StaticPool from sqlalchemy.sql.expression import and_, true, false, text, func, or_ from sqlalchemy.ext.associationproxy import association_proxy +from sqlalchemy.orm import joinedload from flask_login import current_user -from babel import Locale as LC -from babel.core import UnknownLocaleError from flask_babel import gettext as _ from flask import flash @@ -338,15 +337,15 @@ class Books(Base): isbn = Column(String(collation='NOCASE'), default="") flags = Column(Integer, nullable=False, default=1) - authors = relationship('Authors', secondary=books_authors_link, backref='books') - tags = relationship('Tags', secondary=books_tags_link, backref='books', order_by="Tags.name") - comments = relationship('Comments', backref='books') - data = relationship('Data', backref='books') - series = relationship('Series', secondary=books_series_link, backref='books') - ratings = relationship('Ratings', secondary=books_ratings_link, backref='books') - languages = relationship('Languages', secondary=books_languages_link, backref='books') - publishers = relationship('Publishers', secondary=books_publishers_link, backref='books') - identifiers = relationship('Identifiers', backref='books') + authors = relationship(Authors, secondary=books_authors_link, backref='books') + tags = relationship(Tags, secondary=books_tags_link, backref='books', order_by="Tags.name") + comments = relationship(Comments, backref='books') + data = relationship(Data, backref='books') + series = relationship(Series, secondary=books_series_link, backref='books') + ratings = relationship(Ratings, secondary=books_ratings_link, backref='books') + languages = relationship(Languages, secondary=books_languages_link, backref='books') + publishers = relationship(Publishers, secondary=books_publishers_link, backref='books') + identifiers = relationship(Identifiers, backref='books') def __init__(self, title, sort, author_sort, timestamp, pubdate, series_index, last_modified, path, has_cover, authors, tags, languages=None): @@ -602,6 +601,33 @@ class CalibreDB(): return self.session.query(Books).filter(Books.id == book_id). \ filter(self.common_filters(allow_show_archived)).first() + def get_book_read_archived(self, book_id, read_column, allow_show_archived=False): + # Add missing relationships for inter database joins + #setattr(Books, "is_archived", + # relationship(ub.ArchivedBook, + # uselist=False, + # foreign_keys=ub.ArchivedBook.book_id, + # primaryjoin=and_(Books.id == ub.ArchivedBook.book_id, + # int(current_user.id) == ub.ArchivedBook.user_id))) + if not read_column: + bd = (self.session.query(Books, ub.ReadBook.read_status, ub.ArchivedBook.is_archived).select_from(Books) + .join(ub.ReadBook, and_(ub.ReadBook.user_id == int(current_user.id), ub.ReadBook.book_id == book_id), + isouter=True)) + else: + try: + read_column = cc_classes[read_column] + bd = (self.session.query(Books, read_column.value, ub.ArchivedBook.is_archived).select_from(Books) + .join(read_column, read_column.book == book_id, + isouter=True)) + except (KeyError, AttributeError): + log.error("Custom Column No.%d is not existing in calibre database", read_column) + # Skip linking read column and return None instead of read status + bd = self.session.query(Books, None, ub.ArchivedBook.is_archived) + return (bd.filter(Books.id == book_id) + .join(ub.ArchivedBook, and_(Books.id == ub.ArchivedBook.book_id, + int(current_user.id) == ub.ArchivedBook.user_id), isouter=True) + .filter(self.common_filters(allow_show_archived)).first()) + def get_book_by_uuid(self, book_uuid): return self.session.query(Books).filter(Books.uuid == book_uuid).first() @@ -709,8 +735,6 @@ class CalibreDB(): entries = query.order_by(*order).offset(off).limit(pagesize).all() except Exception as ex: log.debug_or_exception(ex) - #for book in entries: - # book = self.order_authors(book) return entries, randm, pagination # Orders all Authors in the list according to authors sort @@ -730,7 +754,7 @@ class CalibreDB(): authors_ordered.append(r) if not error: entry.authors = authors_ordered - return entry + return authors_ordered def get_typeahead(self, database, query, replace=('', ''), tag_filter=true()): query = query or '' diff --git a/cps/editbooks.py b/cps/editbooks.py index d3e1f01e..14e0e1a1 100644 --- a/cps/editbooks.py +++ b/cps/editbooks.py @@ -376,7 +376,7 @@ def render_edit_book(book_id): for lang in book.languages: lang.language_name = isoLanguages.get_language_name(get_locale(), lang.lang_code) - book = calibre_db.order_authors(book) + book.authors = calibre_db.order_authors(book) author_names = [] for authr in book.authors: @@ -1249,9 +1249,9 @@ def table_xchange_author_title(): modif_date = False book = calibre_db.get_book(val) authors = book.title - entries = calibre_db.order_authors(book) + book.authors = calibre_db.order_authors(book) author_names = [] - for authr in entries.authors: + for authr in book.authors: author_names.append(authr.name.replace('|', ',')) title_change = handle_title_on_edit(book, " ".join(author_names)) diff --git a/cps/templates/detail.html b/cps/templates/detail.html index 6dd1c72a..bd8f71c1 100644 --- a/cps/templates/detail.html +++ b/cps/templates/detail.html @@ -36,9 +36,9 @@ {% endif %} {% endif %} - {% if g.user.kindle_mail and kindle_list %} - {% if kindle_list.__len__() == 1 %} - {{kindle_list[0]['text']}} + {% if g.user.kindle_mail and entry.kindle_list %} + {% if entry.kindle_list.__len__() == 1 %} + {{entry.kindle_list[0]['text']}} {% else %}
{% endif %} {% endif %} - {% if reader_list and g.user.role_viewer() %} + {% if entry.reader_list and g.user.role_viewer() %}
- {% if reader_list|length > 1 %} + {% if entry.reader_list|length > 1 %} {% else %} - {{_('Read in Browser')}} - {{reader_list[0]}} + {{_('Read in Browser')}} - {{entry.reader_list[0]}} {% endif %}
{% endif %} - {% if audioentries|length > 0 and g.user.role_viewer() %} + {% if entry.audioentries|length > 0 and g.user.role_viewer() %}
- {% if audioentries|length > 1 %} + {% if entry.audioentries|length > 1 %} {% else %} - {{_('Listen in Browser')}} - {{audioentries[0]}} + {{_('Listen in Browser')}} - {{entry.audioentries[0]}} {% endif %}
{% endif %} @@ -216,7 +216,7 @@
@@ -226,7 +226,7 @@
diff --git a/cps/web.py b/cps/web.py index 066169eb..ce887c98 100644 --- a/cps/web.py +++ b/cps/web.py @@ -187,7 +187,7 @@ def toggle_read(book_id): return "Custom Column No.{} is not existing in calibre database".format(config.config_read_column), 400 except (OperationalError, InvalidRequestError) as e: 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 "" @@ -1756,63 +1756,40 @@ def read_book(book_id, book_format): @web.route("/book/") @login_required_if_no_ano def show_book(book_id): - entries = calibre_db.get_filtered_book(book_id, allow_show_archived=True) + entries = calibre_db.get_book_read_archived(book_id, config.config_read_column, allow_show_archived=True) if entries: - for index in range(0, len(entries.languages)): - entries.languages[index].language_name = isoLanguages.get_language_name(get_locale(), entries.languages[ + read_book = entries[1] + archived_book = entries[2] + entry = entries[0] + entry.read_status = read_book == ub.ReadBook.STATUS_FINISHED + entry.is_archived = archived_book + for index in range(0, len(entry.languages)): + entry.languages[index].language_name = isoLanguages.get_language_name(get_locale(), entry.languages[ index].lang_code) cc = get_cc_columns(filter_config_custom_read=True) book_in_shelfs = [] shelfs = ub.session.query(ub.BookShelf).filter(ub.BookShelf.book_id == book_id).all() - for entry in shelfs: - book_in_shelfs.append(entry.shelf) + for sh in shelfs: + book_in_shelfs.append(sh.shelf) - if not current_user.is_anonymous: - if not config.config_read_column: - matching_have_read_book = ub.session.query(ub.ReadBook). \ - filter(and_(ub.ReadBook.user_id == int(current_user.id), ub.ReadBook.book_id == book_id)).all() - have_read = len( - matching_have_read_book) > 0 and matching_have_read_book[0].read_status == ub.ReadBook.STATUS_FINISHED - else: - try: - matching_have_read_book = getattr(entries, 'custom_column_' + str(config.config_read_column)) - have_read = len(matching_have_read_book) > 0 and matching_have_read_book[0].value - except (KeyError, AttributeError): - log.error("Custom Column No.%d is not existing in calibre database", config.config_read_column) - have_read = None + entry.tags = sort(entry.tags, key=lambda tag: tag.name) - archived_book = ub.session.query(ub.ArchivedBook).\ - filter(and_(ub.ArchivedBook.user_id == int(current_user.id), - ub.ArchivedBook.book_id == book_id)).first() - is_archived = archived_book and archived_book.is_archived + entry.authors = calibre_db.order_authors(entry) - else: - have_read = None - is_archived = None + entry.kindle_list = check_send_to_kindle(entry) + entry.reader_list = check_read_formats(entry) - entries.tags = sort(entries.tags, key=lambda tag: tag.name) - - entries = calibre_db.order_authors(entries) - - kindle_list = check_send_to_kindle(entries) - reader_list = check_read_formats(entries) - - audioentries = [] - for media_format in entries.data: + entry.audioentries = [] + for media_format in entry.data: if media_format.format.lower() in constants.EXTENSIONS_AUDIO: - audioentries.append(media_format.format.lower()) + entry.audioentries.append(media_format.format.lower()) return render_title_template('detail.html', - entry=entries, - audioentries=audioentries, + entry=entry, cc=cc, is_xhr=request.headers.get('X-Requested-With')=='XMLHttpRequest', - title=entries.title, + title=entry.title, books_shelfs=book_in_shelfs, - have_read=have_read, - is_archived=is_archived, - kindle_list=kindle_list, - reader_list=reader_list, page="book") else: log.debug(u"Oops! Selected book title is unavailable. File does not exist or is not accessible")