From aecc68d11e2686957c4cc5ba05b57d6c3d47bce3 Mon Sep 17 00:00:00 2001 From: Chris Arderne Date: Wed, 28 Feb 2024 18:37:13 +0000 Subject: [PATCH 1/6] add basic view for kindle --- cps/basic.py | 87 +++++++++++++++++++++++++++++++++ cps/main.py | 2 + cps/templates/basic_detail.html | 77 +++++++++++++++++++++++++++++ cps/templates/basic_index.html | 24 +++++++++ cps/templates/basic_layout.html | 30 ++++++++++++ 5 files changed, 220 insertions(+) create mode 100644 cps/basic.py create mode 100644 cps/templates/basic_detail.html create mode 100644 cps/templates/basic_index.html create mode 100644 cps/templates/basic_layout.html diff --git a/cps/basic.py b/cps/basic.py new file mode 100644 index 00000000..9830d6c1 --- /dev/null +++ b/cps/basic.py @@ -0,0 +1,87 @@ +# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) +# Copyright (C) 2018-2019 OzzieIsaacs, cervinko, jkrehm, bodybybuddha, ok11, +# andy29485, idalin, Kyosfonica, wuqi, Kennyl, lemmsh, +# falgh1, grunjol, csitko, ytils, xybydy, trasba, vrabe, +# ruben-herold, marblepebble, JackED42, SiphonSquirrel, +# apetresc, nanu-c, mutschler, carderne +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + +from flask import Blueprint +from flask_babel import gettext as _ +from flask_babel import get_locale +from flask import request, redirect, url_for + +from . import logger, isoLanguages +from . import db, config +from . import calibre_db +from .usermanagement import login_required_if_no_ano +from .render_template import render_title_template +from .web import get_sort_function + +try: + from natsort import natsorted as sort +except ImportError: + sort = sorted # Just use regular sort then, may cause issues with badly named pages in cbz/cbr files + +basic = Blueprint('basic', __name__) + +log = logger.create() + + +@basic.route("/basic", methods=["GET"]) +@login_required_if_no_ano +def index(): + term = request.args.get("query", "") # default to showing all books + offset = 0 + order = get_sort_function("stored", "search") + join = db.books_series_link, db.Books.id == db.books_series_link.c.book, db.Series + entries, result_count, pagination = calibre_db.get_search_results(term, + config, + offset, + order, + None, + *join) + return render_title_template('basic_index.html', + searchterm=term, + pagination=pagination, + query=term, + adv_searchterm=term, + entries=entries, + result_count=result_count, + title=_("Search"), + page="search", + order=order[1]) + + +@basic.route("/basic_book/") +@login_required_if_no_ano +def show_book(book_id): + entries = calibre_db.get_book_read_archived(book_id, config.config_read_column, allow_show_archived=True) + if entries: + entry = entries[0] + for lang_index in range(0, len(entry.languages)): + entry.languages[lang_index].language_name = isoLanguages.get_language_name(get_locale(), entry.languages[ + lang_index].lang_code) + entry.ordered_authors = calibre_db.order_authors([entry]) + + return render_title_template('basic_detail.html', + entry=entry, + is_xhr=request.headers.get('X-Requested-With') == 'XMLHttpRequest', + title=entry.title, + page="book") + else: + log.debug("Selected book is unavailable. File does not exist or is not accessible") + return redirect(url_for("basic.index")) diff --git a/cps/main.py b/cps/main.py index 286b2b27..1116cceb 100644 --- a/cps/main.py +++ b/cps/main.py @@ -31,6 +31,7 @@ def main(): app = create_app() from .web import web + from .basic import basic from .opds import opds from .admin import admi from .gdrive import gdrive @@ -61,6 +62,7 @@ def main(): app.register_blueprint(search) app.register_blueprint(tasks) app.register_blueprint(web) + app.register_blueprint(basic) app.register_blueprint(opds) limiter.limit("3/minute",key_func=request_username)(opds) app.register_blueprint(jinjia) diff --git a/cps/templates/basic_detail.html b/cps/templates/basic_detail.html new file mode 100644 index 00000000..c3c358e2 --- /dev/null +++ b/cps/templates/basic_detail.html @@ -0,0 +1,77 @@ +{% extends "basic_layout.html" %} + +{% block body %} +
+ +

{{ entry.title }}

+
+ {% for author in entry.ordered_authors %} +

{{ author.name.replace("|",",") }}

+ {% endfor %} +
+ +{% if current_user.role_download() %} + {% if entry.data|length %} +
+

Download

