1
0
mirror of https://github.com/janeczku/calibre-web synced 2024-11-24 10:37:23 +00:00

Update shelfs handling, bugfix changed updater

This commit is contained in:
Ozzieisaacs 2020-04-02 18:23:24 +02:00
parent 0c27ff11b9
commit bab14a1fbf
9 changed files with 103 additions and 57 deletions

View File

@ -25,7 +25,7 @@ import sys
import datetime
from functools import wraps
from flask import Blueprint, request, render_template, Response, g, make_response
from flask import Blueprint, request, render_template, Response, g, make_response, abort
from flask_login import current_user
from sqlalchemy.sql.expression import func, text, or_, and_
from werkzeug.security import check_password_hash
@ -165,7 +165,10 @@ def feed_author(book_id):
off = request.args.get("offset") or 0
entries, __, pagination = fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1),
db.Books, db.Books.authors.any(db.Authors.id == book_id), [db.Books.timestamp.desc()])
return render_xml_template('feed.xml', entries=entries, pagination=pagination)
if len(entries):
return render_xml_template('feed.xml', entries=entries, pagination=pagination)
else:
return abort(404)
@opds.route("/opds/publisher")
@ -186,7 +189,10 @@ def feed_publisher(book_id):
entries, __, pagination = fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1),
db.Books, db.Books.publishers.any(db.Publishers.id == book_id),
[db.Books.timestamp.desc()])
return render_xml_template('feed.xml', entries=entries, pagination=pagination)
if len(entries):
return render_xml_template('feed.xml', entries=entries, pagination=pagination)
else:
return abort(404)
@opds.route("/opds/category")
@ -206,7 +212,10 @@ def feed_category(book_id):
off = request.args.get("offset") or 0
entries, __, pagination = fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1),
db.Books, db.Books.tags.any(db.Tags.id == book_id), [db.Books.timestamp.desc()])
return render_xml_template('feed.xml', entries=entries, pagination=pagination)
if len(entries):
return render_xml_template('feed.xml', entries=entries, pagination=pagination)
else:
return abort(404)
@opds.route("/opds/series")
@ -226,7 +235,10 @@ def feed_series(book_id):
off = request.args.get("offset") or 0
entries, __, pagination = fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1),
db.Books, db.Books.series.any(db.Series.id == book_id), [db.Books.series_index])
return render_xml_template('feed.xml', entries=entries, pagination=pagination)
if len(entries):
return render_xml_template('feed.xml', entries=entries, pagination=pagination)
else:
return abort(404)
@opds.route("/opds/ratings")
@requires_basic_auth_if_no_ano
@ -250,7 +262,11 @@ def feed_ratings(book_id):
off = request.args.get("offset") or 0
entries, __, pagination = fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1),
db.Books, db.Books.ratings.any(db.Ratings.id == book_id),[db.Books.timestamp.desc()])
return render_xml_template('feed.xml', entries=entries, pagination=pagination)
if len(entries):
return render_xml_template('feed.xml', entries=entries, pagination=pagination)
else:
return abort(404)
@opds.route("/opds/formats")
@ -274,7 +290,11 @@ def feed_format(book_id):
off = request.args.get("offset") or 0
entries, __, pagination = fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1),
db.Books, db.Books.data.any(db.Data.format == book_id.upper()), [db.Books.timestamp.desc()])
return render_xml_template('feed.xml', entries=entries, pagination=pagination)
if len(entries):
return render_xml_template('feed.xml', entries=entries, pagination=pagination)
else:
return abort(404)
@opds.route("/opds/language")
@opds.route("/opds/language/")
@ -305,20 +325,23 @@ def feed_languages(book_id):
off = request.args.get("offset") or 0
entries, __, pagination = fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1),
db.Books, db.Books.languages.any(db.Languages.id == book_id), [db.Books.timestamp.desc()])
return render_xml_template('feed.xml', entries=entries, pagination=pagination)
@opds.route("/opds/shelfindex", defaults={'public': 0})
@opds.route("/opds/shelfindex/<string:public>")
@requires_basic_auth_if_no_ano
def feed_shelfindex(public):
off = request.args.get("offset") or 0
if public != 0:
shelf = g.public_shelfes
number = len(shelf)
if len(entries):
return render_xml_template('feed.xml', entries=entries, pagination=pagination)
else:
shelf = g.user.shelf
number = shelf.count()
return abort(404)
@opds.route("/opds/shelfindex") #, defaults={'public': 0})
# @opds.route("/opds/shelfindex/<string:public>")
@requires_basic_auth_if_no_ano
def feed_shelfindex():
off = request.args.get("offset") or 0
# if public != 0:
shelf = g.shelves_access
number = len(shelf)
#else:
#shelf = g.user.shelf
# number = shelf.count()
pagination = Pagination((int(off) / (int(config.config_books_per_page)) + 1), config.config_books_per_page,
number)
return render_xml_template('feed.xml', listelements=shelf, folder='opds.feed_shelf', pagination=pagination)
@ -346,6 +369,8 @@ def feed_shelf(book_id):
pagination = Pagination((int(off) / (int(config.config_books_per_page)) + 1), config.config_books_per_page,
len(result))
return render_xml_template('feed.xml', entries=result, pagination=pagination)
else:
return abort(404)
@opds.route("/opds/download/<book_id>/<book_format>/")

