diff --git a/cps/db.py b/cps/db.py index 64abbe1b..cf4ab50c 100644 --- a/cps/db.py +++ b/cps/db.py @@ -605,13 +605,6 @@ class CalibreDB(): 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), @@ -704,11 +697,13 @@ class CalibreDB(): return outcome[offset:offset + limit] # Fill indexpage with all requested data from database - def fill_indexpage(self, page, pagesize, database, db_filter, order, *join): - return self.fill_indexpage_with_archived_books(page, pagesize, db_filter, order, False, database, join) + def fill_indexpage(self, page, pagesize, database, db_filter, order, + join_archive_read=False, config_read_column=0, *join): + return self.fill_indexpage_with_archived_books(page, database, pagesize, db_filter, order, False, + join_archive_read, config_read_column, *join) - def fill_indexpage_with_archived_books(self, page, pagesize, db_filter, order, allow_show_archived, - *args): + def fill_indexpage_with_archived_books(self, page, database, pagesize, db_filter, order, allow_show_archived, + join_archive_read, config_read_column, *join): pagesize = pagesize or self.config.config_books_per_page if current_user.show_detail_random(): randm = self.session.query(Books) \ @@ -717,15 +712,26 @@ class CalibreDB(): .limit(self.config.config_random_books).all() else: randm = false() - if len(args) > 1: - if isinstance(args[0], DeclarativeMeta): - query = self.session.query(args[0]) + if join_archive_read: + if not config_read_column: + query = (self.session.query(database, ub.ReadBook.read_status, ub.ArchivedBook.is_archived) + .select_from(Books) + .outerjoin(ub.ReadBook, + and_(ub.ReadBook.user_id == int(current_user.id), ub.ReadBook.book_id == Books.id))) else: - query = self.session.query(*args[0]) - join = args[1] + try: + read_column = cc_classes[config_read_column] + query = (self.session.query(database, read_column.value, ub.ArchivedBook.is_archived) + .select_from(Books) + .outerjoin(read_column, read_column.book == Books.id)) + 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 + query =self.session.query(database, None, ub.ArchivedBook.is_archived) + query = query.outerjoin(ub.ArchivedBook, and_(Books.id == ub.ArchivedBook.book_id, + int(current_user.id) == ub.ArchivedBook.user_id)) else: - join = tuple() - query = self.session.query(args) + query = self.session.query(database) off = int(int(pagesize) * (page - 1)) indx = len(join) @@ -793,16 +799,29 @@ class CalibreDB(): return self.session.query(Books) \ .filter(and_(Books.authors.any(and_(*q)), func.lower(Books.title).ilike("%" + title + "%"))).first() - def search_query(self, term, *join): + def search_query(self, term, config_read_column, *join): term.strip().lower() self.session.connection().connection.connection.create_function("lower", 1, lcase) q = list() authorterms = re.split("[, ]+", term) for authorterm in authorterms: q.append(Books.authors.any(func.lower(Authors.name).ilike("%" + authorterm + "%"))) - query = (self.session.query(Books, ub.ArchivedBook.is_archived) - .outerjoin(ub.ArchivedBook, and_(Books.id == ub.ArchivedBook.book_id, - int(current_user.id) == ub.ArchivedBook.user_id))) + if not config_read_column: + query = (self.session.query(Books, ub.ArchivedBook.is_archived, ub.ReadBook).select_from(Books) + .outerjoin(ub.ReadBook, and_(Books.id == ub.ReadBook.book_id, + int(current_user.id) == ub.ReadBook.user_id))) + else: + try: + read_column = cc_classes[config_read_column] + query = (self.session.query(Books, ub.ArchivedBook.is_archived, read_column.value).select_from(Books) + .outerjoin(read_column, read_column.book == Books.id)) + except (KeyError, AttributeError): + log.error("Custom Column No.%d is not existing in calibre database", config_read_column) + # Skip linking read column + query = self.session.query(Books, ub.ArchivedBook.is_archived, None) + query = query.outerjoin(ub.ArchivedBook, and_(Books.id == ub.ArchivedBook.book_id, + int(current_user.id) == ub.ArchivedBook.user_id)) + if len(join) == 6: query = query.outerjoin(join[0], join[1]).outerjoin(join[2]).outerjoin(join[3], join[4]).outerjoin(join[5]) if len(join) == 3: diff --git a/cps/editbooks.py b/cps/editbooks.py index e466e22c..383422b1 100644 --- a/cps/editbooks.py +++ b/cps/editbooks.py @@ -1161,13 +1161,22 @@ def edit_list_book(param): ret = Response(json.dumps({'success': True, 'newValue': ' & '.join([author.replace('|',',') for author in input_authors])}), mimetype='application/json') + elif param =='is_archive': + # ToDo save + ret = Response(json.dumps({'success': True, 'newValue': vals['value']}), + mimetype='application/json') + elif param =='read_status': + # ToDo save + ret = Response(json.dumps({'success': True, 'newValue': vals['value']}), + mimetype='application/json') elif param.startswith("custom_column_"): new_val = dict() new_val[param] = vals['value'] edit_single_cc_data(book.id, book, param[14:], new_val) ret = Response(json.dumps({'success': True, 'newValue': vals['value']}), mimetype='application/json') - + else: + return _("Parameter not found"), 400 book.last_modified = datetime.utcnow() try: calibre_db.session.commit() diff --git a/cps/shelf.py b/cps/shelf.py index 09fe8dd4..2f9269a4 100644 --- a/cps/shelf.py +++ b/cps/shelf.py @@ -425,6 +425,7 @@ def render_show_shelf(shelf_type, shelf_id, page_no, sort_param): db.Books, ub.BookShelf.shelf == shelf_id, [ub.BookShelf.order.asc()], + False, 0, ub.BookShelf, ub.BookShelf.book_id == db.Books.id) # delete chelf entries where book is not existent anymore, can happen if book is deleted outside calibre-web wrong_entries = calibre_db.session.query(ub.BookShelf) \ diff --git a/cps/static/js/table.js b/cps/static/js/table.js index d1a32862..ba664d64 100644 --- a/cps/static/js/table.js +++ b/cps/static/js/table.js @@ -631,14 +631,21 @@ function singleUserFormatter(value, row) { } function checkboxFormatter(value, row){ - if(value & this.column) + if (value & this.column) return ''; else return ''; } +function bookCheckboxFormatter(value, row){ + if (value) + return ''; + else + return ''; +} + function singlecheckboxFormatter(value, row){ - if(value) + if (value) return ''; else return ''; @@ -790,7 +797,7 @@ function handleListServerResponse (data) { function checkboxChange(checkbox, userId, field, field_index) { $.ajax({ method: "post", - url: window.location.pathname + "/../../ajax/editlistusers/" + field, + url: getPath() + "/ajax/editlistusers/" + field, data: {"pk": userId, "field_index": field_index, "value": checkbox.checked}, error: function(data) { handleListServerResponse([{type:"danger", message:data.responseText}]) @@ -799,6 +806,19 @@ function checkboxChange(checkbox, userId, field, field_index) { }); } +function BookCheckboxChange(checkbox, userId, field) { + $.ajax({ + method: "post", + url: getPath() + "/ajax/editbooks/" + field, + data: {"pk": userId, "value": checkbox.checked}, + error: function(data) { + handleListServerResponse([{type:"danger", message:data.responseText}]) + }, + success: handleListServerResponse + }); +} + + function selectHeader(element, field) { if (element.value !== "None") { confirmDialog(element.id, "GeneralChangeModal", 0, function () { diff --git a/cps/templates/book_table.html b/cps/templates/book_table.html index 6f8e8747..bbdbe50d 100644 --- a/cps/templates/book_table.html +++ b/cps/templates/book_table.html @@ -14,13 +14,13 @@ >{{ show_text }} {%- endmacro %} -{% macro book_checkbox_row(parameter, array_field, show_text, element, value, sort) -%} - + {%- endmacro %} @@ -71,7 +71,8 @@ {{ text_table_row('publishers', _('Enter Publishers'),_('Publishers'), false, true) }} {{_('Comments')}} - + {{ book_checkbox_row('is_archived', _('Enter Archiv Status'), false)}} + {{ book_checkbox_row('read_status', _('Enter Read Status'), false)}} {% for c in cc %} {% if c.datatype == "int" %} {{c.name}} diff --git a/cps/templates/detail.html b/cps/templates/detail.html index 00c6ca96..919afaff 100644 --- a/cps/templates/detail.html +++ b/cps/templates/detail.html @@ -228,7 +228,7 @@
diff --git a/cps/web.py b/cps/web.py index 0fcb43f4..6892ec9e 100644 --- a/cps/web.py +++ b/cps/web.py @@ -406,6 +406,7 @@ def render_books_list(data, sort, book_id, page): else: website = data or "newest" entries, random, pagination = calibre_db.fill_indexpage(page, 0, db.Books, True, order, + False, 0, db.books_series_link, db.Books.id == db.books_series_link.c.book, db.Series) @@ -419,6 +420,7 @@ def render_rated_books(page, book_id, order): db.Books, db.Books.ratings.any(db.Ratings.rating > 9), order, + False, 0, db.books_series_link, db.Books.id == db.books_series_link.c.book, db.Series) @@ -482,6 +484,7 @@ def render_downloaded_books(page, order, user_id): db.Books, ub.Downloads.user_id == user_id, order, + False, 0, ub.Downloads, db.Books.id == ub.Downloads.book_id) for book in entries: if not calibre_db.session.query(db.Books).filter(calibre_db.common_filters()) \ @@ -504,6 +507,7 @@ def render_author_books(page, author_id, order): db.Books, db.Books.authors.any(db.Authors.id == author_id), [order[0], db.Series.name, db.Books.series_index], + False, 0, db.books_series_link, db.Books.id == db.books_series_link.c.book, db.Series) @@ -535,6 +539,7 @@ def render_publisher_books(page, book_id, order): db.Books, db.Books.publishers.any(db.Publishers.id == book_id), [db.Series.name, order[0], db.Books.series_index], + False, 0, db.books_series_link, db.Books.id == db.books_series_link.c.book, db.Series) @@ -590,6 +595,7 @@ def render_category_books(page, book_id, order): db.Books, db.Books.tags.any(db.Tags.id == book_id), [order[0], db.Series.name, db.Books.series_index], + False, 0, db.books_series_link, db.Books.id == db.books_series_link.c.book, db.Series) @@ -625,6 +631,7 @@ def render_read_books(page, are_read, as_xml=False, order=None): db.Books, db_filter, order, + False, 0, db.books_series_link, db.Books.id == db.books_series_link.c.book, db.Series, @@ -639,6 +646,7 @@ def render_read_books(page, are_read, as_xml=False, order=None): db.Books, db_filter, order, + False, 0, db.books_series_link, db.Books.id == db.books_series_link.c.book, db.Series, @@ -676,11 +684,12 @@ def render_archived_books(page, order): archived_filter = db.Books.id.in_(archived_book_ids) - entries, random, pagination = calibre_db.fill_indexpage_with_archived_books(page, 0, + entries, random, pagination = calibre_db.fill_indexpage_with_archived_books(page, db.Books, + 0, archived_filter, order, True, - db.Books) + False, 0) name = _(u'Archived Books') + ' (' + str(len(archived_book_ids)) + ')' pagename = "archived" @@ -770,7 +779,7 @@ def list_books(): sort = request.args.get("sort", "id") order = request.args.get("order", "").lower() state = None - join = list() + join = tuple() if sort == "state": state = json.loads(request.args.get("state", "[]")) @@ -802,27 +811,48 @@ def list_books(): books = calibre_db.search_query(search).all() filtered_count = len(books) else: - books = (calibre_db.session.query(db.Books,ub.ArchivedBook.is_archived) - .outerjoin(ub.ArchivedBook, and_(db.Books.id == ub.ArchivedBook.book_id, - int(current_user.id) == ub.ArchivedBook.user_id)) + if not config.config_read_column: + books = (calibre_db.session.query(db.Books, ub.ReadBook.read_status, ub.ArchivedBook.is_archived) + .select_from(db.Books) + .outerjoin(ub.ReadBook, + and_(ub.ReadBook.user_id == int(current_user.id), + ub.ReadBook.book_id == db.Books.id))) + else: + try: + read_column = db.cc_classes[config.config_read_column] + books = (calibre_db.session.query(db.Books, read_column.value, ub.ArchivedBook.is_archived) + .select_from(db.Books) + .outerjoin(read_column, read_column.book == db.Books.id)) + 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 + books =calibre_db.session.query(db.Books, None, ub.ArchivedBook.is_archived) + books = (books.outerjoin(ub.ArchivedBook, and_(db.Books.id == ub.ArchivedBook.book_id, + int(current_user.id) == ub.ArchivedBook.user_id)) .filter(calibre_db.common_filters()).all()) entries = calibre_db.get_checkbox_sorted(books, state, off, limit, order, True) elif search: - entries, filtered_count, __ = calibre_db.get_search_results(search, off, order, limit, *tuple(join)) + entries, filtered_count, __ = calibre_db.get_search_results(search, + off, + order, + limit, + config.config_read_column, + *join) else: - join.append(ub.ArchivedBook) - join.append(and_(db.Books.id == ub.ArchivedBook.book_id,int(current_user.id) == ub.ArchivedBook.user_id)) entries, __, __ = calibre_db.fill_indexpage((int(off) / (int(limit)) + 1), limit, - (db.Books, ub.ArchivedBook), + db.Books, True, order, - *tuple(join)) + True, + config.config_read_column, + *join) result = list() for entry in entries: val = entry[0] - val.is_archived = entry[1] == True + val.read_status = entry[1] == ub.ReadBook.STATUS_FINISHED + val.is_archived = entry[2] is True for index in range(0, len(val.languages)): val.languages[index].language_name = isoLanguages.get_language_name(get_locale(), val.languages[ index].lang_code)