diff --git a/cps/basic.py b/cps/basic.py new file mode 100644 index 00000000..b0121010 --- /dev/null +++ b/cps/basic.py @@ -0,0 +1,90 @@ +# 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 cps.pagination import Pagination +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 + 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, + off, + order, + limit, + *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/jinjia.py b/cps/jinjia.py index 9635f154..cb51b2bc 100644 --- a/cps/jinjia.py +++ b/cps/jinjia.py @@ -43,6 +43,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) diff --git a/cps/main.py b/cps/main.py index 1b3b40b4..44e563f9 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 @@ -64,6 +65,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/static/css/basic.css b/cps/static/css/basic.css new file mode 100644 index 00000000..7fe9e5b8 --- /dev/null +++ b/cps/static/css/basic.css @@ -0,0 +1,108 @@ +body { + margin: 0; +} + +nav { + height: 75px; + padding: 5px 20px; + width: 100%; + display: table; + box-sizing: border-box; + border-bottom: 1px solid black; +} + +nav > * { + display: inline-block; + display: table-cell; + vertical-align: middle; + float: none; + text-align: center; + width: auto; +} + +nav > *:first-child { + text-align: left; + width: 1%; +} + +.theme{ + text-align: center; + margin: 10px; +} +nav > *:last-child { + text-align: right; + width: 1%; +} + +nav > a { + color: black; + margin: 0 20px; +} + +.search { + margin: auto auto; +} + +form > input { + width: 18ch; + padding-left: 4px; +} + +form > * { + height: 50px; + background-color: white; + border-radius: 0; + border: 1px solid #ccc; + padding: 0; + margin: 0; + display: inline-block; + vertical-align: top; +} + +form > span { + margin-left: -5px; +} + +button { + border: none; + padding: 0 10px; + margin: 0; + width: 160px; + height: 100%; + background-color: white; +} + +.body { + padding: 5px 20px; +} + +a { + color: black; +} + +img { + width: 150px; + height: 250px; + object-fit: cover; +} + +.listing { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + margin-right: 20px; +} + +.pagination { + padding: 10px 0; + height: 20px; + font-weight: 700; +} + +.pagination > div { + float: left; +} + +.pagination > div:last-child { + float: right; +} diff --git a/cps/templates/basic_detail.html b/cps/templates/basic_detail.html new file mode 100644 index 00000000..1996497b --- /dev/null +++ b/cps/templates/basic_detail.html @@ -0,0 +1,81 @@ +{% 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..ae88087f --- /dev/null +++ b/cps/templates/basic_index.html @@ -0,0 +1,32 @@ +{% extends "basic_layout.html" %} +{% block body %} + + + +{% 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 new file mode 100644 index 00000000..b3000be8 --- /dev/null +++ b/cps/templates/basic_layout.html @@ -0,0 +1,47 @@ + + + + +{{instance}} | {{title}} + + + + + + +
+
+ {% if current_user.is_authenticated or g.allow_anonymous %} + + + {% endif %} +
+
+
+ {% block body %} + {% endblock %} +
+ + + diff --git a/cps/templates/layout.html b/cps/templates/layout.html index 2aba6f10..d433a5aa 100644 --- a/cps/templates/layout.html +++ b/cps/templates/layout.html @@ -37,11 +37,12 @@ {{instance}} {% if g.current_theme == 1 %} -
+
{% endif %} {% if current_user.is_authenticated or g.allow_anonymous %} -