View File

@ -24,7 +24,7 @@ import signal
import socket
try:
from gevent.pyewsgi import WSGIServer
from gevent.pywsgi import WSGIServer
from gevent.pool import Pool
from gevent import __version__ as _version
VERSION = 'Gevent ' + _version
@ -171,6 +171,7 @@ class WebServer(object):
except Exception as ex:
log.error("Error starting server: %s", ex)
print("Error starting server: %s" % ex)
self.stop()
return False
finally:
self.wsgiserver = None

View File

@ -204,12 +204,24 @@ def create_shelf():
shelf.is_public = 1
shelf.name = to_save["title"]
shelf.user_id = int(current_user.id)
existing_shelf = ub.session.query(ub.Shelf).filter(
or_((ub.Shelf.name == to_save["title"]) & (ub.Shelf.is_public == 1),
(ub.Shelf.name == to_save["title"]) & (ub.Shelf.user_id == int(current_user.id)))).first()
if existing_shelf:
flash(_(u"A shelf with the name '%(title)s' already exists.", title=to_save["title"]), category="error")
is_shelf_name_unique = False
if shelf.is_public == 1:
is_shelf_name_unique = ub.session.query(ub.Shelf) \
.filter((ub.Shelf.name == to_save["title"]) & (ub.Shelf.is_public == 1)) \
.first() is None
if not is_shelf_name_unique:
flash(_(u"A public shelf with the name '%(title)s' already exists.", title=to_save["title"]), category="error")
else:
is_shelf_name_unique = ub.session.query(ub.Shelf) \
.filter((ub.Shelf.name == to_save["title"]) & (ub.Shelf.is_public == 0) & (ub.Shelf.user_id == int(current_user.id))) \
.first() is None
if not is_shelf_name_unique:
flash(_(u"A private shelf with the name '%(title)s' already exists.", title=to_save["title"]), category="error")
if is_shelf_name_unique:
try:
ub.session.add(shelf)
ub.session.commit()
@ -227,13 +239,26 @@ def edit_shelf(shelf_id):
shelf = ub.session.query(ub.Shelf).filter(ub.Shelf.id == shelf_id).first()
if request.method == "POST":
to_save = request.form.to_dict()
existing_shelf = ub.session.query(ub.Shelf).filter(
or_((ub.Shelf.name == to_save["title"]) & (ub.Shelf.is_public == 1),
(ub.Shelf.name == to_save["title"]) & (ub.Shelf.user_id == int(current_user.id)))).filter(
ub.Shelf.id != shelf_id).first()
if existing_shelf:
flash(_(u"A shelf with the name '%(title)s' already exists.", title=to_save["title"]), category="error")
is_shelf_name_unique = False
if shelf.is_public == 1:
is_shelf_name_unique = ub.session.query(ub.Shelf) \
.filter((ub.Shelf.name == to_save["title"]) & (ub.Shelf.is_public == 1)) \
.filter(ub.Shelf.id != shelf_id) \
.first() is None
if not is_shelf_name_unique:
flash(_(u"A public shelf with the name '%(title)s' already exists.", title=to_save["title"]), category="error")
else:
is_shelf_name_unique = ub.session.query(ub.Shelf) \
.filter((ub.Shelf.name == to_save["title"]) & (ub.Shelf.is_public == 0) & (ub.Shelf.user_id == int(current_user.id))) \
.filter(ub.Shelf.id != shelf_id) \
.first() is None
if not is_shelf_name_unique:
flash(_(u"A private shelf with the name '%(title)s' already exists.", title=to_save["title"]), category="error")
if is_shelf_name_unique:
shelf.name = to_save["title"]
if "is_public" in to_save:
shelf.is_public = 1