+ {% for format in entry.data %} +

+ + {{ format.format }} ({{ format.uncompressed_size|filesizeformat }}) +

+ {% endfor %} +
+ {% endif %} +{% endif %} + +

Details

+ +{% if entry.series|length > 0 %} +

{{ _("Book %(index)s of %(range)s", index=entry.series_index | formatfloat(2), range=(entry.series[0].name)|safe) }}

+{% endif %} + +{% if entry.languages|length > 0 %} +
+

+ + {{_('Language')}}: {% for language in entry.languages %}{{language.language_name}}{% if not loop.last %}, {% endif %}{% endfor %} + +

+
+{% endif %} + +{% if entry.identifiers|length > 0 %} +
+

+ + {% for identifier in entry.identifiers %} +

{{ identifier.format_type() }}: {{ identifier|escape }}

+ {% endfor %} +

+
+{% endif %} + +{% if entry.publishers|length > 0 %} +
+

+ {{ _('Publisher') }}: + {{ entry.publishers[0].name }} + +

+
+{% endif %} + +{% if (entry.pubdate|string)[:10] != '0101-01-01' %} +
+

{{ _('Published') }}: {{ entry.pubdate|formatdate }}

+
+{% endif %} + +{% if entry.comments|length > 0 and entry.comments[0].text|length > 0 %} +
+

{{ _('Description:') }}

+ {{ entry.comments[0].text|safe }} +
+{% endif %} +
+{% endblock %} diff --git a/cps/templates/basic_index.html b/cps/templates/basic_index.html new file mode 100644 index 00000000..9734c0d6 --- /dev/null +++ b/cps/templates/basic_index.html @@ -0,0 +1,24 @@ +{% extends "basic_layout.html" %} +{% block body %} + +
+ {% if entries|length < 1 %} +

{{_('No Results Found')}}

+

{{_('Search Term:')}} {{adv_searchterm}}

+ {% endif %} + +
+ {% for entry in entries %} + {% if entry.Books.authors %} + {% set author = entry.Books.authors[0].name.replace('|',',')|shortentitle(30) %} + {% else %} + {% set author = '' %} + {% endif %} + +

{{ author }} - {{entry.Books.title|shortentitle}}

+
+ {% endfor %} +
+
+ +{% endblock %} diff --git a/cps/templates/basic_layout.html b/cps/templates/basic_layout.html new file mode 100644 index 00000000..eb990b8f --- /dev/null +++ b/cps/templates/basic_layout.html @@ -0,0 +1,30 @@ + + + + {{instance}} | {{title}} + + + + +
+
+ {% if current_user.is_authenticated or g.allow_anonymous %} +
+
+ + + + +
+
+ {% if not current_user.is_anonymous %} + + {{_('Logout')}} + + {% endif %} + {% endif %} +
+
+ {% block body %}{% endblock %} + + From 51eb6bddf66399fb098014ee2b88711b57b15c09 Mon Sep 17 00:00:00 2001 From: Chris Arderne Date: Wed, 3 Apr 2024 10:40:13 +0100 Subject: [PATCH 2/6] improve basic CSS, add cover image --- cps/templates/basic_detail.html | 4 ++ cps/templates/basic_layout.html | 101 ++++++++++++++++++++++++++++---- 2 files changed, 92 insertions(+), 13 deletions(-) diff --git a/cps/templates/basic_detail.html b/cps/templates/basic_detail.html index c3c358e2..1996497b 100644 --- a/cps/templates/basic_detail.html +++ b/cps/templates/basic_detail.html @@ -10,6 +10,10 @@ {% endfor %} +
+ +
+ {% if current_user.role_download() %} {% if entry.data|length %}
diff --git a/cps/templates/basic_layout.html b/cps/templates/basic_layout.html index eb990b8f..01ffbfc0 100644 --- a/cps/templates/basic_layout.html +++ b/cps/templates/basic_layout.html @@ -1,16 +1,86 @@ - - {{instance}} | {{title}} - - - - + + +{{instance}} | {{title}} + + + + + + +
-
- {% if current_user.is_authenticated or g.allow_anonymous %} + {% if current_user.is_authenticated or g.allow_anonymous %} + + {% endif %}
- {% block body %}{% endblock %} - +
+
+ {% block body %} + {% endblock %} +
+ + From ae5ccf6e91284ee5d0ed052d399382cf36b937d1 Mon Sep 17 00:00:00 2001 From: Chris Arderne Date: Wed, 3 Apr 2024 13:12:31 +0100 Subject: [PATCH 3/6] fix pagination jinja custom function --- cps/jinjia.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cps/jinjia.py b/cps/jinjia.py index 584e7d6b..14bdf7e3 100644 --- a/cps/jinjia.py +++ b/cps/jinjia.py @@ -44,6 +44,8 @@ def url_for_other_page(page): args = request.view_args.copy() args['page'] = page for get, val in request.args.items(): + if get == "page": + continue args[get] = val return url_for(request.endpoint, **args) From 458576a141e4b2a5db09528bfdc3f830a598418b Mon Sep 17 00:00:00 2001 From: Chris Arderne Date: Wed, 3 Apr 2024 13:12:39 +0100 Subject: [PATCH 4/6] add pagination to basic --- cps/basic.py | 9 +++++--- cps/templates/basic_index.html | 40 ++++++++++++++++++++------------- cps/templates/basic_layout.html | 14 ++++++++++++ 3 files changed, 44 insertions(+), 19 deletions(-) diff --git a/cps/basic.py b/cps/basic.py index 9830d6c1..b0121010 100644 --- a/cps/basic.py +++ b/cps/basic.py @@ -19,6 +19,7 @@ # along with this program. If not, see . +from cps.pagination import Pagination from flask import Blueprint from flask_babel import gettext as _ from flask_babel import get_locale @@ -45,14 +46,16 @@ log = logger.create() @login_required_if_no_ano def index(): term = request.args.get("query", "") # default to showing all books - offset = 0 + limit = 15 + page = int(request.args.get("page") or 1) + off = (page - 1) * limit order = get_sort_function("stored", "search") join = db.books_series_link, db.Books.id == db.books_series_link.c.book, db.Series entries, result_count, pagination = calibre_db.get_search_results(term, config, - offset, + off, order, - None, + limit, *join) return render_title_template('basic_index.html', searchterm=term, diff --git a/cps/templates/basic_index.html b/cps/templates/basic_index.html index 9734c0d6..ae88087f 100644 --- a/cps/templates/basic_index.html +++ b/cps/templates/basic_index.html @@ -1,24 +1,32 @@ {% extends "basic_layout.html" %} {% block body %} -
- {% if entries|length < 1 %} -

