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:
parent
0c27ff11b9
commit
bab14a1fbf
65
cps/opds.py
65
cps/opds.py
@ -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>/")
|
||||
|
@ -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
|
||||
|
47
cps/shelf.py
47
cps/shelf.py
@ -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
|
||||
|
@ -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) }}"
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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'))
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user