View File

@ -217,7 +217,7 @@
<div class="more-stuff">
{% if g.user.is_authenticated %}
{% if g.user.shelf.all() or g.public_shelfes %}
{% if g.user.shelf.all() or g.shelves_access %}
<div id="shelf-actions" class="btn-toolbar" role="toolbar">
<div class="btn-group" role="group" aria-label="Add to shelves">
<button id="add-to-shelf" type="button" class="btn btn-primary btn-sm dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
@ -237,7 +237,7 @@
</li>
{% endif %}
{%endfor%}
{% for shelf in g.public_shelfes %}
{% for shelf in g.shelves_access %}
{% if not shelf.id in books_shelfs %}
<li>
<a href="{{ url_for('shelf.add_to_shelf', book_id=entry.id, shelf_id=shelf.id) }}"
@ -263,7 +263,7 @@
</a>
{% endif %}
{%endfor%}
{% for shelf in g.public_shelfes %}
{% for shelf in g.shelves_access %}
{% if shelf.id in books_shelfs %}
<a href="{{ url_for('shelf.remove_from_shelf', book_id=entry.id, shelf_id=shelf.id) }}"
data-add-href="{{ url_for('shelf.add_to_shelf', book_id=entry.id, shelf_id=shelf.id) }}"

View File

@ -75,7 +75,11 @@
{% endif %}
{% for entry in listelements %}
<entry>
{% if entry.__class__.__name__ == 'Shelf' and entry.is_public == 1 %}
<title>{{entry.name}} {{_('(Public)')}}</title>
{% else %}
<title>{{entry.name}}</title>
{% endif %}
<id>{{ url_for(folder, book_id=entry.id) }}</id>
<link rel="subsection" type="application/atom+xml;profile=opds-catalog" href="{{url_for(folder, book_id=entry.id)}}"/>
</entry>

View File

@ -108,19 +108,10 @@
<content type="text">{{_('Books ordered by file formats')}}</content>
</entry>
<entry>
<title>{{_('Public Shelves')}}</title>
<link href="{{url_for('opds.feed_shelfindex', public='public')}}" type="application/atom+xml;profile=opds-catalog"/>
<id>{{url_for('opds.feed_shelfindex', public="public")}}</id>
<updated>{{ current_time }}</updated>
<content type="text">{{_('Books organized in public shelfs, visible to everyone')}}</content>
</entry>
{% if not current_user.is_anonymous %}
<entry>
<title>{{_('Your Shelves')}}</title>
<link href="{{url_for('opds.feed_shelfindex')}}" type="application/atom+xml;profile=opds-catalog"/>
<title>{{_('Shelves')}}</title>
<link href="{{url_for('opds.feed_shelfindex')}}" type="application/atom+xml;profile=opds-catalog"/>
<id>{{url_for('opds.feed_shelfindex')}}</id>
<updated>{{ current_time }}</updated>
<content type="text">{{_("User's own shelfs, only visible to the current user himself")}}</content>
<content type="text">{{_('Books organized in shelves')}}</content>
</entry>
{% endif %}
</feed>

View File