{{_('No Results Found')}}

-

{{_('Search Term:')}} {{adv_searchterm}}

- {% endif %} - + +{% if entries|length < 1 %} +

{{_('No Results Found')}}

+{% endif %} + +{% for entry in entries %} + {% if entry.Books.authors %} + {% set author = entry.Books.authors[0].name.replace('|',',')|shortentitle(30) %} + {% else %} + {% set author = '' %} + {% endif %} + +

{{ author }} - {{entry.Books.title|shortentitle}}

+
+{% endfor %} + {% endblock %} diff --git a/cps/templates/basic_layout.html b/cps/templates/basic_layout.html index 01ffbfc0..a7f1d192 100644 --- a/cps/templates/basic_layout.html +++ b/cps/templates/basic_layout.html @@ -71,6 +71,20 @@ nav > a { height: 250px; object-fit: cover; } + +.listing { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + margin-right: 20px; +} + +.pagination { + display: flex; + justify-content: space-between; + padding: 10px 0; + height: 20px; +} From ec8afde6b2de98aec9ceb4ea49e61e032eaf22b2 Mon Sep 17 00:00:00 2001 From: Chris Arderne Date: Wed, 3 Apr 2024 13:26:56 +0100 Subject: [PATCH 5/6] add basic home button --- cps/templates/basic_layout.html | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/cps/templates/basic_layout.html b/cps/templates/basic_layout.html index a7f1d192..4f35f423 100644 --- a/cps/templates/basic_layout.html +++ b/cps/templates/basic_layout.html @@ -20,21 +20,22 @@ nav { nav > a { color: black; - margin-right: 20px; + margin: 0 20px; } .search { - margin: 20px auto; + margin: auto auto; width: 50%; display: flex; flex: 1; + justify-content: center; } -.search > input { +form > input { padding-left: 4px; } -.search > * { +form > * { height: 32px; background-color: white; border-radius: 0; @@ -45,11 +46,11 @@ nav > a { vertical-align: top; } -.search > span { +form > span { margin-left: -5px; } -.search button { +button { border: none; padding: 0; margin: 0; @@ -62,11 +63,11 @@ nav > a { padding: 0 20px; } -.body a { +a { color: black; } -.body img { +img { width: 150px; height: 250px; object-fit: cover; @@ -93,16 +94,19 @@ nav > a {
{% if current_user.is_authenticated or g.allow_anonymous %}