diff --git a/cps/opds.py b/cps/opds.py index b13b0570..c0ed6c20 100644 --- a/cps/opds.py +++ b/cps/opds.py @@ -31,7 +31,7 @@ from flask_babel import gettext as _ from sqlalchemy.sql.expression import func, text, or_, and_, true from sqlalchemy.exc import InvalidRequestError, OperationalError -from . import logger, config, db, calibre_db, ub, isoLanguages +from . import logger, config, db, calibre_db, ub, isoLanguages, constants from .usermanagement import requires_basic_auth_if_no_ano from .helper import get_download_link, get_book_cover from .pagination import Pagination @@ -94,6 +94,8 @@ def feed_letter_books(book_id): @opds.route("/opds/new") @requires_basic_auth_if_no_ano def feed_new(): + if not current_user.check_visibility(constants.SIDEBAR_RECENT): + abort(404) off = request.args.get("offset") or 0 entries, __, pagination = calibre_db.fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1), 0, db.Books, True, [db.Books.timestamp.desc()], @@ -104,6 +106,8 @@ def feed_new(): @opds.route("/opds/discover") @requires_basic_auth_if_no_ano def feed_discover(): + if not current_user.check_visibility(constants.SIDEBAR_RANDOM): + abort(404) query = calibre_db.generate_linked_query(config.config_read_column, db.Books) entries = query.filter(calibre_db.common_filters()).order_by(func.random()).limit(config.config_books_per_page) pagination = Pagination(1, config.config_books_per_page, int(config.config_books_per_page)) @@ -113,6 +117,8 @@ def feed_discover(): @opds.route("/opds/rated") @requires_basic_auth_if_no_ano def feed_best_rated(): + if not current_user.check_visibility(constants.SIDEBAR_RATED): + abort(404) off = request.args.get("offset") or 0 entries, __, pagination = calibre_db.fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1), 0, db.Books, db.Books.ratings.any(db.Ratings.rating > 9), @@ -124,6 +130,8 @@ def feed_best_rated(): @opds.route("/opds/hot") @requires_basic_auth_if_no_ano def feed_hot(): + if not current_user.check_visibility(constants.SIDEBAR_DOWNLOAD): + abort(404) off = request.args.get("offset") or 0 all_books = ub.session.query(ub.Downloads, func.count(ub.Downloads.book_id)).order_by( func.count(ub.Downloads.book_id).desc()).group_by(ub.Downloads.book_id) @@ -146,12 +154,16 @@ def feed_hot(): @opds.route("/opds/author") @requires_basic_auth_if_no_ano def feed_authorindex(): + if not current_user.check_visibility(constants.SIDEBAR_AUTHOR): + abort(404) return render_element_index(db.Authors.sort, db.books_authors_link, 'opds.feed_letter_author') @opds.route("/opds/author/letter/") @requires_basic_auth_if_no_ano def feed_letter_author(book_id): + if not current_user.check_visibility(constants.SIDEBAR_AUTHOR): + abort(404) off = request.args.get("offset") or 0 letter = true() if book_id == "00" else func.upper(db.Authors.sort).startswith(book_id) entries = calibre_db.session.query(db.Authors).join(db.books_authors_link).join(db.Books)\ @@ -173,6 +185,8 @@ def feed_author(book_id): @opds.route("/opds/publisher") @requires_basic_auth_if_no_ano def feed_publisherindex(): + if not current_user.check_visibility(constants.SIDEBAR_PUBLISHER): + abort(404) off = request.args.get("offset") or 0 entries = calibre_db.session.query(db.Publishers)\ .join(db.books_publishers_link)\ @@ -194,12 +208,16 @@ def feed_publisher(book_id): @opds.route("/opds/category") @requires_basic_auth_if_no_ano def feed_categoryindex(): + if not current_user.check_visibility(constants.SIDEBAR_CATEGORY): + abort(404) return render_element_index(db.Tags.name, db.books_tags_link, 'opds.feed_letter_category') @opds.route("/opds/category/letter/") @requires_basic_auth_if_no_ano def feed_letter_category(book_id): + if not current_user.check_visibility(constants.SIDEBAR_CATEGORY): + abort(404) off = request.args.get("offset") or 0 letter = true() if book_id == "00" else func.upper(db.Tags.name).startswith(book_id) entries = calibre_db.session.query(db.Tags)\ @@ -223,12 +241,16 @@ def feed_category(book_id): @opds.route("/opds/series") @requires_basic_auth_if_no_ano def feed_seriesindex(): + if not current_user.check_visibility(constants.SIDEBAR_SERIES): + abort(404) return render_element_index(db.Series.sort, db.books_series_link, 'opds.feed_letter_series') @opds.route("/opds/series/letter/") @requires_basic_auth_if_no_ano def feed_letter_series(book_id): + if not current_user.check_visibility(constants.SIDEBAR_SERIES): + abort(404) off = request.args.get("offset") or 0 letter = true() if book_id == "00" else func.upper(db.Series.sort).startswith(book_id) entries = calibre_db.session.query(db.Series)\ @@ -258,6 +280,8 @@ def feed_series(book_id): @opds.route("/opds/ratings") @requires_basic_auth_if_no_ano def feed_ratingindex(): + if not current_user.check_visibility(constants.SIDEBAR_RATING): + abort(404) off = request.args.get("offset") or 0 entries = calibre_db.session.query(db.Ratings, func.count('books_ratings_link.book').label('count'), (db.Ratings.rating / 2).label('name')) \ @@ -284,6 +308,8 @@ def feed_ratings(book_id): @opds.route("/opds/formats") @requires_basic_auth_if_no_ano def feed_formatindex(): + if not current_user.check_visibility(constants.SIDEBAR_FORMAT): + abort(404) off = request.args.get("offset") or 0 entries = calibre_db.session.query(db.Data).join(db.Books)\ .filter(calibre_db.common_filters()) \ @@ -291,7 +317,6 @@ def feed_formatindex(): .order_by(db.Data.format).all() pagination = Pagination((int(off) / (int(config.config_books_per_page)) + 1), config.config_books_per_page, len(entries)) - element = list() for entry in entries: element.append(FeedObject(entry.format, entry.format)) @@ -314,6 +339,8 @@ def feed_format(book_id): @opds.route("/opds/language/") @requires_basic_auth_if_no_ano def feed_languagesindex(): + if not current_user.check_visibility(constants.SIDEBAR_LANGUAGE): + abort(404) off = request.args.get("offset") or 0 if current_user.filter_language() == "all": languages = calibre_db.speaking_language() @@ -341,6 +368,8 @@ def feed_languages(book_id): @opds.route("/opds/shelfindex") @requires_basic_auth_if_no_ano def feed_shelfindex(): + if not (current_user.is_authenticated or g.allow_anonymous): + abort(404) off = request.args.get("offset") or 0 shelf = 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() @@ -353,7 +382,8 @@ def feed_shelfindex(): @opds.route("/opds/shelf/") @requires_basic_auth_if_no_ano def feed_shelf(book_id): - off = request.args.get("offset") or 0 + if not (current_user.is_authenticated or g.allow_anonymous): + abort(404) if current_user.is_anonymous: shelf = ub.session.query(ub.Shelf).filter(ub.Shelf.is_public == 1, ub.Shelf.id == book_id).first() @@ -436,6 +466,8 @@ def feed_get_cover(book_id): @opds.route("/opds/readbooks") @requires_basic_auth_if_no_ano def feed_read_books(): + if not (current_user.check_visibility(constants.SIDEBAR_READ_AND_UNREAD) and not current_user.is_anonymous): + return abort(403) off = request.args.get("offset") or 0 result, pagination = render_read_books(int(off) / (int(config.config_books_per_page)) + 1, True, True) return render_xml_template('feed.xml', entries=result, pagination=pagination) @@ -444,6 +476,8 @@ def feed_read_books(): @opds.route("/opds/unreadbooks") @requires_basic_auth_if_no_ano def feed_unread_books(): + if not (current_user.check_visibility(constants.SIDEBAR_READ_AND_UNREAD) and not current_user.is_anonymous): + return abort(403) off = request.args.get("offset") or 0 result, pagination = render_read_books(int(off) / (int(config.config_books_per_page)) + 1, False, True) return render_xml_template('feed.xml', entries=result, pagination=pagination) @@ -477,7 +511,7 @@ def feed_search(term): def render_xml_template(*args, **kwargs): # ToDo: return time in current timezone similar to %z currtime = datetime.datetime.now().strftime("%Y-%m-%dT%H:%M:%S+00:00") - xml = render_template(current_time=currtime, instance=config.config_calibre_web_title, *args, **kwargs) + xml = render_template(current_time=currtime, instance=config.config_calibre_web_title, constants=constants.sidebar_settings, *args, **kwargs) response = make_response(xml) response.headers["Content-Type"] = "application/atom+xml; charset=utf-8" return response