@ -133,14 +133,14 @@
{% endif %}
{% endfor %}
{% if g.user.is_authenticated or g.allow_anonymous %}
<li class="nav-head hidden-xs public-shelves">{{_('Public Shelves')}}</li>
{% for shelf in g.public_shelfes %}
<li><a href="{{url_for('shelf.show_shelf', shelf_id=shelf.id)}}"><span class="glyphicon glyphicon-list public_shelf"></span> {{shelf.name|shortentitle(40)}}</a></li>
<li class="nav-head hidden-xs public-shelves">{{_('Shelves')}}</li>
{% for shelf in g.shelves_access %}
<li><a href="{{url_for('shelf.show_shelf', shelf_id=shelf.id)}}"><span class="glyphicon glyphicon-list shelf"></span>{{shelf.name|shortentitle(40)}}{% if shelf.is_public == 1 %} {{_('(Public)')}}{% endif %}</a></li>
{% endfor %}
<li class="nav-head hidden-xs your-shelves">{{_('Your Shelves')}}</li>
<!--li class="nav-head hidden-xs your-shelves">{{_('Your Shelves')}}</li>
{% for shelf in g.user.shelf %}
<li><a href="{{url_for('shelf.show_shelf', shelf_id=shelf.id)}}"><span class="glyphicon glyphicon-list private_shelf"></span> {{shelf.name|shortentitle(40)}}</a></li>
{% endfor %}
<li><a href="{{url_for('shelf.show_shelf', shelf_id=shelf.id)}}"><span class="glyphicon glyphicon-list private_shelf"></span>{{shelf.name|shortentitle(40)}}{% if shelf.is_public == 1 %} {{_('(Public)')}}{% endif %}</a></li>
{% endfor %}-->
{% if not g.user.is_anonymous %}
<li id="nav_createshelf" class="create-shelf"><a href="{{url_for('shelf.create_shelf')}}">{{_('Create a Shelf')}}</a></li>
<li id="nav_about" {% if page == 'stat' %}class="active"{% endif %}><a href="{{url_for('about.stats')}}"><span class="glyphicon glyphicon-info-sign"></span> {{_('About')}}</a></li>

View File

@ -7,7 +7,7 @@
{% else %}
<h2>{{entries|length}} {{_('Results for:')}} {{searchterm}}</h2>
{% if g.user.is_authenticated %}
{% if g.user.shelf.all() or g.public_shelfes %}
{% if g.user.shelf.all() or g.shelves_access %}
<div id="shelf-actions" class="btn-toolbar" role="toolbar">
<div class="btn-group" role="group" aria-label="Add to shelves">
<button id="add-to-shelf" type="button" class="btn btn-primary btn-sm dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
@ -20,7 +20,7 @@
<li><a href="{{ url_for('shelf.search_to_shelf', shelf_id=shelf.id) }}"> {{shelf.name}}</a></li>
{% endif %}
{% endfor %}
{% for shelf in g.public_shelfes %}
{% for shelf in g.shelves_access %}
<li><a href="{{ url_for('shelf.search_to_shelf', shelf_id=shelf.id) }}">{{shelf.name}}</a></li>
{% endfor %}
</ul>

View File

@ -37,7 +37,7 @@ from flask import render_template, request, redirect, send_from_directory, make_
from flask_babel import gettext as _
from flask_login import login_user, logout_user, login_required, current_user
from sqlalchemy.exc import IntegrityError
from sqlalchemy.sql.expression import text, func, true, false, not_, and_, exists
from sqlalchemy.sql.expression import text, func, true, false, not_, and_, exists, or_
from werkzeug.exceptions import default_exceptions
from werkzeug.datastructures import Headers
from werkzeug.security import generate_password_hash, check_password_hash
@ -268,7 +268,7 @@ def before_request():
g.allow_upload = config.config_uploading
g.current_theme = config.config_theme
g.config_authors_max = config.config_authors_max
g.public_shelfes = ub.session.query(ub.Shelf).filter(ub.Shelf.is_public == 1).order_by(ub.Shelf.name).all()
g.shelves_access = ub.session.query(ub.Shelf).filter(or_(ub.Shelf.is_public == 1, ub.Shelf.user_id == current_user.id)).order_by(ub.Shelf.name).all()
if not config.db_configured and request.endpoint not in ('admin.basic_configuration', 'login') and '/static/' not in request.path:
return redirect(url_for('admin.basic_configuration'))