diff --git a/cps/editbooks.py b/cps/editbooks.py index 0bb005fb..8e86132c 100644 --- a/cps/editbooks.py +++ b/cps/editbooks.py @@ -369,11 +369,11 @@ def upload_cover(request, book): requested_file = request.files['btn-upload-cover'] # check for empty request if requested_file.filename != '': - if helper.save_cover(requested_file, book.path) is True: + ret, message = helper.save_cover(requested_file, book.path) + if ret is True: return True else: - # ToDo Message not always coorect - flash(_(u"Cover is not a supported imageformat (jpg/png/webp), can't save"), category="error") + flash(message, category="error") return False return None diff --git a/cps/helper.py b/cps/helper.py index 3617843c..f82564b8 100644 --- a/cps/helper.py +++ b/cps/helper.py @@ -508,16 +508,16 @@ def save_cover_from_filestorage(filepath, saved_filename, img): os.makedirs(filepath) except OSError: log.error(u"Failed to create path for cover") - return False + return False, _(u"Failed to create path for cover") try: img.save(os.path.join(filepath, saved_filename)) except IOError: log.error(u"Cover-file is not a valid image file") - return False + return False, _(u"Cover-file is not a valid image file") except OSError: log.error(u"Failed to store cover-file") - return False - return True + return False, _(u"Failed to store cover-file") + return True, None # saves book cover to gdrive or locally @@ -527,7 +527,7 @@ def save_cover(img, book_path): if use_PIL: if content_type not in ('image/jpeg', 'image/png', 'image/webp'): log.error("Only jpg/jpeg/png/webp files are supported as coverfile") - return False + return False, _("Only jpg/jpeg/png/webp files are supported as coverfile") # convert to jpg because calibre only supports jpg if content_type in ('image/png', 'image/webp'): if hasattr(img,'stream'): @@ -541,17 +541,18 @@ def save_cover(img, book_path): else: if content_type not in ('image/jpeg'): log.error("Only jpg/jpeg files are supported as coverfile") - return False + return False, _("Only jpg/jpeg files are supported as coverfile") if config.config_use_google_drive: tmpDir = gettempdir() - if save_cover_from_filestorage(tmpDir, "uploaded_cover.jpg", img) is True: + ret, message = save_cover_from_filestorage(tmpDir, "uploaded_cover.jpg", img) + if ret is True: gd.uploadFileToEbooksFolder(os.path.join(book_path, 'cover.jpg'), os.path.join(tmpDir, "uploaded_cover.jpg")) log.info("Cover is saved on Google Drive") - return True + return True, None else: - return False + return False, message else: return save_cover_from_filestorage(os.path.join(config.config_calibre_dir, book_path), "cover.jpg", img) @@ -818,11 +819,11 @@ def get_download_link(book_id, book_format): book_format = book_format.split(".")[0] book = db.session.query(db.Books).filter(db.Books.id == book_id).filter(common_filters()).first() if book: - data = db.session.query(db.Data).filter(db.Data.book == book.id)\ + data1 = db.session.query(db.Data).filter(db.Data.book == book.id)\ .filter(db.Data.format == book_format.upper()).first() else: abort(404) - if data: + if data1: # collect downloaded books only for registered user and not for anonymous user if current_user.is_authenticated: ub.update_download(book_id, int(current_user.id)) @@ -834,7 +835,7 @@ def get_download_link(book_id, book_format): headers["Content-Type"] = mimetypes.types_map.get('.' + book_format, "application/octet-stream") headers["Content-Disposition"] = "attachment; filename=%s.%s; filename*=UTF-8''%s.%s" % ( quote(file_name.encode('utf-8')), book_format, quote(file_name.encode('utf-8')), book_format) - return do_download_file(book, book_format, data, headers) + return do_download_file(book, book_format, data1, headers) else: abort(404) diff --git a/cps/kobo.py b/cps/kobo.py index 15a17022..9830f1c2 100644 --- a/cps/kobo.py +++ b/cps/kobo.py @@ -214,29 +214,19 @@ def HandleMetadataRequest(book_uuid): def get_download_url_for_book(book, book_format): if not current_app.wsgi_app.is_proxied: - if request.environ['SERVER_NAME'] != '::': - return "{url_scheme}://{url_base}:{url_port}/download/{book_id}/{book_format}".format( - url_scheme=request.environ['wsgi.url_scheme'], - url_base=request.environ['SERVER_NAME'], - url_port=config.config_port, - book_id=book.id, - book_format=book_format.lower() - ) - else: - return "{url_scheme}://{url_base}:{url_port}/download/{book_id}/{book_format}".format( - url_scheme=request.environ['wsgi.url_scheme'], - url_base=request.host, # ToDo: both server ?? - url_port=config.config_port, - book_id=book.id, - book_format=book_format.lower() - ) - else: - return url_for( - "web.download_link", + return "{url_scheme}://{url_base}:{url_port}/download/{book_id}/{book_format}".format( + url_scheme=request.scheme, + url_base=request.host, + url_port=config.config_port, book_id=book.id, - book_format=book_format.lower(), - _external=True, + book_format=book_format.lower() ) + return url_for( + "web.download_link", + book_id=book.id, + book_format=book_format.lower(), + _external=True, + ) def create_book_entitlement(book): @@ -466,15 +456,11 @@ def HandleInitRequest(): if not current_app.wsgi_app.is_proxied: log.debug('Kobo: Received unproxied request, changed request port to server port') - if request.environ['SERVER_NAME'] != '::': - calibre_web_url = "{url_scheme}://{url_base}:{url_port}".format( - url_scheme=request.environ['wsgi.url_scheme'], - url_base=request.environ['SERVER_NAME'], - url_port=config.config_port - ) - else: - log.debug('Kobo: Received unproxied request, on IPV6 host') - calibre_web_url = url_for("web.index", _external=True).strip("/") + calibre_web_url = "{url_scheme}://{url_base}:{url_port}".format( + url_scheme=request.scheme, + url_base=request.host, + url_port=config.config_port + ) else: calibre_web_url = url_for("web.index", _external=True).strip("/") diff --git a/cps/opds.py b/cps/opds.py index 72ae693c..f76d5dc0 100644 --- a/cps/opds.py +++ b/cps/opds.py @@ -56,6 +56,20 @@ def requires_basic_auth_if_no_ano(f): return decorated +class FeedObject(): + def __init__(self,rating_id , rating_name): + self.rating_id = rating_id + self.rating_name = rating_name + + @property + def id(self): + return self.rating_id + + @property + def name(self): + return self.rating_name + + @opds.route("/opds/") @opds.route("/opds") @requires_basic_auth_if_no_ano @@ -214,6 +228,31 @@ def feed_series(book_id): 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) +@opds.route("/opds/ratings") +@requires_basic_auth_if_no_ano +def feed_ratingindex(): + off = request.args.get("offset") or 0 + entries = db.session.query(db.Ratings, func.count('books_ratings_link.book').label('count'), + (db.Ratings.rating / 2).label('name')) \ + .join(db.books_ratings_link).join(db.Books).filter(common_filters()) \ + .group_by(text('books_ratings_link.rating')).order_by(db.Ratings.rating).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[0].id, "{} Stars".format(entry.name))) + return render_xml_template('feed.xml', listelements=element, folder='opds.feed_ratings', pagination=pagination) + +@opds.route("/opds/ratings/") +@requires_basic_auth_if_no_ano +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) + + @opds.route("/opds/formats") @requires_basic_auth_if_no_ano def feed_formatindex(): @@ -222,10 +261,11 @@ def feed_formatindex(): .group_by(db.Data.format).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: - entry.name = entry.format - entry.id = entry.format - return render_xml_template('feed.xml', listelements=entries, folder='opds.feed_format', pagination=pagination) + element.append(FeedObject(entry.format, entry.format)) + return render_xml_template('feed.xml', listelements=element, folder='opds.feed_format', pagination=pagination) @opds.route("/opds/formats/") @@ -265,16 +305,9 @@ 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()]) - '''for entry in entries: - for index in range(0, len(entry.languages)): - try: - entry.languages[index].language_name = LC.parse(entry.languages[index].lang_code).get_language_name( - get_locale()) - except UnknownLocaleError: - entry.languages[index].language_name = _( - isoLanguages.get(part3=entry.languages[index].lang_code).name)''' return render_xml_template('feed.xml', entries=entries, pagination=pagination) + @opds.route("/opds/shelfindex", defaults={'public': 0}) @opds.route("/opds/shelfindex/") @requires_basic_auth_if_no_ano @@ -319,11 +352,11 @@ def feed_shelf(book_id): @requires_basic_auth_if_no_ano @download_required def opds_download_link(book_id, book_format): - return get_download_link(book_id,book_format) + return get_download_link(book_id,book_format.lower()) @opds.route("/ajax/book//") -@opds.route("/ajax/book/") +@opds.route("/ajax/book/",defaults={'library': ""}) @requires_basic_auth_if_no_ano def get_metadata_calibre_companion(uuid, library): entry = db.session.query(db.Books).filter(db.Books.uuid.like("%" + uuid + "%")).first() diff --git a/cps/templates/index.xml b/cps/templates/index.xml index c99388a3..8b5f6344 100644 --- a/cps/templates/index.xml +++ b/cps/templates/index.xml @@ -92,6 +92,14 @@ {{ current_time }} {{_('Books ordered by Languages')}} + + {{_('Ratings')}} + + {{url_for('opds.feed_ratingindex')}} + {{ current_time }} + {{_('Books ordered by Rating')}} + + {{_('File formats')}} diff --git a/cps/templates/osd.xml b/cps/templates/osd.xml index b1077890..674303c2 100644 --- a/cps/templates/osd.xml +++ b/cps/templates/osd.xml @@ -6,7 +6,7 @@ Janeczku https://github.com/janeczku/calibre-web + template="{{url_for('opds.feed_cc_search')}}/{searchTerms}"/> open diff --git a/cps/web.py b/cps/web.py index 35cc5d97..8f273faf 100644 --- a/cps/web.py +++ b/cps/web.py @@ -1044,7 +1044,7 @@ def serve_book(book_id, book_format, anyname): @login_required_if_no_ano @download_required def download_link(book_id, book_format): - return get_download_link(book_id, book_format) + return get_download_link(book_id, book_format.lower()) @web.route('/send///')