diff --git a/.gitignore b/.gitignore index 614e9936..14da8a03 100644 --- a/.gitignore +++ b/.gitignore @@ -23,6 +23,7 @@ vendor/ # calibre-web *.db *.log +cps/cache .idea/ *.bak diff --git a/README.md b/README.md index ea9d9ba0..267f21ef 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # About -Calibre-Web is a web app providing a clean interface for browsing, reading and downloading eBooks using an existing [Calibre](https://calibre-ebook.com) database. +Calibre-Web is a web app providing a clean interface for browsing, reading and downloading eBooks using a valid [Calibre](https://calibre-ebook.com) database. [![GitHub License](https://img.shields.io/github/license/janeczku/calibre-web?style=flat-square)](https://github.com/janeczku/calibre-web/blob/master/LICENSE) [![GitHub commit activity](https://img.shields.io/github/commit-activity/w/janeczku/calibre-web?logo=github&style=flat-square&label=commits)]() @@ -40,23 +40,20 @@ Calibre-Web is a web app providing a clean interface for browsing, reading and d ## Installation #### Installation via pip (recommended) -1. Install calibre web via pip with the command `pip install calibreweb` (Depending on your OS and or distro the command could also be `pip3`). -2. Optional features can also be installed via pip, please refer to [this page](https://github.com/janeczku/calibre-web/wiki/Dependencies-in-Calibre-Web-Linux-Windows) for details -3. Calibre-Web can be started afterwards by typing `cps` or `python3 -m cps` +1. To avoid problems with already installed python dependencies, it's recommended to create a virtual environment for Calibre-Web +2. Install Calibre-Web via pip with the command `pip install calibreweb` (Depending on your OS and or distro the command could also be `pip3`). +3. Optional features can also be installed via pip, please refer to [this page](https://github.com/janeczku/calibre-web/wiki/Dependencies-in-Calibre-Web-Linux-Windows) for details +4. Calibre-Web can be started afterwards by typing `cps` -#### Manual installation -1. Install dependencies by running `pip3 install --target vendor -r requirements.txt` (python3.x). Alternativly set up a python virtual environment. -2. Execute the command: `python3 cps.py` (or `nohup python3 cps.py` - recommended if you want to exit the terminal window) - -Issues with Ubuntu: -Please note that running the above install command can fail on some versions of Ubuntu, saying `"can't combine user with prefix"`. This is a [known bug](https://github.com/pypa/pip/issues/3826) and can be remedied by using the command `pip install --system --target vendor -r requirements.txt` instead. +In the Wiki there are also examples for: a [manual installation](https://github.com/janeczku/calibre-web/wiki/Manual-installation), [installation on Linux Mint](https://github.com/janeczku/calibre-web/wiki/How-To:Install-Calibre-Web-in-Linux-Mint-19-or-20), [installation on a Cloud Provider](https://github.com/janeczku/calibre-web/wiki/How-To:-Install-Calibre-Web-on-a-Cloud-Provider). ## Quick start -Point your browser to `http://localhost:8083` or `http://localhost:8083/opds` for the OPDS catalog -Set `Location of Calibre database` to the path of the folder where your Calibre library (metadata.db) lives, push "submit" button\ -Optionally a Google Drive can be used to host the calibre library [-> Using Google Drive integration](https://github.com/janeczku/calibre-web/wiki/Configuration#using-google-drive-integration) -Go to Login page +Point your browser to `http://localhost:8083` or `http://localhost:8083/opds` for the OPDS catalog \ +Login with default admin login \ +Set `Location of Calibre database` to the path of the folder where your Calibre library (metadata.db) lives, push "submit" button \ +Optionally a Google Drive can be used to host the calibre library [-> Using Google Drive integration](https://github.com/janeczku/calibre-web/wiki/Configuration#using-google-drive-integration) \ +Afterwards you can configure your Calibre-Web instance ([Basic Configuration](https://github.com/janeczku/calibre-web/wiki/Configuration#basic-configuration) and [UI Configuration](https://github.com/janeczku/calibre-web/wiki/Configuration#ui-configuration) on admin page) #### Default admin login: *Username:* admin\ @@ -71,7 +68,7 @@ Optionally, to enable on-the-fly conversion from one ebook format to another whe [Download and install](https://calibre-ebook.com/download) the Calibre desktop program for your platform and enter the folder including program name (normally /opt/calibre/ebook-convert, or C:\Program Files\calibre\ebook-convert.exe) in the field "calibre's converter tool" on the setup page. -[Download](https://github.com/pgaskin/kepubify/releases/latest) Kepubify tool for your platform and place the binary starting with `kepubify` in Linux: `\opt\kepubify` Windows: `C:\Program Files\kepubify`. +[Download](https://github.com/pgaskin/kepubify/releases/latest) Kepubify tool for your platform and place the binary starting with `kepubify` in Linux: `/opt/kepubify` Windows: `C:\Program Files\kepubify`. ## Docker Images diff --git a/SECURITY.md b/SECURITY.md index 262e66e2..1b93b5f9 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -24,16 +24,22 @@ To receive fixes for security vulnerabilities it is required to always upgrade t | V 0.6.13 | JavaScript could get executed in the shelf title || | V 0.6.13 | Login with the old session cookie after logout. Thanks to @ibarrionuevo || | V 0.6.14 | CSRF was possible. Thanks to @mik317 and Hagai Wechsler (WhiteSource) |CVE-2021-25965| -| V 0.6.14 | Migrated some routes to POST-requests (CSRF protection). Thanks to @scara31 || -| V 0.6.15 | Fix for "javascript:" script links in identifier. Thanks to @scara31 || +| V 0.6.14 | Migrated some routes to POST-requests (CSRF protection). Thanks to @scara31 |CVE-2021-4164| +| V 0.6.15 | Fix for "javascript:" script links in identifier. Thanks to @scara31 |CVE-2021-4170| | V 0.6.15 | Cross-Site Scripting vulnerability on uploaded cover file names. Thanks to @ibarrionuevo || | V 0.6.15 | Creating public shelfs is now denied if user is missing the edit public shelf right. Thanks to @ibarrionuevo || | V 0.6.15 | Changed error message in case of trying to delete a shelf unauthorized. Thanks to @ibarrionuevo || -| V 0.6.16 | JavaScript could get executed on authors page. Thanks to @alicaz || -| V 0.6.16 | Localhost can no longer be used to upload covers. Thanks to @scara31 || -| V 0.6.16 | Another case where public shelfs could be created without permission is prevented. Thanks to @nhiephon || +| V 0.6.16 | JavaScript could get executed on authors page. Thanks to @alicaz |CVE-2022-0352| +| V 0.6.16 | Localhost can no longer be used to upload covers. Thanks to @scara31 |CVE-2022-0339| +| V 0.6.16 | Another case where public shelfs could be created without permission is prevented. Thanks to @nhiephon |CVE-2022-0273| +| V 0.6.16 | It's prevented to get the name of a private shelfs. Thanks to @nhiephon |CVE-2022-0405| +| V 0.6.17 | The SSRF Protection can no longer be bypassed via an HTTP redirect. Thanks to @416e6e61 |CVE-2022-0767| +| V 0.6.17 | The SSRF Protection can no longer be bypassed via 0.0.0.0 and it's ipv6 equivalent. Thanks to @r0hanSH |CVE-2022-0766| +| V 0.6.18 | Possible SQL Injection is prevented in user table Thanks to Iman Sharafaldin (Forward Security) || +| V 0.6.18 | The SSRF protection no longer can be bypassed by IPV6/IPV4 embedding. Thanks to @416e6e61 |CVE-2022-0939| +| V 0.6.18 | The SSRF protection no longer can be bypassed to connect to other servers in the local network. Thanks to @michaellrowley |CVE-2022-0990| -## Staement regarding Log4j (CVE-2021-44228 and related) +## Statement regarding Log4j (CVE-2021-44228 and related) Calibre-web is not affected by bugs related to Log4j. Calibre-Web is a python program, therefore not using Java, and not using the Java logging feature log4j. diff --git a/cps.py b/cps.py index 277da288..55d9339c 100755 --- a/cps.py +++ b/cps.py @@ -16,11 +16,6 @@ # # You should have received a copy of the GNU General Public License # along with this program. If not, see . -try: - from gevent import monkey - monkey.patch_all() -except ImportError: - pass import sys import os @@ -40,10 +35,11 @@ from cps.about import about from cps.shelf import shelf from cps.admin import admi from cps.gdrive import gdrive -from cps.editbooks import editbook +from cps.editbooks import EditBook from cps.remotelogin import remotelogin from cps.search_metadata import meta from cps.error_handler import init_errorhandler +from cps.schedule import register_scheduled_tasks, register_startup_tasks try: from cps.kobo import kobo, get_kobo_activated @@ -73,12 +69,17 @@ def main(): app.register_blueprint(remotelogin) app.register_blueprint(meta) app.register_blueprint(gdrive) - app.register_blueprint(editbook) + app.register_blueprint(EditBook) if kobo_available: app.register_blueprint(kobo) app.register_blueprint(kobo_auth) if oauth_available: app.register_blueprint(oauth) + + # Register scheduled tasks + register_scheduled_tasks() # ToDo only reconnect if reconnect is enabled + register_startup_tasks() + success = web_server.start() sys.exit(0 if success else 1) diff --git a/cps/__init__.py b/cps/__init__.py index 2dfad699..68947905 100644 --- a/cps/__init__.py +++ b/cps/__init__.py @@ -91,7 +91,7 @@ if wtf_present: else: csrf = None -ub.init_db(cli.settingspath) +ub.init_db(cli.settings_path) # pylint: disable=no-member config = config_sql.load_configuration(ub.session) @@ -106,7 +106,7 @@ log = logger.create() from . import services db.CalibreDB.update_config(config) -db.CalibreDB.setup_db(config.config_calibre_dir, cli.settingspath) +db.CalibreDB.setup_db(config.config_calibre_dir, cli.settings_path) calibre_db = db.CalibreDB() @@ -156,9 +156,10 @@ def create_app(): services.goodreads_support.connect(config.config_goodreads_api_key, config.config_goodreads_api_secret, config.config_use_goodreads) - config.store_calibre_uuid(calibre_db, db.Library_Id) + config.store_calibre_uuid(calibre_db, db.LibraryId) return app + @babel.localeselector def get_locale(): # if a user is logged in, use the locale from the user settings @@ -178,12 +179,6 @@ def get_locale(): return negotiate_locale(preferred or ['en'], _BABEL_TRANSLATIONS) -@babel.timezoneselector -def get_timezone(): - user = getattr(g, 'user', None) - return user.timezone if user else None - - from .updater import Updater updater_thread = Updater() diff --git a/cps/about.py b/cps/about.py index 8f2bf715..92dc41aa 100644 --- a/cps/about.py +++ b/cps/about.py @@ -69,9 +69,9 @@ _VERSIONS.update(uploader.get_versions(False)) def collect_stats(): - _VERSIONS['ebook converter'] = _(converter.get_calibre_version()) - _VERSIONS['unrar'] = _(converter.get_unrar_version()) - _VERSIONS['kepubify'] = _(converter.get_kepubify_version()) + _VERSIONS['ebook converter'] = converter.get_calibre_version() + _VERSIONS['unrar'] = converter.get_unrar_version() + _VERSIONS['kepubify'] = converter.get_kepubify_version() return _VERSIONS diff --git a/cps/admin.py b/cps/admin.py index 4876d421..73442ef2 100644 --- a/cps/admin.py +++ b/cps/admin.py @@ -24,12 +24,12 @@ import os import re import base64 import json -import time import operator -from datetime import datetime, timedelta +from datetime import datetime, timedelta, time +from functools import wraps -from babel import Locale as LC -from babel.dates import format_datetime +from babel import Locale +from babel.dates import format_datetime, format_time, format_timedelta from flask import Blueprint, flash, redirect, url_for, abort, request, make_response, send_from_directory, g, Response from flask_login import login_required, current_user, logout_user, confirm_login from flask_babel import gettext as _ @@ -40,14 +40,15 @@ from sqlalchemy.exc import IntegrityError, OperationalError, InvalidRequestError from sqlalchemy.sql.expression import func, or_, text from . import constants, logger, helper, services, cli -from . import db, calibre_db, ub, web_server, get_locale, config, updater_thread, babel, gdriveutils, kobo_sync_status +from . import db, calibre_db, ub, web_server, get_locale, config, updater_thread, babel, gdriveutils, \ + kobo_sync_status, schedule from .helper import check_valid_domain, send_test_mail, reset_password, generate_password_hash, check_email, \ - valid_email, check_username + valid_email, check_username, update_thumbnail_cache from .gdriveutils import is_gdrive_ready, gdrive_support from .render_template import render_title_template, get_sidebar_config +from .services.worker import WorkerThread from . import debug_info, _BABEL_TRANSLATIONS -from functools import wraps log = logger.create() @@ -56,7 +57,8 @@ feature_support = { 'goodreads': bool(services.goodreads_support), 'kobo': bool(services.kobo), 'updater': constants.UPDATER_AVAILABLE, - 'gmail': bool(services.gmail) + 'gmail': bool(services.gmail), + 'scheduler': schedule.use_APScheduler } try: @@ -159,7 +161,7 @@ def shutdown(): # needed for docker applications, as changes on metadata.db from host are not visible to application @admi.route("/reconnect", methods=['GET']) def reconnect(): - if cli.args.r: + if cli.reconnect_enable: calibre_db.reconnect_db(config, ub.app_DB_path) return json.dumps({}) else: @@ -167,10 +169,22 @@ def reconnect(): abort(404) +@admi.route("/ajax/updateThumbnails", methods=['POST']) +@admin_required +@login_required +def update_thumbnails(): + content = config.get_scheduled_task_settings() + if content['schedule_generate_book_covers']: + log.info("Update of Cover cache requested") + update_thumbnail_cache() + return "" + + @admi.route("/admin/view") @login_required @admin_required def admin(): + locale = get_locale() version = updater_thread.get_current_version_info() if version is False: commit = _(u'Unknown') @@ -185,15 +199,19 @@ def admin(): form_date -= timedelta(hours=int(commit[20:22]), minutes=int(commit[23:])) elif commit[19] == '-': form_date += timedelta(hours=int(commit[20:22]), minutes=int(commit[23:])) - commit = format_datetime(form_date - tz, format='short', locale=get_locale()) + commit = format_datetime(form_date - tz, format='short', locale=locale) else: commit = version['version'] - allUser = ub.session.query(ub.User).all() + all_user = ub.session.query(ub.User).all() email_settings = config.get_mail_settings() - kobo_support = feature_support['kobo'] and config.config_kobo_sync - return render_title_template("admin.html", allUser=allUser, email=email_settings, config=config, commit=commit, - feature_support=feature_support, kobo_support=kobo_support, + schedule_time = format_time(time(hour=config.schedule_start_time), format="short", locale=locale) + t = timedelta(hours=config.schedule_duration // 60, minutes=config.schedule_duration % 60) + schedule_duration = format_timedelta(t, format="short", threshold=.99, locale=locale) + + return render_title_template("admin.html", allUser=all_user, email=email_settings, config=config, commit=commit, + feature_support=feature_support, schedule_time=schedule_time, + schedule_duration=schedule_duration, title=_(u"Admin page"), page="admin") @@ -242,12 +260,12 @@ def calibreweb_alive(): @login_required @admin_required def view_configuration(): - read_column = calibre_db.session.query(db.Custom_Columns)\ - .filter(and_(db.Custom_Columns.datatype == 'bool', db.Custom_Columns.mark_for_delete == 0)).all() - restrict_columns = calibre_db.session.query(db.Custom_Columns)\ - .filter(and_(db.Custom_Columns.datatype == 'text', db.Custom_Columns.mark_for_delete == 0)).all() + read_column = calibre_db.session.query(db.CustomColumns)\ + .filter(and_(db.CustomColumns.datatype == 'bool', db.CustomColumns.mark_for_delete == 0)).all() + restrict_columns = calibre_db.session.query(db.CustomColumns)\ + .filter(and_(db.CustomColumns.datatype == 'text', db.CustomColumns.mark_for_delete == 0)).all() languages = calibre_db.speaking_language() - translations = [LC('en')] + babel.list_translations() + translations = [Locale('en')] + babel.list_translations() return render_title_template("config_view_edit.html", conf=config, readColumns=read_column, restrictColumns=restrict_columns, languages=languages, @@ -261,8 +279,8 @@ def view_configuration(): def edit_user_table(): visibility = current_user.view_settings.get('useredit', {}) languages = calibre_db.speaking_language() - translations = babel.list_translations() + [LC('en')] - allUser = ub.session.query(ub.User) + translations = babel.list_translations() + [Locale('en')] + all_user = ub.session.query(ub.User) tags = calibre_db.session.query(db.Tags)\ .join(db.books_tags_link)\ .join(db.Books)\ @@ -274,10 +292,10 @@ def edit_user_table(): else: custom_values = [] if not config.config_anonbrowse: - allUser = allUser.filter(ub.User.role.op('&')(constants.ROLE_ANONYMOUS) != constants.ROLE_ANONYMOUS) + all_user = all_user.filter(ub.User.role.op('&')(constants.ROLE_ANONYMOUS) != constants.ROLE_ANONYMOUS) kobo_support = feature_support['kobo'] and config.config_kobo_sync return render_title_template("user_table.html", - users=allUser.all(), + users=all_user.all(), tags=tags, custom_values=custom_values, translations=translations, @@ -298,10 +316,13 @@ def list_users(): limit = int(request.args.get("limit") or 10) search = request.args.get("search") sort = request.args.get("sort", "id") - order = request.args.get("order", "").lower() state = None if sort == "state": state = json.loads(request.args.get("state", "[]")) + else: + if sort not in ub.User.__table__.columns.keys(): + sort = "id" + order = request.args.get("order", "").lower() if sort != "state" and order: order = text(sort + " " + order) @@ -329,7 +350,7 @@ def list_users(): if user.default_language == "all": user.default = _("All") else: - user.default = LC.parse(user.default_language).get_language_name(get_locale()) + user.default = Locale.parse(user.default_language).get_language_name(get_locale()) table_entries = {'totalNotFiltered': total_count, 'total': filtered_count, "rows": users} js_list = json.dumps(table_entries, cls=db.AlchemyEncoder) @@ -377,7 +398,7 @@ def delete_user(): @login_required @admin_required def table_get_locale(): - locale = babel.list_translations() + [LC('en')] + locale = babel.list_translations() + [Locale('en')] ret = list() current_locale = get_locale() for loc in locale: @@ -441,7 +462,7 @@ def edit_list_user(param): elif param.endswith('role'): value = int(vals['field_index']) if user.name == "Guest" and value in \ - [constants.ROLE_ADMIN, constants.ROLE_PASSWD, constants.ROLE_EDIT_SHELFS]: + [constants.ROLE_ADMIN, constants.ROLE_PASSWD, constants.ROLE_EDIT_SHELFS]: raise Exception(_("Guest can't have this role")) # check for valid value, last on checks for power of 2 value if value > 0 and value <= constants.ROLE_VIEWER and (value & value-1 == 0 or value == 1): @@ -496,7 +517,7 @@ def edit_list_user(param): else: return _("Parameter not found"), 400 except Exception as ex: - log.debug_or_exception(ex) + log.error_or_exception(ex) return str(ex), 400 ub.session_commit() return "" @@ -521,16 +542,16 @@ def update_table_settings(): def check_valid_read_column(column): if column != "0": - if not calibre_db.session.query(db.Custom_Columns).filter(db.Custom_Columns.id == column) \ - .filter(and_(db.Custom_Columns.datatype == 'bool', db.Custom_Columns.mark_for_delete == 0)).all(): + if not calibre_db.session.query(db.CustomColumns).filter(db.CustomColumns.id == column) \ + .filter(and_(db.CustomColumns.datatype == 'bool', db.CustomColumns.mark_for_delete == 0)).all(): return False return True def check_valid_restricted_column(column): if column != "0": - if not calibre_db.session.query(db.Custom_Columns).filter(db.Custom_Columns.id == column) \ - .filter(and_(db.Custom_Columns.datatype == 'text', db.Custom_Columns.mark_for_delete == 0)).all(): + if not calibre_db.session.query(db.CustomColumns).filter(db.CustomColumns.id == column) \ + .filter(and_(db.CustomColumns.datatype == 'text', db.CustomColumns.mark_for_delete == 0)).all(): return False return True @@ -607,6 +628,8 @@ def load_dialogtexts(element_id): texts["main"] = _('Are you sure you want to change shelf sync behavior for the selected user(s)?') elif element_id == "db_submit": texts["main"] = _('Are you sure you want to change Calibre library location?') + elif element_id == "admin_refresh_cover_cache": + texts["main"] = _('Calibre-Web will search for updated Covers and update Cover Thumbnails, this may take a while?') elif element_id == "btnfullsync": texts["main"] = _("Are you sure you want delete Calibre-Web's sync database " "to force a full sync with your Kobo Reader?") @@ -860,10 +883,10 @@ def delete_restriction(res_type, user_id): usr = current_user if element['id'].startswith('a'): usr.allowed_tags = restriction_deletion(element, usr.list_allowed_tags) - ub.session_commit("Deleted allowed tags of user {}: {}".format(usr.name, usr.list_allowed_tags)) + ub.session_commit("Deleted allowed tags of user {}: {}".format(usr.name, element['Element'])) elif element['id'].startswith('d'): usr.denied_tags = restriction_deletion(element, usr.list_denied_tags) - ub.session_commit("Deleted denied tags of user {}: {}".format(usr.name, usr.list_allowed_tags)) + ub.session_commit("Deleted denied tag of user {}: {}".format(usr.name, element['Element'])) elif res_type == 3: # Columns per user if isinstance(user_id, int): usr = ub.session.query(ub.User).filter(ub.User.id == int(user_id)).first() @@ -872,12 +895,12 @@ def delete_restriction(res_type, user_id): if element['id'].startswith('a'): usr.allowed_column_value = restriction_deletion(element, usr.list_allowed_column_values) ub.session_commit("Deleted allowed columns of user {}: {}".format(usr.name, - usr.list_allowed_column_values)) + usr.list_allowed_column_values())) elif element['id'].startswith('d'): usr.denied_column_value = restriction_deletion(element, usr.list_denied_column_values) ub.session_commit("Deleted denied columns of user {}: {}".format(usr.name, - usr.list_denied_column_values)) + usr.list_denied_column_values())) return "" @@ -1075,12 +1098,12 @@ def _configuration_oauth_helper(to_save): reboot_required = False for element in oauthblueprints: if to_save["config_" + str(element['id']) + "_oauth_client_id"] != element['oauth_client_id'] \ - or to_save["config_" + str(element['id']) + "_oauth_client_secret"] != element['oauth_client_secret']: + or to_save["config_" + str(element['id']) + "_oauth_client_secret"] != element['oauth_client_secret']: reboot_required = True element['oauth_client_id'] = to_save["config_" + str(element['id']) + "_oauth_client_id"] element['oauth_client_secret'] = to_save["config_" + str(element['id']) + "_oauth_client_secret"] if to_save["config_" + str(element['id']) + "_oauth_client_id"] \ - and to_save["config_" + str(element['id']) + "_oauth_client_secret"]: + and to_save["config_" + str(element['id']) + "_oauth_client_secret"]: active_oauths += 1 element["active"] = 1 else: @@ -1133,7 +1156,7 @@ def _configuration_ldap_helper(to_save): if not config.config_ldap_provider_url \ or not config.config_ldap_port \ or not config.config_ldap_dn \ - or not config.config_ldap_user_object: + or not config.config_ldap_user_object: return reboot_required, _configuration_result(_('Please Enter a LDAP Provider, ' 'Port, DN and User Object Identifier')) @@ -1208,15 +1231,16 @@ def _db_configuration_update_helper(): '', to_save['config_calibre_dir'], flags=re.IGNORECASE) + db_valid = False try: db_change, db_valid = _db_simulate_change() # gdrive_error drive setup gdrive_error = _configuration_gdrive_helper(to_save) - except (OperationalError, InvalidRequestError): + except (OperationalError, InvalidRequestError) as e: ub.session.rollback() - log.error("Settings DB is not Writeable") - _db_configuration_result(_("Settings DB is not Writeable"), gdrive_error) + log.error_or_exception("Settings Database error: {}".format(e)) + _db_configuration_result(_(u"Database error: %(error)s.", error=e.orig), gdrive_error) try: metadata_db = os.path.join(to_save['config_calibre_dir'], "metadata.db") if config.config_use_google_drive and is_gdrive_ready() and not os.path.exists(metadata_db): @@ -1226,14 +1250,14 @@ def _db_configuration_update_helper(): return _db_configuration_result('{}'.format(ex), gdrive_error) if db_change or not db_valid or not config.db_configured \ - or config.config_calibre_dir != to_save["config_calibre_dir"]: + or config.config_calibre_dir != to_save["config_calibre_dir"]: if not calibre_db.setup_db(to_save['config_calibre_dir'], ub.app_DB_path): return _db_configuration_result(_('DB Location is not Valid, Please Enter Correct Path'), gdrive_error) - config.store_calibre_uuid(calibre_db, db.Library_Id) + config.store_calibre_uuid(calibre_db, db.LibraryId) # if db changed -> delete shelfs, delete download books, delete read books, kobo sync... if db_change: - log.info("Calibre Database changed, delete all Calibre-Web info related to old Database") + log.info("Calibre Database changed, all Calibre-Web info related to old Database gets deleted") ub.session.query(ub.Downloads).delete() ub.session.query(ub.ArchivedBook).delete() ub.session.query(ub.ReadBook).delete() @@ -1242,6 +1266,7 @@ def _db_configuration_update_helper(): ub.session.query(ub.KoboReadingState).delete() ub.session.query(ub.KoboStatistics).delete() ub.session.query(ub.KoboSyncedBooks).delete() + helper.delete_thumbnail_cache() ub.session_commit() _config_string(to_save, "config_calibre_dir") calibre_db.update_config(config) @@ -1269,7 +1294,7 @@ def _configuration_update_helper(): _config_checkbox_int(to_save, "config_unicode_filename") # Reboot on config_anonbrowse with enabled ldap, as decoraters are changed in this case reboot_required |= (_config_checkbox_int(to_save, "config_anonbrowse") - and config.config_login_type == constants.LOGIN_LDAP) + and config.config_login_type == constants.LOGIN_LDAP) _config_checkbox_int(to_save, "config_public_reg") _config_checkbox_int(to_save, "config_register_email") reboot_required |= _config_checkbox_int(to_save, "config_kobo_sync") @@ -1329,10 +1354,10 @@ def _configuration_update_helper(): unrar_status = helper.check_unrar(config.config_rarfile_location) if unrar_status: return _configuration_result(unrar_status) - except (OperationalError, InvalidRequestError): + except (OperationalError, InvalidRequestError) as e: ub.session.rollback() - log.error("Settings DB is not Writeable") - _configuration_result(_("Settings DB is not Writeable")) + log.error_or_exception("Settings Database error: {}".format(e)) + _configuration_result(_(u"Database error: %(error)s.", error=e.orig)) config.save() if reboot_required: @@ -1427,10 +1452,10 @@ def _handle_new_user(to_save, content, languages, translations, kobo_support): ub.session.rollback() log.error("Found an existing account for {} or {}".format(content.name, content.email)) flash(_("Found an existing account for this e-mail address or name."), category="error") - except OperationalError: + except OperationalError as e: ub.session.rollback() - log.error("Settings DB is not Writeable") - flash(_("Settings DB is not Writeable"), category="error") + log.error_or_exception("Settings Database error: {}".format(e)) + flash(_(u"Database error: %(error)s.", error=e.orig), category="error") def _delete_user(content): @@ -1489,7 +1514,7 @@ def _handle_edit_user(to_save, content, languages, translations, kobo_support): content.role &= ~constants.ROLE_ANONYMOUS val = [int(k[5:]) for k in to_save if k.startswith('show_')] - sidebar = get_sidebar_config() + sidebar, __ = get_sidebar_config() for element in sidebar: value = element['visibility'] if value in val and not content.check_visibility(value): @@ -1544,10 +1569,10 @@ def _handle_edit_user(to_save, content, languages, translations, kobo_support): ub.session.rollback() log.error("An unknown error occurred while changing user: {}".format(str(ex))) flash(_(u"An unknown error occurred. Please try again later."), category="error") - except OperationalError: + except OperationalError as e: ub.session.rollback() - log.error("Settings DB is not Writeable") - flash(_("Settings DB is not Writeable"), category="error") + log.error_or_exception("Settings Database error: {}".format(e)) + flash(_(u"Database error: %(error)s.", error=e.orig), category="error") return "" @@ -1557,7 +1582,7 @@ def _handle_edit_user(to_save, content, languages, translations, kobo_support): def new_user(): content = ub.User() languages = calibre_db.speaking_language() - translations = [LC('en')] + babel.list_translations() + translations = [Locale('en')] + babel.list_translations() kobo_support = feature_support['kobo'] and config.config_kobo_sync if request.method == "POST": to_save = request.form.to_dict() @@ -1613,10 +1638,10 @@ def update_mailsettings(): _config_int(to_save, "mail_size", lambda y: int(y)*1024*1024) try: config.save() - except (OperationalError, InvalidRequestError): + except (OperationalError, InvalidRequestError) as e: ub.session.rollback() - log.error("Settings DB is not Writeable") - flash(_("Settings DB is not Writeable"), category="error") + log.error_or_exception("Settings Database error: {}".format(e)) + flash(_(u"Database error: %(error)s.", error=e.orig), category="error") return edit_mailsettings() if to_save.get("test"): @@ -1635,6 +1660,66 @@ def update_mailsettings(): return edit_mailsettings() +@admi.route("/admin/scheduledtasks") +@login_required +@admin_required +def edit_scheduledtasks(): + content = config.get_scheduled_task_settings() + time_field = list() + duration_field = list() + + locale = get_locale() + for n in range(24): + time_field.append((n , format_time(time(hour=n), format="short", locale=locale))) + for n in range(5, 65, 5): + t = timedelta(hours=n // 60, minutes=n % 60) + duration_field.append((n, format_timedelta(t, format="short", threshold=.99, locale=locale))) + + return render_title_template("schedule_edit.html", config=content, starttime=time_field, duration=duration_field, title=_(u"Edit Scheduled Tasks Settings")) + + +@admi.route("/admin/scheduledtasks", methods=["POST"]) +@login_required +@admin_required +def update_scheduledtasks(): + error = False + to_save = request.form.to_dict() + if 0 <= int(to_save.get("schedule_start_time")) <= 23: + _config_int(to_save, "schedule_start_time") + else: + flash(_(u"Invalid start time for task specified"), category="error") + error = True + if 0 < int(to_save.get("schedule_duration")) <= 60: + _config_int(to_save, "schedule_duration") + else: + flash(_(u"Invalid duration for task specified"), category="error") + error = True + _config_checkbox(to_save, "schedule_generate_book_covers") + _config_checkbox(to_save, "schedule_generate_series_covers") + _config_checkbox(to_save, "schedule_reconnect") + + if not error: + try: + config.save() + flash(_(u"Scheduled tasks settings updated"), category="success") + + # Cancel any running tasks + schedule.end_scheduled_tasks() + + # Re-register tasks with new settings + schedule.register_scheduled_tasks(config.schedule_reconnect) + except IntegrityError: + ub.session.rollback() + log.error("An unknown error occurred while saving scheduled tasks settings") + flash(_(u"An unknown error occurred. Please try again later."), category="error") + except OperationalError: + ub.session.rollback() + log.error("Settings DB is not Writeable") + flash(_("Settings DB is not Writeable"), category="error") + + return edit_scheduledtasks() + + @admi.route("/admin/user/", methods=["GET", "POST"]) @login_required @admin_required @@ -1644,7 +1729,7 @@ def edit_user(user_id): flash(_(u"User not found"), category="error") return redirect(url_for('admin.admin')) languages = calibre_db.speaking_language(return_all_languages=True) - translations = babel.list_translations() + [LC('en')] + translations = babel.list_translations() + [Locale('en')] kobo_support = feature_support['kobo'] and config.config_kobo_sync if request.method == "POST": to_save = request.form.to_dict() @@ -1848,7 +1933,7 @@ def import_ldap_users(): try: new_users = services.ldap.get_group_members(config.config_ldap_group_name) except (services.ldap.LDAPException, TypeError, AttributeError, KeyError) as e: - log.debug_or_exception(e) + log.error_or_exception(e) showtext['text'] = _(u'Error: %(ldaperror)s', ldaperror=e) return json.dumps(showtext) if not new_users: @@ -1876,7 +1961,7 @@ def import_ldap_users(): try: user_data = services.ldap.get_object_details(user=user_identifier, query_filter=query_filter) except AttributeError as ex: - log.debug_or_exception(ex) + log.error_or_exception(ex) continue if user_data: user_count, message = ldap_import_create_user(user, user_data) @@ -1911,3 +1996,13 @@ def extract_dynamic_field_from_filter(user, filtr): def extract_user_identifier(user, filtr): dynamic_field = extract_dynamic_field_from_filter(user, filtr) return extract_user_data_from_field(user, dynamic_field) + + +@admi.route("/ajax/canceltask", methods=['POST']) +@login_required +@admin_required +def cancel_task(): + task_id = request.get_json().get('task_id', None) + worker = WorkerThread.get_instance() + worker.end_task(task_id) + return "" diff --git a/cps/cache_buster.py b/cps/cache_buster.py index 9619d605..ba19afd6 100644 --- a/cps/cache_buster.py +++ b/cps/cache_buster.py @@ -47,13 +47,16 @@ def init_cache_busting(app): for filename in filenames: # compute version component rooted_filename = os.path.join(dirpath, filename) - with open(rooted_filename, 'rb') as f: - file_hash = hashlib.md5(f.read()).hexdigest()[:7] # nosec + try: + with open(rooted_filename, 'rb') as f: + file_hash = hashlib.md5(f.read()).hexdigest()[:7] # nosec + # save version to tables + file_path = rooted_filename.replace(static_folder, "") + file_path = file_path.replace("\\", "/") # Convert Windows path to web path + hash_table[file_path] = file_hash + except PermissionError: + log.error("No permission to access {} file.".format(rooted_filename)) - # save version to tables - file_path = rooted_filename.replace(static_folder, "") - file_path = file_path.replace("\\", "/") # Convert Windows path to web path - hash_table[file_path] = file_hash log.debug('Finished computing cache-busting values') def bust_filename(filename): diff --git a/cps/cli.py b/cps/cli.py index a63d7282..629fd76d 100644 --- a/cps/cli.py +++ b/cps/cli.py @@ -24,7 +24,7 @@ import socket from .constants import CONFIG_DIR as _CONFIG_DIR from .constants import STABLE_VERSION as _STABLE_VERSION from .constants import NIGHTLY_VERSION as _NIGHTLY_VERSION - +from .constants import DEFAULT_SETTINGS_FILE, DEFAULT_GDRIVE_FILE def version_info(): if _NIGHTLY_VERSION[1].startswith('$Format'): @@ -51,8 +51,15 @@ parser.add_argument('-d', action='store_true', help='Dry run of updater to check parser.add_argument('-r', action='store_true', help='Enable public database reconnect route under /reconnect') args = parser.parse_args() -settingspath = args.p or os.path.join(_CONFIG_DIR, "app.db") -gdpath = args.g or os.path.join(_CONFIG_DIR, "gdrive.db") +settings_path = args.p or os.path.join(_CONFIG_DIR, DEFAULT_SETTINGS_FILE) +gd_path = args.g or os.path.join(_CONFIG_DIR, DEFAULT_GDRIVE_FILE) + +if os.path.isdir(settings_path): + settings_path = os.path.join(settings_path, DEFAULT_SETTINGS_FILE) + +if os.path.isdir(gd_path): + gd_path = os.path.join(gd_path, DEFAULT_GDRIVE_FILE) + # handle and check parameter for ssl encryption certfilepath = None @@ -84,10 +91,14 @@ if args.k == "": # dry run updater dry_run = args.d or None +# enable reconnect endpoint for docker database reconnect +reconnect_enable = args.r or os.environ.get("CALIBRE_RECONNECT", None) # load covers from localhost -allow_localhost = args.l or None +allow_localhost = args.l or os.environ.get("CALIBRE_LOCALHOST", None) # handle and check ip address argument ip_address = args.i or None + + if ip_address: try: # try to parse the given ip address with socket diff --git a/cps/comic.py b/cps/comic.py index 64711460..8f3a6f61 100644 --- a/cps/comic.py +++ b/cps/comic.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- # This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) -# Copyright (C) 2018 OzzieIsaacs +# Copyright (C) 2018-2022 OzzieIsaacs # # 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 @@ -18,19 +18,16 @@ import os -from . import logger, isoLanguages +from . import logger, isoLanguages, cover from .constants import BookMeta - -log = logger.create() - - try: from wand.image import Image use_IM = True except (ImportError, RuntimeError) as e: use_IM = False +log = logger.create() try: from comicapi.comicarchive import ComicArchive, MetaDataStyle @@ -51,29 +48,8 @@ except (ImportError, LookupError) as e: use_rarfile = False use_comic_meta = False -NO_JPEG_EXTENSIONS = ['.png', '.webp', '.bmp'] -COVER_EXTENSIONS = ['.png', '.webp', '.bmp', '.jpg', '.jpeg'] -def _cover_processing(tmp_file_name, img, extension): - tmp_cover_name = os.path.join(os.path.dirname(tmp_file_name), 'cover.jpg') - if extension in NO_JPEG_EXTENSIONS: - if use_IM: - with Image(blob=img) as imgc: - imgc.format = 'jpeg' - imgc.transform_colorspace('rgb') - imgc.save(filename=tmp_cover_name) - return tmp_cover_name - else: - return None - if img: - with open(tmp_cover_name, 'wb') as f: - f.write(img) - return tmp_cover_name - else: - return None - - -def _extract_Cover_from_archive(original_file_extension, tmp_file_name, rarExecutable): +def _extract_cover_from_archive(original_file_extension, tmp_file_name, rar_executable): cover_data = extension = None if original_file_extension.upper() == '.CBZ': cf = zipfile.ZipFile(tmp_file_name) @@ -81,7 +57,7 @@ def _extract_Cover_from_archive(original_file_extension, tmp_file_name, rarExecu ext = os.path.splitext(name) if len(ext) > 1: extension = ext[1].lower() - if extension in COVER_EXTENSIONS: + if extension in cover.COVER_EXTENSIONS: cover_data = cf.read(name) break elif original_file_extension.upper() == '.CBT': @@ -90,44 +66,44 @@ def _extract_Cover_from_archive(original_file_extension, tmp_file_name, rarExecu ext = os.path.splitext(name) if len(ext) > 1: extension = ext[1].lower() - if extension in COVER_EXTENSIONS: + if extension in cover.COVER_EXTENSIONS: cover_data = cf.extractfile(name).read() break elif original_file_extension.upper() == '.CBR' and use_rarfile: try: - rarfile.UNRAR_TOOL = rarExecutable + rarfile.UNRAR_TOOL = rar_executable cf = rarfile.RarFile(tmp_file_name) - for name in cf.getnames(): + for name in cf.namelist(): ext = os.path.splitext(name) if len(ext) > 1: extension = ext[1].lower() - if extension in COVER_EXTENSIONS: + if extension in cover.COVER_EXTENSIONS: cover_data = cf.read(name) break except Exception as ex: - log.debug('Rarfile failed with error: %s', ex) + log.debug('Rarfile failed with error: {}'.format(ex)) return cover_data, extension -def _extractCover(tmp_file_name, original_file_extension, rarExecutable): +def _extract_cover(tmp_file_name, original_file_extension, rar_executable): cover_data = extension = None if use_comic_meta: - archive = ComicArchive(tmp_file_name, rar_exe_path=rarExecutable) + archive = ComicArchive(tmp_file_name, rar_exe_path=rar_executable) for index, name in enumerate(archive.getPageNameList()): ext = os.path.splitext(name) if len(ext) > 1: extension = ext[1].lower() - if extension in COVER_EXTENSIONS: + if extension in cover.COVER_EXTENSIONS: cover_data = archive.getPage(index) break else: - cover_data, extension = _extract_Cover_from_archive(original_file_extension, tmp_file_name, rarExecutable) - return _cover_processing(tmp_file_name, cover_data, extension) + cover_data, extension = _extract_cover_from_archive(original_file_extension, tmp_file_name, rar_executable) + return cover.cover_processing(tmp_file_name, cover_data, extension) -def get_comic_info(tmp_file_path, original_file_name, original_file_extension, rarExecutable): +def get_comic_info(tmp_file_path, original_file_name, original_file_extension, rar_executable): if use_comic_meta: - archive = ComicArchive(tmp_file_path, rar_exe_path=rarExecutable) + archive = ComicArchive(tmp_file_path, rar_exe_path=rar_executable) if archive.seemsToBeAComicArchive(): if archive.hasMetadata(MetaDataStyle.CIX): style = MetaDataStyle.CIX @@ -137,34 +113,38 @@ def get_comic_info(tmp_file_path, original_file_name, original_file_extension, r style = None # if style is not None: - loadedMetadata = archive.readMetadata(style) + loaded_metadata = archive.readMetadata(style) - lang = loadedMetadata.language or "" - loadedMetadata.language = isoLanguages.get_lang3(lang) + lang = loaded_metadata.language or "" + loaded_metadata.language = isoLanguages.get_lang3(lang) return BookMeta( file_path=tmp_file_path, extension=original_file_extension, - title=loadedMetadata.title or original_file_name, + title=loaded_metadata.title or original_file_name, author=" & ".join([credit["person"] - for credit in loadedMetadata.credits if credit["role"] == "Writer"]) or u'Unknown', - cover=_extractCover(tmp_file_path, original_file_extension, rarExecutable), - description=loadedMetadata.comments or "", + for credit in loaded_metadata.credits if credit["role"] == "Writer"]) or 'Unknown', + cover=_extract_cover(tmp_file_path, original_file_extension, rar_executable), + description=loaded_metadata.comments or "", tags="", - series=loadedMetadata.series or "", - series_id=loadedMetadata.issue or "", - languages=loadedMetadata.language, - publisher="") + series=loaded_metadata.series or "", + series_id=loaded_metadata.issue or "", + languages=loaded_metadata.language, + publisher="", + pubdate="", + identifiers=[]) return BookMeta( file_path=tmp_file_path, extension=original_file_extension, title=original_file_name, author=u'Unknown', - cover=_extractCover(tmp_file_path, original_file_extension, rarExecutable), + cover=_extract_cover(tmp_file_path, original_file_extension, rar_executable), description="", tags="", series="", series_id="", languages="", - publisher="") + publisher="", + pubdate="", + identifiers=[]) diff --git a/cps/config_sql.py b/cps/config_sql.py index 01523a01..f4fbb554 100644 --- a/cps/config_sql.py +++ b/cps/config_sql.py @@ -134,13 +134,19 @@ class _Settings(_Base): config_calibre = Column(String) config_rarfile_location = Column(String, default=None) config_upload_formats = Column(String, default=','.join(constants.EXTENSIONS_UPLOAD)) - config_unicode_filename =Column(Boolean, default=False) + config_unicode_filename = Column(Boolean, default=False) config_updatechannel = Column(Integer, default=constants.UPDATE_STABLE) config_reverse_proxy_login_header_name = Column(String) config_allow_reverse_proxy_header_login = Column(Boolean, default=False) + schedule_start_time = Column(Integer, default=4) + schedule_duration = Column(Integer, default=10) + schedule_generate_book_covers = Column(Boolean, default=False) + schedule_generate_series_covers = Column(Boolean, default=False) + schedule_reconnect = Column(Boolean, default=False) + def __repr__(self): return self.__class__.__name__ @@ -171,7 +177,6 @@ class _ConfigSQL(object): if change: self.save() - def _read_from_storage(self): if self._settings is None: log.debug("_ConfigSQL._read_from_storage") @@ -255,6 +260,8 @@ class _ConfigSQL(object): return bool((self.mail_server != constants.DEFAULT_MAIL_SERVER and self.mail_server_type == 0) or (self.mail_gmail_token != {} and self.mail_server_type == 1)) + def get_scheduled_task_settings(self): + return {k:v for k, v in self.__dict__.items() if k.startswith('schedule_')} def set_from_dictionary(self, dictionary, field, convertor=None, default=None, encode=None): """Possibly updates a field of this object. @@ -290,7 +297,6 @@ class _ConfigSQL(object): storage[k] = v return storage - def load(self): '''Load all configuration values from the underlying storage.''' s = self._read_from_storage() # type: _Settings @@ -411,6 +417,7 @@ def autodetect_calibre_binary(): return element return "" + def autodetect_unrar_binary(): if sys.platform == "win32": calibre_path = ["C:\\program files\\WinRar\\unRAR.exe", @@ -422,6 +429,7 @@ def autodetect_unrar_binary(): return element return "" + def autodetect_kepubify_binary(): if sys.platform == "win32": calibre_path = ["C:\\program files\\kepubify\\kepubify-windows-64Bit.exe", @@ -433,6 +441,7 @@ def autodetect_kepubify_binary(): return element return "" + def _migrate_database(session): # make sure the table is created, if it does not exist _Base.metadata.create_all(session.bind) diff --git a/cps/constants.py b/cps/constants.py index f9003125..0f3b2530 100644 --- a/cps/constants.py +++ b/cps/constants.py @@ -23,6 +23,9 @@ from sqlalchemy import __version__ as sql_version sqlalchemy_version2 = ([int(x) for x in sql_version.split('.')] >= [2, 0, 0]) +# APP_MODE - production, development, or test +APP_MODE = os.environ.get('APP_MODE', 'production') + # if installed via pip this variable is set to true (empty file with name .HOMEDIR present) HOME_CONFIG = os.path.isfile(os.path.join(os.path.dirname(os.path.abspath(__file__)), '.HOMEDIR')) @@ -35,6 +38,10 @@ STATIC_DIR = os.path.join(BASE_DIR, 'cps', 'static') TEMPLATES_DIR = os.path.join(BASE_DIR, 'cps', 'templates') TRANSLATIONS_DIR = os.path.join(BASE_DIR, 'cps', 'translations') +# Cache dir - use CACHE_DIR environment variable, otherwise use the default directory: cps/cache +DEFAULT_CACHE_DIR = os.path.join(BASE_DIR, 'cps', 'cache') +CACHE_DIR = os.environ.get('CACHE_DIR', DEFAULT_CACHE_DIR) + if HOME_CONFIG: home_dir = os.path.join(os.path.expanduser("~"), ".calibre-web") if not os.path.exists(home_dir): @@ -43,6 +50,8 @@ if HOME_CONFIG: else: CONFIG_DIR = os.environ.get('CALIBRE_DBPATH', BASE_DIR) +DEFAULT_SETTINGS_FILE = "app.db" +DEFAULT_GDRIVE_FILE = "gdrive.db" ROLE_USER = 0 << 0 ROLE_ADMIN = 1 << 0 @@ -152,9 +161,9 @@ def selected_roles(dictionary): # :rtype: BookMeta BookMeta = namedtuple('BookMeta', 'file_path, extension, title, author, cover, description, tags, series, ' - 'series_id, languages, publisher') + 'series_id, languages, publisher, pubdate, identifiers') -STABLE_VERSION = {'version': '0.6.17 Beta'} +STABLE_VERSION = {'version': '0.6.19 Beta'} NIGHTLY_VERSION = dict() NIGHTLY_VERSION[0] = '$Format:%H$' @@ -162,6 +171,19 @@ NIGHTLY_VERSION[1] = '$Format:%cI$' # NIGHTLY_VERSION[0] = 'bb7d2c6273ae4560e83950d36d64533343623a57' # NIGHTLY_VERSION[1] = '2018-09-09T10:13:08+02:00' +# CACHE +CACHE_TYPE_THUMBNAILS = 'thumbnails' + +# Thumbnail Types +THUMBNAIL_TYPE_COVER = 1 +THUMBNAIL_TYPE_SERIES = 2 +THUMBNAIL_TYPE_AUTHOR = 3 + +# Thumbnails Sizes +COVER_THUMBNAIL_ORIGINAL = 0 +COVER_THUMBNAIL_SMALL = 1 +COVER_THUMBNAIL_MEDIUM = 2 +COVER_THUMBNAIL_LARGE = 3 # clean-up the module namespace del sys, os, namedtuple diff --git a/cps/converter.py b/cps/converter.py index fcbabbfc..af2a6c09 100644 --- a/cps/converter.py +++ b/cps/converter.py @@ -18,7 +18,8 @@ import os import re -from flask_babel import gettext as _ + +from flask_babel import lazy_gettext as N_ from . import config, logger from .subproc_wrapper import process_wait @@ -26,10 +27,9 @@ from .subproc_wrapper import process_wait log = logger.create() -# _() necessary to make babel aware of string for translation -_NOT_CONFIGURED = _('not configured') -_NOT_INSTALLED = _('not installed') -_EXECUTION_ERROR = _('Execution permissions missing') +# strings getting translated when used +_NOT_INSTALLED = N_('not installed') +_EXECUTION_ERROR = N_('Execution permissions missing') def _get_command_version(path, pattern, argument=None): @@ -48,14 +48,16 @@ def _get_command_version(path, pattern, argument=None): def get_calibre_version(): - return _get_command_version(config.config_converterpath, r'ebook-convert.*\(calibre', '--version') \ - or _NOT_CONFIGURED + return _get_command_version(config.config_converterpath, r'ebook-convert.*\(calibre', '--version') def get_unrar_version(): - return _get_command_version(config.config_rarfile_location, r'UNRAR.*\d') or _NOT_CONFIGURED + unrar_version = _get_command_version(config.config_rarfile_location, r'UNRAR.*\d') + if unrar_version == "not installed": + unrar_version = _get_command_version(config.config_rarfile_location, r'unrar.*\d','-V') + return unrar_version def get_kepubify_version(): - return _get_command_version(config.config_kepubifypath, r'kepubify\s','--version') or _NOT_CONFIGURED + return _get_command_version(config.config_kepubifypath, r'kepubify\s','--version') diff --git a/cps/cover.py b/cps/cover.py new file mode 100644 index 00000000..5dd29534 --- /dev/null +++ b/cps/cover.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- + +# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) +# Copyright (C) 2022 OzzieIsaacs +# +# 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 . + +import os + +try: + from wand.image import Image + use_IM = True +except (ImportError, RuntimeError) as e: + use_IM = False + + +NO_JPEG_EXTENSIONS = ['.png', '.webp', '.bmp'] +COVER_EXTENSIONS = ['.png', '.webp', '.bmp', '.jpg', '.jpeg'] + + +def cover_processing(tmp_file_name, img, extension): + tmp_cover_name = os.path.join(os.path.dirname(tmp_file_name), 'cover.jpg') + if extension in NO_JPEG_EXTENSIONS: + if use_IM: + with Image(blob=img) as imgc: + imgc.format = 'jpeg' + imgc.transform_colorspace('rgb') + imgc.save(filename=tmp_cover_name) + return tmp_cover_name + else: + return None + if img: + with open(tmp_cover_name, 'wb') as f: + f.write(img) + return tmp_cover_name + else: + return None diff --git a/cps/db.py b/cps/db.py index a3b93d89..9f6440aa 100644 --- a/cps/db.py +++ b/cps/db.py @@ -17,14 +17,15 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import sys import os import re import ast import json from datetime import datetime from urllib.parse import quote +import unidecode +from sqlite3 import OperationalError as sqliteOperationalError from sqlalchemy import create_engine from sqlalchemy import Table, Column, ForeignKey, CheckConstraint from sqlalchemy import String, Integer, Boolean, TIMESTAMP, Float @@ -49,11 +50,6 @@ from .pagination import Pagination from weakref import WeakSet -try: - import unidecode - use_unidecode = True -except ImportError: - use_unidecode = False log = logger.create() @@ -93,7 +89,7 @@ books_publishers_link = Table('books_publishers_link', Base.metadata, ) -class Library_Id(Base): +class LibraryId(Base): __tablename__ = 'library_id' id = Column(Integer, primary_key=True) uuid = Column(String, nullable=False) @@ -112,7 +108,7 @@ class Identifiers(Base): self.type = id_type self.book = book - def formatType(self): + def format_type(self): format_type = self.type.lower() if format_type == 'amazon': return u"Amazon" @@ -184,8 +180,8 @@ class Comments(Base): book = Column(Integer, ForeignKey('books.id'), nullable=False, unique=True) text = Column(String(collation='NOCASE'), nullable=False) - def __init__(self, text, book): - self.text = text + def __init__(self, comment, book): + self.text = comment self.book = book def get(self): @@ -367,7 +363,6 @@ class Books(Base): self.path = path self.has_cover = (has_cover != None) - def __repr__(self): return u"".format(self.title, self.sort, self.author_sort, self.timestamp, self.pubdate, self.series_index, @@ -375,10 +370,10 @@ class Books(Base): @property def atom_timestamp(self): - return (self.timestamp.strftime('%Y-%m-%dT%H:%M:%S+00:00') or '') + return self.timestamp.strftime('%Y-%m-%dT%H:%M:%S+00:00') or '' -class Custom_Columns(Base): +class CustomColumns(Base): __tablename__ = 'custom_columns' id = Column(Integer, primary_key=True) @@ -436,7 +431,7 @@ class AlchemyEncoder(json.JSONEncoder): return json.JSONEncoder.default(self, o) -class CalibreDB(): +class CalibreDB: _init = False engine = None config = None @@ -450,17 +445,17 @@ class CalibreDB(): """ self.session = None if self._init: - self.initSession(expire_on_commit) + self.init_session(expire_on_commit) self.instances.add(self) - def initSession(self, expire_on_commit=True): + def init_session(self, expire_on_commit=True): self.session = self.session_factory() self.session.expire_on_commit = expire_on_commit self.update_title_sort(self.config) @classmethod - def setup_db_cc_classes(self, cc): + def setup_db_cc_classes(cls, cc): cc_ids = [] books_custom_column_links = {} for row in cc: @@ -539,16 +534,16 @@ class CalibreDB(): return False, False try: check_engine = create_engine('sqlite://', - echo=False, - isolation_level="SERIALIZABLE", - connect_args={'check_same_thread': False}, - poolclass=StaticPool) + echo=False, + isolation_level="SERIALIZABLE", + connect_args={'check_same_thread': False}, + poolclass=StaticPool) with check_engine.begin() as connection: connection.execute(text("attach database '{}' as calibre;".format(dbpath))) connection.execute(text("attach database '{}' as app_settings;".format(app_db_path))) local_session = scoped_session(sessionmaker()) local_session.configure(bind=connection) - database_uuid = local_session().query(Library_Id).one_or_none() + database_uuid = local_session().query(LibraryId).one_or_none() # local_session.dispose() check_engine.connect() @@ -597,13 +592,14 @@ class CalibreDB(): cc = conn.execute(text("SELECT id, datatype FROM custom_columns")) cls.setup_db_cc_classes(cc) except OperationalError as e: - log.debug_or_exception(e) + log.error_or_exception(e) + return False cls.session_factory = scoped_session(sessionmaker(autocommit=False, autoflush=True, bind=cls.engine)) for inst in cls.instances: - inst.initSession() + inst.init_session() cls._init = True return True @@ -626,8 +622,8 @@ class CalibreDB(): bd = (self.session.query(Books, read_column.value, ub.ArchivedBook.is_archived).select_from(Books) .join(read_column, read_column.book == book_id, isouter=True)) - except (KeyError, AttributeError): - log.error("Custom Column No.%d is not existing in calibre database", read_column) + except (KeyError, AttributeError, IndexError): + log.error("Custom Column No.{} is not existing in calibre database".format(read_column)) # Skip linking read column and return None instead of read status bd = self.session.query(Books, None, ub.ArchivedBook.is_archived) return (bd.filter(Books.id == book_id) @@ -644,12 +640,10 @@ class CalibreDB(): # Language and content filters for displaying in the UI def common_filters(self, allow_show_archived=False, return_all_languages=False): if not allow_show_archived: - archived_books = ( - ub.session.query(ub.ArchivedBook) - .filter(ub.ArchivedBook.user_id == int(current_user.id)) - .filter(ub.ArchivedBook.is_archived == True) - .all() - ) + archived_books = (ub.session.query(ub.ArchivedBook) + .filter(ub.ArchivedBook.user_id == int(current_user.id)) + .filter(ub.ArchivedBook.is_archived == True) + .all()) archived_book_ids = [archived_book.book_id for archived_book in archived_books] archived_filter = Books.id.notin_(archived_book_ids) else: @@ -668,16 +662,16 @@ class CalibreDB(): pos_cc_list = current_user.allowed_column_value.split(',') pos_content_cc_filter = true() if pos_cc_list == [''] else \ getattr(Books, 'custom_column_' + str(self.config.config_restricted_column)). \ - any(cc_classes[self.config.config_restricted_column].value.in_(pos_cc_list)) + any(cc_classes[self.config.config_restricted_column].value.in_(pos_cc_list)) neg_cc_list = current_user.denied_column_value.split(',') neg_content_cc_filter = false() if neg_cc_list == [''] else \ getattr(Books, 'custom_column_' + str(self.config.config_restricted_column)). \ - any(cc_classes[self.config.config_restricted_column].value.in_(neg_cc_list)) - except (KeyError, AttributeError): + any(cc_classes[self.config.config_restricted_column].value.in_(neg_cc_list)) + except (KeyError, AttributeError, IndexError): pos_content_cc_filter = false() neg_content_cc_filter = true() - log.error(u"Custom Column No.%d is not existing in calibre database", - self.config.config_restricted_column) + log.error("Custom Column No.{} is not existing in calibre database".format( + self.config.config_restricted_column)) flash(_("Custom Column No.%(column)d is not existing in calibre database", column=self.config.config_restricted_column), category="error") @@ -688,6 +682,25 @@ class CalibreDB(): return and_(lang_filter, pos_content_tags_filter, ~neg_content_tags_filter, pos_content_cc_filter, ~neg_content_cc_filter, archived_filter) + def generate_linked_query(self, config_read_column, database): + if not config_read_column: + query = (self.session.query(database, ub.ArchivedBook.is_archived, ub.ReadBook.read_status) + .select_from(Books) + .outerjoin(ub.ReadBook, + and_(ub.ReadBook.user_id == int(current_user.id), ub.ReadBook.book_id == Books.id))) + else: + try: + read_column = cc_classes[config_read_column] + query = (self.session.query(database, ub.ArchivedBook.is_archived, read_column.value) + .select_from(Books) + .outerjoin(read_column, read_column.book == Books.id)) + except (KeyError, AttributeError, IndexError): + log.error("Custom Column No.{} is not existing in calibre database".format(config_read_column)) + # Skip linking read column and return None instead of read status + query = self.session.query(database, None, ub.ArchivedBook.is_archived) + return query.outerjoin(ub.ArchivedBook, and_(Books.id == ub.ArchivedBook.book_id, + int(current_user.id) == ub.ArchivedBook.user_id)) + @staticmethod def get_checkbox_sorted(inputlist, state, offset, limit, order, combo=False): outcome = list() @@ -717,30 +730,14 @@ class CalibreDB(): join_archive_read, config_read_column, *join): pagesize = pagesize or self.config.config_books_per_page if current_user.show_detail_random(): - randm = self.session.query(Books) \ - .filter(self.common_filters(allow_show_archived)) \ - .order_by(func.random()) \ - .limit(self.config.config_random_books).all() + random_query = self.generate_linked_query(config_read_column, database) + randm = (random_query.filter(self.common_filters(allow_show_archived)) + .order_by(func.random()) + .limit(self.config.config_random_books).all()) else: randm = false() if join_archive_read: - if not config_read_column: - query = (self.session.query(database, ub.ReadBook.read_status, ub.ArchivedBook.is_archived) - .select_from(Books) - .outerjoin(ub.ReadBook, - and_(ub.ReadBook.user_id == int(current_user.id), ub.ReadBook.book_id == Books.id))) - else: - try: - read_column = cc_classes[config_read_column] - query = (self.session.query(database, read_column.value, ub.ArchivedBook.is_archived) - .select_from(Books) - .outerjoin(read_column, read_column.book == Books.id)) - except (KeyError, AttributeError): - log.error("Custom Column No.%d is not existing in calibre database", read_column) - # Skip linking read column and return None instead of read status - query =self.session.query(database, None, ub.ArchivedBook.is_archived) - query = query.outerjoin(ub.ArchivedBook, and_(Books.id == ub.ArchivedBook.book_id, - int(current_user.id) == ub.ArchivedBook.user_id)) + query = self.generate_linked_query(config_read_column, database) else: query = self.session.query(database) off = int(int(pagesize) * (page - 1)) @@ -769,13 +766,15 @@ class CalibreDB(): len(query.all())) entries = query.order_by(*order).offset(off).limit(pagesize).all() except Exception as ex: - log.debug_or_exception(ex) + log.error_or_exception(ex) # display authors in right order entries = self.order_authors(entries, True, join_archive_read) return entries, randm, pagination # Orders all Authors in the list according to authors sort def order_authors(self, entries, list_return=False, combined=False): + # entries_copy = copy.deepcopy(entries) + # entries_copy =[] for entry in entries: if combined: sort_authors = entry.Books.author_sort.split('&') @@ -785,25 +784,30 @@ class CalibreDB(): sort_authors = entry.author_sort.split('&') ids = [a.id for a in entry.authors] authors_ordered = list() - error = False + # error = False for auth in sort_authors: results = self.session.query(Authors).filter(Authors.sort == auth.lstrip().strip()).all() - # ToDo: How to handle not found authorname + # ToDo: How to handle not found author name if not len(results): - error = True + log.error("Author {} not found to display name in right order".format(auth.strip())) + # error = True break for r in results: if r.id in ids: authors_ordered.append(r) - if not error: + ids.remove(r.id) + for author_id in ids: + result = self.session.query(Authors).filter(Authors.id == author_id).first() + authors_ordered.append(result) + + if list_return: if combined: entry.Books.authors = authors_ordered else: - entry.authors = authors_ordered - if list_return: - return entries - else: - return authors_ordered + entry.ordered_authors = authors_ordered + else: + return authors_ordered + return entries def get_typeahead(self, database, query, replace=('', ''), tag_filter=true()): query = query or '' @@ -817,36 +821,21 @@ class CalibreDB(): def check_exists_book(self, authr, title): self.session.connection().connection.connection.create_function("lower", 1, lcase) q = list() - authorterms = re.split(r'\s*&\s*', authr) - for authorterm in authorterms: - q.append(Books.authors.any(func.lower(Authors.name).ilike("%" + authorterm + "%"))) + author_terms = re.split(r'\s*&\s*', authr) + for author_term in author_terms: + q.append(Books.authors.any(func.lower(Authors.name).ilike("%" + author_term + "%"))) return self.session.query(Books) \ .filter(and_(Books.authors.any(and_(*q)), func.lower(Books.title).ilike("%" + title + "%"))).first() - def search_query(self, term, config_read_column, *join): + def search_query(self, term, config, *join): term.strip().lower() self.session.connection().connection.connection.create_function("lower", 1, lcase) q = list() - authorterms = re.split("[, ]+", term) - for authorterm in authorterms: - q.append(Books.authors.any(func.lower(Authors.name).ilike("%" + authorterm + "%"))) - if not config_read_column: - query = (self.session.query(Books, ub.ArchivedBook.is_archived, ub.ReadBook).select_from(Books) - .outerjoin(ub.ReadBook, and_(Books.id == ub.ReadBook.book_id, - int(current_user.id) == ub.ReadBook.user_id))) - else: - try: - read_column = cc_classes[config_read_column] - query = (self.session.query(Books, ub.ArchivedBook.is_archived, read_column.value).select_from(Books) - .outerjoin(read_column, read_column.book == Books.id)) - except (KeyError, AttributeError): - log.error("Custom Column No.%d is not existing in calibre database", config_read_column) - # Skip linking read column - query = self.session.query(Books, ub.ArchivedBook.is_archived, None) - query = query.outerjoin(ub.ArchivedBook, and_(Books.id == ub.ArchivedBook.book_id, - int(current_user.id) == ub.ArchivedBook.user_id)) - + author_terms = re.split("[, ]+", term) + for author_term in author_terms: + q.append(Books.authors.any(func.lower(Authors.name).ilike("%" + author_term + "%"))) + query = self.generate_linked_query(config.config_read_column, Books) if len(join) == 6: query = query.outerjoin(join[0], join[1]).outerjoin(join[2]).outerjoin(join[3], join[4]).outerjoin(join[5]) if len(join) == 3: @@ -855,20 +844,42 @@ class CalibreDB(): query = query.outerjoin(join[0], join[1]) elif len(join) == 1: query = query.outerjoin(join[0]) - return query.filter(self.common_filters(True)).filter( - or_(Books.tags.any(func.lower(Tags.name).ilike("%" + term + "%")), - Books.series.any(func.lower(Series.name).ilike("%" + term + "%")), - Books.authors.any(and_(*q)), - Books.publishers.any(func.lower(Publishers.name).ilike("%" + term + "%")), - func.lower(Books.title).ilike("%" + term + "%") - )) + + cc = self.get_cc_columns(config, filter_config_custom_read=True) + filter_expression = [Books.tags.any(func.lower(Tags.name).ilike("%" + term + "%")), + Books.series.any(func.lower(Series.name).ilike("%" + term + "%")), + Books.authors.any(and_(*q)), + Books.publishers.any(func.lower(Publishers.name).ilike("%" + term + "%")), + func.lower(Books.title).ilike("%" + term + "%")] + for c in cc: + if c.datatype not in ["datetime", "rating", "bool", "int", "float"]: + filter_expression.append( + getattr(Books, + 'custom_column_' + str(c.id)).any( + func.lower(cc_classes[c.id].value).ilike("%" + term + "%"))) + return query.filter(self.common_filters(True)).filter(or_(*filter_expression)) + + def get_cc_columns(self, config, filter_config_custom_read=False): + tmp_cc = self.session.query(CustomColumns).filter(CustomColumns.datatype.notin_(cc_exceptions)).all() + cc = [] + r = None + if config.config_columns_to_ignore: + r = re.compile(config.config_columns_to_ignore) + + for col in tmp_cc: + if filter_config_custom_read and config.config_read_column and config.config_read_column == col.id: + continue + if r and r.match(col.name): + continue + cc.append(col) + + return cc # read search results from calibre-database and return it (function is used for feed and simple search - def get_search_results(self, term, offset=None, order=None, limit=None, allow_show_archived=False, - config_read_column=False, *join): + def get_search_results(self, term, config, offset=None, order=None, limit=None, *join): order = order[0] if order else [Books.sort] pagination = None - result = self.search_query(term, config_read_column, *join).order_by(*order).all() + result = self.search_query(term, config, *join).order_by(*order).all() result_count = len(result) if offset != None and limit != None: offset = int(offset) @@ -893,9 +904,20 @@ class CalibreDB(): .join(books_languages_link).join(Books)\ .filter(self.common_filters(return_all_languages=return_all_languages)) \ .group_by(text('books_languages_link.lang_code')).all() + tags = list() for lang in languages: - lang[0].name = isoLanguages.get_language_name(get_locale(), lang[0].lang_code) - return sorted(languages, key=lambda x: x[0].name, reverse=reverse_order) + tag = Category(isoLanguages.get_language_name(get_locale(), lang[0].lang_code), lang[0].lang_code) + tags.append([tag, lang[1]]) + # Append all books without language to list + if not return_all_languages: + no_lang_count = (self.session.query(Books) + .outerjoin(books_languages_link).outerjoin(Languages) + .filter(Languages.lang_code == None) + .filter(self.common_filters()) + .count()) + if no_lang_count: + tags.append([Category(_("None"), "none"), no_lang_count]) + return sorted(tags, key=lambda x: x[0].name, reverse=reverse_order) else: if not languages: languages = self.session.query(Languages) \ @@ -907,7 +929,6 @@ class CalibreDB(): lang.name = isoLanguages.get_language_name(get_locale(), lang.lang_code) return sorted(languages, key=lambda x: x.name, reverse=reverse_order) - def update_title_sort(self, config, conn=None): # user defined sort function for calibre databases (Series, etc.) def _title_sort(title): @@ -920,7 +941,10 @@ class CalibreDB(): return title.strip() conn = conn or self.session.connection().connection.connection - conn.create_function("title_sort", 1, _title_sort) + try: + conn.create_function("title_sort", 1, _title_sort) + except sqliteOperationalError: + pass @classmethod def dispose(cls): @@ -965,6 +989,25 @@ def lcase(s): try: return unidecode.unidecode(s.lower()) except Exception as ex: - log = logger.create() - log.debug_or_exception(ex) + _log = logger.create() + _log.error_or_exception(ex) return s.lower() + + +class Category: + name = None + id = None + count = None + rating = None + + def __init__(self, name, cat_id, rating=None): + self.name = name + self.id = cat_id + self.rating = rating + self.count = 1 + +'''class Count: + count = None + + def __init__(self, count): + self.count = count''' diff --git a/cps/dep_check.py b/cps/dep_check.py index 84e16e85..929185c2 100644 --- a/cps/dep_check.py +++ b/cps/dep_check.py @@ -5,7 +5,7 @@ import json from .constants import BASE_DIR try: - from importlib_metadata import version + from importlib.metadata import version importlib = True ImportNotFound = BaseException except ImportError: diff --git a/cps/editbooks.py b/cps/editbooks.py index fcf043a5..768f1830 100755 --- a/cps/editbooks.py +++ b/cps/editbooks.py @@ -25,19 +25,20 @@ from datetime import datetime import json from shutil import copyfile from uuid import uuid4 -from markupsafe import escape +from markupsafe import escape # dependency of flask from functools import wraps try: from lxml.html.clean import clean_html except ImportError: - pass + clean_html = None from flask import Blueprint, request, flash, redirect, url_for, abort, Markup, Response from flask_babel import gettext as _ +from flask_babel import lazy_gettext as N_ from flask_login import current_user, login_required from sqlalchemy.exc import OperationalError, IntegrityError -from sqlite3 import OperationalError as sqliteOperationalError +# from sqlite3 import OperationalError as sqliteOperationalError from . import constants, logger, isoLanguages, gdriveutils, uploader, helper, kobo_sync_status from . import config, get_locale, ub, db from . import calibre_db @@ -48,7 +49,7 @@ from .usermanagement import login_required_if_no_ano from .kobo_sync_status import change_archived_books -editbook = Blueprint('editbook', __name__) +EditBook = Blueprint('edit-book', __name__) log = logger.create() @@ -61,6 +62,7 @@ def upload_required(f): return inner + def edit_required(f): @wraps(f) def inner(*args, **kwargs): @@ -70,6 +72,7 @@ def edit_required(f): return inner + def search_objects_remove(db_book_object, db_type, input_elements): del_elements = [] for c_elements in db_book_object: @@ -119,6 +122,7 @@ def remove_objects(db_book_object, db_session, del_elements): db_session.delete(del_element) return changed + def add_objects(db_book_object, db_object, db_session, db_type, add_elements): changed = False if db_type == 'languages': @@ -128,7 +132,7 @@ def add_objects(db_book_object, db_object, db_session, db_type, add_elements): else: db_filter = db_object.name for add_element in add_elements: - # check if a element with that name exists + # check if an element with that name exists db_element = db_session.query(db_object).filter(db_filter == add_element).first() # if no element is found add it if db_type == 'author': @@ -147,7 +151,6 @@ def add_objects(db_book_object, db_object, db_session, db_type, add_elements): db_book_object.append(new_element) else: db_element = create_objects_for_addition(db_element, add_element, db_type) - changed = True # add element to book changed = True db_book_object.append(db_element) @@ -178,7 +181,7 @@ def create_objects_for_addition(db_element, add_element, db_type): return db_element -# Modifies different Database objects, first check if elements if elements have to be deleted, +# Modifies different Database objects, first check if elements have to be deleted, # because they are no longer used, than check if elements have to be added to database def modify_database_object(input_elements, db_book_object, db_object, db_session, db_type): # passing input_elements not as a list may lead to undesired results @@ -207,7 +210,7 @@ def modify_identifiers(input_identifiers, db_identifiers, db_session): input_dict = dict([(identifier.type.lower(), identifier) for identifier in input_identifiers]) if len(input_identifiers) != len(input_dict): error = True - db_dict = dict([(identifier.type.lower(), identifier) for identifier in db_identifiers ]) + db_dict = dict([(identifier.type.lower(), identifier) for identifier in db_identifiers]) # delete db identifiers not present in input or modify them with input val for identifier_type, identifier in db_dict.items(): if identifier_type not in input_dict.keys(): @@ -224,21 +227,22 @@ def modify_identifiers(input_identifiers, db_identifiers, db_session): changed = True return changed, error -@editbook.route("/ajax/delete/", methods=["POST"]) + +@EditBook.route("/ajax/delete/", methods=["POST"]) @login_required def delete_book_from_details(book_id): return Response(delete_book_from_table(book_id, "", True), mimetype='application/json') -@editbook.route("/delete/", defaults={'book_format': ""}, methods=["POST"]) -@editbook.route("/delete//", methods=["POST"]) +@EditBook.route("/delete/", defaults={'book_format': ""}, methods=["POST"]) +@EditBook.route("/delete//", methods=["POST"]) @login_required def delete_book_ajax(book_id, book_format): return delete_book_from_table(book_id, book_format, False) def delete_whole_book(book_id, book): - # delete book from Shelfs, Downloads, Read list + # delete book from shelves, Downloads, Read list ub.session.query(ub.BookShelf).filter(ub.BookShelf.book_id == book_id).delete() ub.session.query(ub.ReadBook).filter(ub.ReadBook.book_id == book_id).delete() ub.delete_download(book_id) @@ -252,8 +256,8 @@ def delete_whole_book(book_id, book): modify_database_object([u''], book.languages, db.Languages, calibre_db.session, 'languages') modify_database_object([u''], book.publishers, db.Publishers, calibre_db.session, 'publishers') - cc = calibre_db.session.query(db.Custom_Columns). \ - filter(db.Custom_Columns.datatype.notin_(db.cc_exceptions)).all() + cc = calibre_db.session.query(db.CustomColumns). \ + filter(db.CustomColumns.datatype.notin_(db.cc_exceptions)).all() for c in cc: cc_string = "custom_column_" + str(c.id) if not c.is_multiple: @@ -283,18 +287,18 @@ def delete_whole_book(book_id, book): calibre_db.session.query(db.Books).filter(db.Books.id == book_id).delete() -def render_delete_book_result(book_format, jsonResponse, warning, book_id): +def render_delete_book_result(book_format, json_response, warning, book_id): if book_format: - if jsonResponse: - return json.dumps([warning, {"location": url_for("editbook.edit_book", book_id=book_id), + if json_response: + return json.dumps([warning, {"location": url_for("edit-book.show_edit_book", book_id=book_id), "type": "success", "format": book_format, "message": _('Book Format Successfully Deleted')}]) else: flash(_('Book Format Successfully Deleted'), category="success") - return redirect(url_for('editbook.edit_book', book_id=book_id)) + return redirect(url_for('edit-book.show_edit_book', book_id=book_id)) else: - if jsonResponse: + if json_response: return json.dumps([warning, {"location": url_for('web.index'), "type": "success", "format": book_format, @@ -304,7 +308,7 @@ def render_delete_book_result(book_format, jsonResponse, warning, book_id): return redirect(url_for('web.index')) -def delete_book_from_table(book_id, book_format, jsonResponse): +def delete_book_from_table(book_id, book_format, json_response): warning = {} if current_user.role_delete_books(): book = calibre_db.get_book(book_id) @@ -312,20 +316,20 @@ def delete_book_from_table(book_id, book_format, jsonResponse): try: result, error = helper.delete_book(book, config.config_calibre_dir, book_format=book_format.upper()) if not result: - if jsonResponse: - return json.dumps([{"location": url_for("editbook.edit_book", book_id=book_id), - "type": "danger", - "format": "", - "message": error}]) + if json_response: + return json.dumps([{"location": url_for("edit-book.show_edit_book", book_id=book_id), + "type": "danger", + "format": "", + "message": error}]) else: flash(error, category="error") - return redirect(url_for('editbook.edit_book', book_id=book_id)) + return redirect(url_for('edit-book.show_edit_book', book_id=book_id)) if error: - if jsonResponse: - warning = {"location": url_for("editbook.edit_book", book_id=book_id), - "type": "warning", - "format": "", - "message": error} + if json_response: + warning = {"location": url_for("edit-book.show_edit_book", book_id=book_id), + "type": "warning", + "format": "", + "message": error} else: flash(error, category="warning") if not book_format: @@ -337,37 +341,38 @@ def delete_book_from_table(book_id, book_format, jsonResponse): kobo_sync_status.remove_synced_book(book.id, True) calibre_db.session.commit() except Exception as ex: - log.debug_or_exception(ex) + log.error_or_exception(ex) calibre_db.session.rollback() - if jsonResponse: - return json.dumps([{"location": url_for("editbook.edit_book", book_id=book_id), + if json_response: + return json.dumps([{"location": url_for("edit-book.show_edit_book", book_id=book_id), "type": "danger", "format": "", "message": ex}]) else: flash(str(ex), category="error") - return redirect(url_for('editbook.edit_book', book_id=book_id)) + return redirect(url_for('edit-book.show_edit_book', book_id=book_id)) else: # book not found log.error('Book with id "%s" could not be deleted: not found', book_id) - return render_delete_book_result(book_format, jsonResponse, warning, book_id) + return render_delete_book_result(book_format, json_response, warning, book_id) message = _("You are missing permissions to delete books") - if jsonResponse: - return json.dumps({"location": url_for("editbook.edit_book", book_id=book_id), + if json_response: + return json.dumps({"location": url_for("edit-book.show_edit_book", book_id=book_id), "type": "danger", "format": "", "message": message}) else: flash(message, category="error") - return redirect(url_for('editbook.edit_book', book_id=book_id)) + return redirect(url_for('edit-book.show_edit_book', book_id=book_id)) def render_edit_book(book_id): - cc = calibre_db.session.query(db.Custom_Columns).filter(db.Custom_Columns.datatype.notin_(db.cc_exceptions)).all() + cc = calibre_db.session.query(db.CustomColumns).filter(db.CustomColumns.datatype.notin_(db.cc_exceptions)).all() book = calibre_db.get_filtered_book(book_id, allow_show_archived=True) if not book: - flash(_(u"Oops! Selected book title is unavailable. File does not exist or is not accessible"), category="error") + flash(_(u"Oops! Selected book title is unavailable. File does not exist or is not accessible"), + category="error") return redirect(url_for("web.index")) for lang in book.languages: @@ -379,10 +384,10 @@ def render_edit_book(book_id): for authr in book.authors: author_names.append(authr.name.replace('|', ',')) - # Option for showing convertbook button - valid_source_formats=list() + # Option for showing convert_book button + valid_source_formats = list() allowed_conversion_formats = list() - kepub_possible=None + kepub_possible = None if config.config_converterpath: for file in book.data: if file.format.lower() in constants.EXTENSIONS_CONVERT_FROM: @@ -409,18 +414,18 @@ def render_edit_book(book_id): def edit_book_ratings(to_save, book): changed = False - if to_save["rating"].strip(): + if to_save.get("rating", "").strip(): old_rating = False if len(book.ratings) > 0: old_rating = book.ratings[0].rating - ratingx2 = int(float(to_save["rating"]) * 2) - if ratingx2 != old_rating: + rating_x2 = int(float(to_save.get("rating", "")) * 2) + if rating_x2 != old_rating: changed = True - is_rating = calibre_db.session.query(db.Ratings).filter(db.Ratings.rating == ratingx2).first() + is_rating = calibre_db.session.query(db.Ratings).filter(db.Ratings.rating == rating_x2).first() if is_rating: book.ratings.append(is_rating) else: - new_rating = db.Ratings(rating=ratingx2) + new_rating = db.Ratings(rating=rating_x2) book.ratings.append(new_rating) if old_rating: book.ratings.remove(book.ratings[0]) @@ -430,6 +435,7 @@ def edit_book_ratings(to_save, book): changed = True return changed + def edit_book_tags(tags, book): input_tags = tags.split(',') input_tags = list(map(lambda it: it.strip(), input_tags)) @@ -446,48 +452,48 @@ def edit_book_series(series, book): def edit_book_series_index(series_index, book): # Add default series_index to book - modif_date = False + modify_date = False series_index = series_index or '1' if not series_index.replace('.', '', 1).isdigit(): flash(_("%(seriesindex)s is not a valid number, skipping", seriesindex=series_index), category="warning") return False if str(book.series_index) != series_index: book.series_index = series_index - modif_date = True - return modif_date + modify_date = True + return modify_date # Handle book comments/description def edit_book_comments(comments, book): - modif_date = False + modify_date = False if comments: comments = clean_html(comments) if len(book.comments): if book.comments[0].text != comments: book.comments[0].text = comments - modif_date = True + modify_date = True else: if comments: - book.comments.append(db.Comments(text=comments, book=book.id)) - modif_date = True - return modif_date + book.comments.append(db.Comments(comment=comments, book=book.id)) + modify_date = True + return modify_date -def edit_book_languages(languages, book, upload=False, invalid=None): +def edit_book_languages(languages, book, upload_mode=False, invalid=None): input_languages = languages.split(',') unknown_languages = [] - if not upload: + if not upload_mode: input_l = isoLanguages.get_language_codes(get_locale(), input_languages, unknown_languages) else: input_l = isoLanguages.get_valid_language_codes(get_locale(), input_languages, unknown_languages) - for l in unknown_languages: - log.error("'%s' is not a valid language", l) + for lang in unknown_languages: + log.error("'%s' is not a valid language", lang) if isinstance(invalid, list): - invalid.append(l) + invalid.append(lang) else: - raise ValueError(_(u"'%(langname)s' is not a valid language", langname=l)) + raise ValueError(_(u"'%(langname)s' is not a valid language", langname=lang)) # ToDo: Not working correct - if upload and len(input_l) == 1: + if upload_mode and len(input_l) == 1: # If the language of the file is excluded from the users view, it's not imported, to allow the user to view # the book it's language is set to the filter language if input_l[0] != current_user.filter_language() and current_user.filter_language() != "all": @@ -571,17 +577,20 @@ def edit_cc_data_string(book, c, to_save, cc_db_value, cc_string): getattr(book, cc_string).append(new_cc) return changed, to_save + def edit_single_cc_data(book_id, book, column_id, to_save): - cc = (calibre_db.session.query(db.Custom_Columns) - .filter(db.Custom_Columns.datatype.notin_(db.cc_exceptions)) - .filter(db.Custom_Columns.id == column_id) + cc = (calibre_db.session.query(db.CustomColumns) + .filter(db.CustomColumns.datatype.notin_(db.cc_exceptions)) + .filter(db.CustomColumns.id == column_id) .all()) return edit_cc_data(book_id, book, to_save, cc) + def edit_all_cc_data(book_id, book, to_save): - cc = calibre_db.session.query(db.Custom_Columns).filter(db.Custom_Columns.datatype.notin_(db.cc_exceptions)).all() + cc = calibre_db.session.query(db.CustomColumns).filter(db.CustomColumns.datatype.notin_(db.cc_exceptions)).all() return edit_cc_data(book_id, book, to_save, cc) + def edit_cc_data(book_id, book, to_save, cc): changed = False for c in cc: @@ -614,23 +623,27 @@ def edit_cc_data(book_id, book, to_save, cc): 'custom') return changed -def upload_single_file(request, book, book_id): + +# returns None if no file is uploaded +# returns False if an error occurs, in all other cases the ebook metadata is returned +def upload_single_file(file_request, book, book_id): # Check and handle Uploaded file - if 'btn-upload-format' in request.files: - requested_file = request.files['btn-upload-format'] + requested_file = file_request.files.get('btn-upload-format', None) + if requested_file: # check for empty request if requested_file.filename != '': if not current_user.role_upload(): - abort(403) + flash(_(u"User has no rights to upload additional file formats"), category="error") + return False if '.' in requested_file.filename: file_ext = requested_file.filename.rsplit('.', 1)[-1].lower() if file_ext not in constants.EXTENSIONS_UPLOAD and '' not in constants.EXTENSIONS_UPLOAD: flash(_("File extension '%(ext)s' is not allowed to be uploaded to this server", ext=file_ext), category="error") - return redirect(url_for('web.show_book', book_id=book.id)) + return False else: flash(_('File to be uploaded must have an extension'), category="error") - return redirect(url_for('web.show_book', book_id=book.id)) + return False file_name = book.path.rsplit('/', 1)[-1] filepath = os.path.normpath(os.path.join(config.config_calibre_dir, book.path)) @@ -642,12 +655,12 @@ def upload_single_file(request, book, book_id): os.makedirs(filepath) except OSError: flash(_(u"Failed to create path %(path)s (Permission denied).", path=filepath), category="error") - return redirect(url_for('web.show_book', book_id=book.id)) + return False try: requested_file.save(saved_filename) except OSError: flash(_(u"Failed to store file %(file)s.", file=saved_filename), category="error") - return redirect(url_for('web.show_book', book_id=book.id)) + return False file_size = os.path.getsize(saved_filename) is_format = calibre_db.get_book_format(book_id, file_ext.upper()) @@ -663,29 +676,32 @@ def upload_single_file(request, book, book_id): calibre_db.update_title_sort(config) except (OperationalError, IntegrityError) as e: calibre_db.session.rollback() - log.error('Database error: %s', e) - flash(_(u"Database error: %(error)s.", error=e), category="error") - return redirect(url_for('web.show_book', book_id=book.id)) + log.error_or_exception("Database error: {}".format(e)) + flash(_(u"Database error: %(error)s.", error=e.orig), category="error") + return False # return redirect(url_for('web.show_book', book_id=book.id)) # Queue uploader info link = '{}'.format(url_for('web.show_book', book_id=book.id), escape(book.title)) - uploadText=_(u"File format %(ext)s added to %(book)s", ext=file_ext.upper(), book=link) - WorkerThread.add(current_user.name, TaskUpload(uploadText, escape(book.title))) + upload_text = N_(u"File format %(ext)s added to %(book)s", ext=file_ext.upper(), book=link) + WorkerThread.add(current_user.name, TaskUpload(upload_text, escape(book.title))) return uploader.process( saved_filename, *os.path.splitext(requested_file.filename), rarExecutable=config.config_rarfile_location) + return None -def upload_cover(request, book): - if 'btn-upload-cover' in request.files: - requested_file = request.files['btn-upload-cover'] +def upload_cover(cover_request, book): + requested_file = cover_request.files.get('btn-upload-cover', None) + if requested_file: # check for empty request if requested_file.filename != '': if not current_user.role_upload(): - abort(403) + flash(_(u"User has no rights to upload cover"), category="error") + return False ret, message = helper.save_cover(requested_file, book.path) if ret is True: + helper.replace_cover_thumbnail_cache(book.id) return True else: flash(message, category="error") @@ -706,26 +722,7 @@ def handle_title_on_edit(book, book_title): def handle_author_on_edit(book, author_name, update_stored=True): # handle author(s) - # renamed = False - input_authors = author_name.split('&') - input_authors = list(map(lambda it: it.strip().replace(',', '|'), input_authors)) - # Remove duplicates in authors list - input_authors = helper.uniq(input_authors) - # we have all author names now - if input_authors == ['']: - input_authors = [_(u'Unknown')] # prevent empty Author - - renamed = list() - for in_aut in input_authors: - renamed_author = calibre_db.session.query(db.Authors).filter(db.Authors.name == in_aut).first() - if renamed_author and in_aut != renamed_author.name: - renamed.append(renamed_author.name) - all_books = calibre_db.session.query(db.Books) \ - .filter(db.Books.authors.any(db.Authors.name == renamed_author.name)).all() - sorted_renamed_author = helper.get_sorted_author(renamed_author.name) - sorted_old_author = helper.get_sorted_author(in_aut) - for one_book in all_books: - one_book.author_sort = one_book.author_sort.replace(sorted_renamed_author, sorted_old_author) + input_authors, renamed = prepare_authors(author_name) change = modify_database_object(input_authors, book.authors, db.Authors, calibre_db.session, 'author') @@ -746,135 +743,161 @@ def handle_author_on_edit(book, author_name, update_stored=True): return input_authors, change, renamed -@editbook.route("/admin/book/", methods=['GET', 'POST']) +@EditBook.route("/admin/book/", methods=['GET']) +@login_required_if_no_ano +@edit_required +def show_edit_book(book_id): + return render_edit_book(book_id) + + +@EditBook.route("/admin/book/", methods=['POST']) @login_required_if_no_ano @edit_required def edit_book(book_id): - modif_date = False + modify_date = False + edit_error = False # create the function for sorting... - try: - calibre_db.update_title_sort(config) - except sqliteOperationalError as e: - log.debug_or_exception(e) - calibre_db.session.rollback() - - # Show form - if request.method != 'POST': - return render_edit_book(book_id) + #try: + calibre_db.update_title_sort(config) + #except sqliteOperationalError as e: + # log.error_or_exception(e) + # calibre_db.session.rollback() book = calibre_db.get_filtered_book(book_id, allow_show_archived=True) - # Book not found if not book: - flash(_(u"Oops! Selected book title is unavailable. File does not exist or is not accessible"), category="error") + flash(_(u"Oops! Selected book title is unavailable. File does not exist or is not accessible"), + category="error") return redirect(url_for("web.index")) - meta = upload_single_file(request, book, book_id) - if upload_cover(request, book) is True: - book.has_cover = 1 - modif_date = True + to_save = request.form.to_dict() + try: - to_save = request.form.to_dict() - merge_metadata(to_save, meta) - # Update book + # Update folder of book on local disk edited_books_id = None - - # handle book title + title_author_error = None + # handle book title change title_change = handle_title_on_edit(book, to_save["book_title"]) - - input_authors, authorchange, renamed = handle_author_on_edit(book, to_save["author_name"]) - if authorchange or title_change: + # handle book author change + input_authors, author_change, renamed = handle_author_on_edit(book, to_save["author_name"]) + if author_change or title_change: edited_books_id = book.id - modif_date = True + modify_date = True + title_author_error = helper.update_dir_structure(edited_books_id, + config.config_calibre_dir, + input_authors[0], + renamed_author=renamed) + if title_author_error: + flash(title_author_error, category="error") + calibre_db.session.rollback() + book = calibre_db.get_filtered_book(book_id, allow_show_archived=True) + # handle upload other formats from local disk + meta = upload_single_file(request, book, book_id) + # only merge metadata if file was uploaded and no error occurred (meta equals not false or none) + if meta: + merge_metadata(to_save, meta) + # handle upload covers from local disk + cover_upload_success = upload_cover(request, book) + if cover_upload_success: + book.has_cover = 1 + modify_date = True + + # upload new covers or new file formats to google drive if config.config_use_google_drive: gdriveutils.updateGdriveCalibreFromLocal() - error = False - if edited_books_id: - error = helper.update_dir_structure(edited_books_id, config.config_calibre_dir, input_authors[0], - renamed_author=renamed) - - if not error: - if "cover_url" in to_save: - if to_save["cover_url"]: - if not current_user.role_upload(): - calibre_db.session.rollback() - return "", 403 - if to_save["cover_url"].endswith('/static/generic_cover.jpg'): - book.has_cover = 0 - else: - result, error = helper.save_cover_from_url(to_save["cover_url"], book.path) - if result is True: - book.has_cover = 1 - modif_date = True - else: - flash(error, category="error") - - # Add default series_index to book - modif_date |= edit_book_series_index(to_save["series_index"], book) - # Handle book comments/description - modif_date |= edit_book_comments(Markup(to_save['description']).unescape(), book) - # Handle identifiers - input_identifiers = identifier_list(to_save, book) - modification, warning = modify_identifiers(input_identifiers, book.identifiers, calibre_db.session) - if warning: - flash(_("Identifiers are not Case Sensitive, Overwriting Old Identifier"), category="warning") - modif_date |= modification - # Handle book tags - modif_date |= edit_book_tags(to_save['tags'], book) - # Handle book series - modif_date |= edit_book_series(to_save["series"], book) - # handle book publisher - modif_date |= edit_book_publisher(to_save['publisher'], book) - # handle book languages - modif_date |= edit_book_languages(to_save['languages'], book) - # handle book ratings - modif_date |= edit_book_ratings(to_save, book) - # handle cc data - modif_date |= edit_all_cc_data(book_id, book, to_save) - - if to_save["pubdate"]: - try: - book.pubdate = datetime.strptime(to_save["pubdate"], "%Y-%m-%d") - except ValueError: - book.pubdate = db.Books.DEFAULT_PUBDATE + if to_save.get("cover_url", None): + if not current_user.role_upload(): + edit_error = True + flash(_(u"User has no rights to upload cover"), category="error") + if to_save["cover_url"].endswith('/static/generic_cover.jpg'): + book.has_cover = 0 else: + result, error = helper.save_cover_from_url(to_save["cover_url"].strip(), book.path) + if result is True: + book.has_cover = 1 + modify_date = True + helper.replace_cover_thumbnail_cache(book.id) + else: + flash(error, category="error") + + # Add default series_index to book + modify_date |= edit_book_series_index(to_save["series_index"], book) + # Handle book comments/description + modify_date |= edit_book_comments(Markup(to_save['description']).unescape(), book) + # Handle identifiers + input_identifiers = identifier_list(to_save, book) + modification, warning = modify_identifiers(input_identifiers, book.identifiers, calibre_db.session) + if warning: + flash(_("Identifiers are not Case Sensitive, Overwriting Old Identifier"), category="warning") + modify_date |= modification + # Handle book tags + modify_date |= edit_book_tags(to_save['tags'], book) + # Handle book series + modify_date |= edit_book_series(to_save["series"], book) + # handle book publisher + modify_date |= edit_book_publisher(to_save['publisher'], book) + # handle book languages + try: + modify_date |= edit_book_languages(to_save['languages'], book) + except ValueError as e: + flash(str(e), category="error") + edit_error = True + # handle book ratings + modify_date |= edit_book_ratings(to_save, book) + # handle cc data + modify_date |= edit_all_cc_data(book_id, book, to_save) + + if to_save.get("pubdate", None): + try: + book.pubdate = datetime.strptime(to_save["pubdate"], "%Y-%m-%d") + except ValueError as e: book.pubdate = db.Books.DEFAULT_PUBDATE - - if modif_date: - book.last_modified = datetime.utcnow() - kobo_sync_status.remove_synced_book(edited_books_id, all=True) - - calibre_db.session.merge(book) - calibre_db.session.commit() - if config.config_use_google_drive: - gdriveutils.updateGdriveCalibreFromLocal() - if "detail_view" in to_save: - return redirect(url_for('web.show_book', book_id=book.id)) - else: - flash(_("Metadata successfully updated"), category="success") - return render_edit_book(book_id) + flash(str(e), category="error") + edit_error = True + else: + book.pubdate = db.Books.DEFAULT_PUBDATE + + if modify_date: + book.last_modified = datetime.utcnow() + kobo_sync_status.remove_synced_book(edited_books_id, all=True) + + calibre_db.session.merge(book) + calibre_db.session.commit() + if config.config_use_google_drive: + gdriveutils.updateGdriveCalibreFromLocal() + if meta is not False \ + and edit_error is not True \ + and title_author_error is not True \ + and cover_upload_success is not False: + flash(_("Metadata successfully updated"), category="success") + if "detail_view" in to_save: + return redirect(url_for('web.show_book', book_id=book.id)) else: - calibre_db.session.rollback() - flash(error, category="error") return render_edit_book(book_id) except ValueError as e: + log.error_or_exception("Error: {}".format(e)) calibre_db.session.rollback() flash(str(e), category="error") return redirect(url_for('web.show_book', book_id=book.id)) - except Exception as ex: - log.debug_or_exception(ex) + except (OperationalError, IntegrityError) as e: + log.error_or_exception("Database error: {}".format(e)) calibre_db.session.rollback() - flash(_("Error editing book, please check logfile for details"), category="error") + flash(_(u"Database error: %(error)s.", error=e.orig), category="error") + return redirect(url_for('web.show_book', book_id=book.id)) + except Exception as ex: + log.error_or_exception(ex) + calibre_db.session.rollback() + flash(_("Error editing book: {}".format(ex)), category="error") return redirect(url_for('web.show_book', book_id=book.id)) def merge_metadata(to_save, meta): - if to_save['author_name'] == _(u'Unknown'): + if to_save.get('author_name', "") == _(u'Unknown'): to_save['author_name'] = '' - if to_save['book_title'] == _(u'Unknown'): + if to_save.get('book_title', "") == _(u'Unknown'): to_save['book_title'] = '' for s_field, m_field in [ ('tags', 'tags'), ('author_name', 'author'), ('series', 'series'), @@ -900,14 +923,7 @@ def identifier_list(to_save, book): return result -def prepare_authors_on_upload(title, authr): - if title != _(u'Unknown') and authr != _(u'Unknown'): - entry = calibre_db.check_exists_book(authr, title) - if entry: - log.info("Uploaded book probably exists in library") - flash(_(u"Uploaded book probably exists in the library, consider to change before upload new: ") - + Markup(render_title_template('book_exists_flash.html', entry=entry)), category="warning") - +def prepare_authors(authr): # handle authors input_authors = authr.split('&') # handle_authors(input_authors) @@ -930,6 +946,18 @@ def prepare_authors_on_upload(title, authr): sorted_old_author = helper.get_sorted_author(in_aut) for one_book in all_books: one_book.author_sort = one_book.author_sort.replace(sorted_renamed_author, sorted_old_author) + return input_authors, renamed + + +def prepare_authors_on_upload(title, authr): + if title != _(u'Unknown') and authr != _(u'Unknown'): + entry = calibre_db.check_exists_book(authr, title) + if entry: + log.info("Uploaded book probably exists in library") + flash(_(u"Uploaded book probably exists in the library, consider to change before upload new: ") + + Markup(render_title_template('book_exists_flash.html', entry=entry)), category="warning") + + input_authors, renamed = prepare_authors(authr) sort_authors_list = list() db_author = None @@ -950,7 +978,7 @@ def prepare_authors_on_upload(title, authr): return sort_authors, input_authors, db_author, renamed -def create_book_on_upload(modif_date, meta): +def create_book_on_upload(modify_date, meta): title = meta.title authr = meta.author sort_authors, input_authors, db_author, renamed_authors = prepare_authors_on_upload(title, authr) @@ -958,34 +986,39 @@ def create_book_on_upload(modif_date, meta): title_dir = helper.get_valid_filename(title, chars=96) author_dir = helper.get_valid_filename(db_author.name, chars=96) - # combine path and normalize path from windows systems + # combine path and normalize path from Windows systems path = os.path.join(author_dir, title_dir).replace('\\', '/') + try: + pubdate = datetime.strptime(meta.pubdate[:10], "%Y-%m-%d") + except ValueError: + pubdate = datetime(101, 1, 1) + # Calibre adds books with utc as timezone - db_book = db.Books(title, "", sort_authors, datetime.utcnow(), datetime(101, 1, 1), + db_book = db.Books(title, "", sort_authors, datetime.utcnow(), pubdate, '1', datetime.utcnow(), path, meta.cover, db_author, [], "") - modif_date |= modify_database_object(input_authors, db_book.authors, db.Authors, calibre_db.session, - 'author') + modify_date |= modify_database_object(input_authors, db_book.authors, db.Authors, calibre_db.session, + 'author') # Add series_index to book - modif_date |= edit_book_series_index(meta.series_id, db_book) + modify_date |= edit_book_series_index(meta.series_id, db_book) # add languages - invalid=[] - modif_date |= edit_book_languages(meta.languages, db_book, upload=True, invalid=invalid) + invalid = [] + modify_date |= edit_book_languages(meta.languages, db_book, upload_mode=True, invalid=invalid) if invalid: - for l in invalid: - flash(_(u"'%(langname)s' is not a valid language", langname=l), category="warning") + for lang in invalid: + flash(_(u"'%(langname)s' is not a valid language", langname=lang), category="warning") # handle tags - modif_date |= edit_book_tags(meta.tags, db_book) + modify_date |= edit_book_tags(meta.tags, db_book) # handle publisher - modif_date |= edit_book_publisher(meta.publisher, db_book) + modify_date |= edit_book_publisher(meta.publisher, db_book) # handle series - modif_date |= edit_book_series(meta.series, db_book) + modify_date |= edit_book_series(meta.series, db_book) # Add file to book file_size = os.path.getsize(meta.file_path) @@ -995,8 +1028,19 @@ def create_book_on_upload(modif_date, meta): # flush content, get db_book.id available calibre_db.session.flush() + + # Handle identifiers now that db_book.id is available + identifier_list = [] + for type_key, type_value in meta.identifiers: + identifier_list.append(db.Identifiers(type_value, type_key, db_book.id)) + modification, warning = modify_identifiers(identifier_list, db_book.identifiers, calibre_db.session) + if warning: + flash(_("Identifiers are not Case Sensitive, Overwriting Old Identifier"), category="warning") + modify_date |= modification + return db_book, input_authors, title_dir, renamed_authors + def file_handling_on_upload(requested_file): # check if file extension is correct if '.' in requested_file.filename: @@ -1024,23 +1068,23 @@ def file_handling_on_upload(requested_file): def move_coverfile(meta, db_book): # move cover to final directory, including book id if meta.cover: - coverfile = meta.cover + cover_file = meta.cover else: - coverfile = os.path.join(constants.STATIC_DIR, 'generic_cover.jpg') - new_coverpath = os.path.join(config.config_calibre_dir, db_book.path) + cover_file = os.path.join(constants.STATIC_DIR, 'generic_cover.jpg') + new_cover_path = os.path.join(config.config_calibre_dir, db_book.path) try: - os.makedirs(new_coverpath, exist_ok=True) - copyfile(coverfile, os.path.join(new_coverpath, "cover.jpg")) + os.makedirs(new_cover_path, exist_ok=True) + copyfile(cover_file, os.path.join(new_cover_path, "cover.jpg")) if meta.cover: os.unlink(meta.cover) except OSError as e: - log.error("Failed to move cover file %s: %s", new_coverpath, e) - flash(_(u"Failed to Move Cover File %(file)s: %(error)s", file=new_coverpath, + log.error("Failed to move cover file %s: %s", new_cover_path, e) + flash(_(u"Failed to Move Cover File %(file)s: %(error)s", file=new_cover_path, error=e), category="error") -@editbook.route("/upload", methods=["POST"]) +@EditBook.route("/upload", methods=["POST"]) @login_required_if_no_ano @upload_required def upload(): @@ -1049,7 +1093,7 @@ def upload(): if request.method == 'POST' and 'btn-upload' in request.files: for requested_file in request.files.getlist("btn-upload"): try: - modif_date = False + modify_date = False # create the function for sorting... calibre_db.update_title_sort(config) calibre_db.session.connection().connection.connection.create_function('uuid4', 0, lambda: str(uuid4())) @@ -1058,10 +1102,10 @@ def upload(): if error: return error - db_book, input_authors, title_dir, renamed_authors = create_book_on_upload(modif_date, meta) + db_book, input_authors, title_dir, renamed_authors = create_book_on_upload(modify_date, meta) - # Comments needs book id therefore only possible after flush - modif_date |= edit_book_comments(Markup(meta.description).unescape(), db_book) + # Comments need book id therefore only possible after flush + modify_date |= edit_book_comments(Markup(meta.description).unescape(), db_book) book_id = db_book.id title = db_book.title @@ -1091,24 +1135,25 @@ def upload(): if error: flash(error, category="error") link = '{}'.format(url_for('web.show_book', book_id=book_id), escape(title)) - uploadText = _(u"File %(file)s uploaded", file=link) - WorkerThread.add(current_user.name, TaskUpload(uploadText, escape(title))) + upload_text = N_(u"File %(file)s uploaded", file=link) + WorkerThread.add(current_user.name, TaskUpload(upload_text, escape(title))) + helper.add_book_to_thumbnail_cache(book_id) if len(request.files.getlist("btn-upload")) < 2: if current_user.role_edit() or current_user.role_admin(): - resp = {"location": url_for('editbook.edit_book', book_id=book_id)} + resp = {"location": url_for('edit-book.show_edit_book', book_id=book_id)} return Response(json.dumps(resp), mimetype='application/json') else: resp = {"location": url_for('web.show_book', book_id=book_id)} return Response(json.dumps(resp), mimetype='application/json') except (OperationalError, IntegrityError) as e: calibre_db.session.rollback() - log.error("Database error: %s", e) - flash(_(u"Database error: %(error)s.", error=e), category="error") + log.error_or_exception("Database error: {}".format(e)) + flash(_(u"Database error: %(error)s.", error=e.orig), category="error") return Response(json.dumps({"location": url_for("web.index")}), mimetype='application/json') -@editbook.route("/admin/book/convert/", methods=['POST']) +@EditBook.route("/admin/book/convert/", methods=['POST']) @login_required_if_no_ano @edit_required def convert_bookformat(book_id): @@ -1118,7 +1163,7 @@ def convert_bookformat(book_id): if (book_format_from is None) or (book_format_to is None): flash(_(u"Source or destination format for conversion missing"), category="error") - return redirect(url_for('editbook.edit_book', book_id=book_id)) + return redirect(url_for('edit-book.show_edit_book', book_id=book_id)) log.info('converting: book id: %s from: %s to: %s', book_id, book_format_from, book_format_to) rtn = helper.convert_book_format(book_id, config.config_calibre_dir, book_format_from.upper(), @@ -1126,118 +1171,139 @@ def convert_bookformat(book_id): if rtn is None: flash(_(u"Book successfully queued for converting to %(book_format)s", - book_format=book_format_to), - category="success") + book_format=book_format_to), + category="success") else: flash(_(u"There was an error converting this book: %(res)s", res=rtn), category="error") - return redirect(url_for('editbook.edit_book', book_id=book_id)) + return redirect(url_for('edit-book.show_edit_book', book_id=book_id)) -@editbook.route("/ajax/getcustomenum/") + +@EditBook.route("/ajax/getcustomenum/") @login_required def table_get_custom_enum(c_id): ret = list() - cc = (calibre_db.session.query(db.Custom_Columns) - .filter(db.Custom_Columns.id == c_id) - .filter(db.Custom_Columns.datatype.notin_(db.cc_exceptions)).one_or_none()) + cc = (calibre_db.session.query(db.CustomColumns) + .filter(db.CustomColumns.id == c_id) + .filter(db.CustomColumns.datatype.notin_(db.cc_exceptions)).one_or_none()) ret.append({'value': "", 'text': ""}) for idx, en in enumerate(cc.get_display_dict()['enum_values']): ret.append({'value': en, 'text': en}) return json.dumps(ret) -@editbook.route("/ajax/editbooks/", methods=['POST']) +@EditBook.route("/ajax/editbooks/", methods=['POST']) @login_required_if_no_ano @edit_required def edit_list_book(param): vals = request.form.to_dict() book = calibre_db.get_book(vals['pk']) - # ret = "" - if param == 'series_index': - edit_book_series_index(vals['value'], book) - ret = Response(json.dumps({'success': True, 'newValue': book.series_index}), mimetype='application/json') - elif param == 'tags': - edit_book_tags(vals['value'], book) - ret = Response(json.dumps({'success': True, 'newValue': ', '.join([tag.name for tag in book.tags])}), - mimetype='application/json') - elif param == 'series': - edit_book_series(vals['value'], book) - ret = Response(json.dumps({'success': True, 'newValue': ', '.join([serie.name for serie in book.series])}), - mimetype='application/json') - elif param == 'publishers': - edit_book_publisher(vals['value'], book) - ret = Response(json.dumps({'success': True, - 'newValue': ', '.join([publisher.name for publisher in book.publishers])}), - mimetype='application/json') - elif param == 'languages': - invalid = list() - edit_book_languages(vals['value'], book, invalid=invalid) - if invalid: - ret = Response(json.dumps({'success': False, - 'msg': 'Invalid languages in request: {}'.format(','.join(invalid))}), - mimetype='application/json') - else: - lang_names = list() - for lang in book.languages: - lang_names.append(isoLanguages.get_language_name(get_locale(), lang.lang_code)) - ret = Response(json.dumps({'success': True, 'newValue': ', '.join(lang_names)}), - mimetype='application/json') - elif param == 'author_sort': - book.author_sort = vals['value'] - ret = Response(json.dumps({'success': True, 'newValue': book.author_sort}), - mimetype='application/json') - elif param == 'title': - sort = book.sort - handle_title_on_edit(book, vals.get('value', "")) - helper.update_dir_structure(book.id, config.config_calibre_dir) - ret = Response(json.dumps({'success': True, 'newValue': book.title}), - mimetype='application/json') - elif param == 'sort': - book.sort = vals['value'] - ret = Response(json.dumps({'success': True, 'newValue': book.sort}), - mimetype='application/json') - elif param == 'comments': - edit_book_comments(vals['value'], book) - ret = Response(json.dumps({'success': True, 'newValue': book.comments[0].text}), - mimetype='application/json') - elif param == 'authors': - input_authors, __, renamed = handle_author_on_edit(book, vals['value'], vals.get('checkA', None) == "true") - helper.update_dir_structure(book.id, config.config_calibre_dir, input_authors[0], renamed_author=renamed) - ret = Response(json.dumps({'success': True, - 'newValue': ' & '.join([author.replace('|',',') for author in input_authors])}), - mimetype='application/json') - elif param == 'is_archived': - change_archived_books(book.id, vals['value'] == "True") - ret = "" - elif param == 'read_status': - ret = helper.edit_book_read_status(book.id, vals['value'] == "True") - if ret: - return ret, 400 - elif param.startswith("custom_column_"): - new_val = dict() - new_val[param] = vals['value'] - edit_single_cc_data(book.id, book, param[14:], new_val) - # ToDo: Very hacky find better solution - if vals['value'] in ["True", "False"]: - ret = "" - else: - ret = Response(json.dumps({'success': True, 'newValue': vals['value']}), - mimetype='application/json') - else: - return _("Parameter not found"), 400 - book.last_modified = datetime.utcnow() + sort_param = "" + ret = "" try: + if param == 'series_index': + edit_book_series_index(vals['value'], book) + ret = Response(json.dumps({'success': True, 'newValue': book.series_index}), mimetype='application/json') + elif param == 'tags': + edit_book_tags(vals['value'], book) + ret = Response(json.dumps({'success': True, 'newValue': ', '.join([tag.name for tag in book.tags])}), + mimetype='application/json') + elif param == 'series': + edit_book_series(vals['value'], book) + ret = Response(json.dumps({'success': True, 'newValue': ', '.join([serie.name for serie in book.series])}), + mimetype='application/json') + elif param == 'publishers': + edit_book_publisher(vals['value'], book) + ret = Response(json.dumps({'success': True, + 'newValue': ', '.join([publisher.name for publisher in book.publishers])}), + mimetype='application/json') + elif param == 'languages': + invalid = list() + edit_book_languages(vals['value'], book, invalid=invalid) + if invalid: + ret = Response(json.dumps({'success': False, + 'msg': 'Invalid languages in request: {}'.format(','.join(invalid))}), + mimetype='application/json') + else: + lang_names = list() + for lang in book.languages: + lang_names.append(isoLanguages.get_language_name(get_locale(), lang.lang_code)) + ret = Response(json.dumps({'success': True, 'newValue': ', '.join(lang_names)}), + mimetype='application/json') + elif param == 'author_sort': + book.author_sort = vals['value'] + ret = Response(json.dumps({'success': True, 'newValue': book.author_sort}), + mimetype='application/json') + elif param == 'title': + sort_param = book.sort + if handle_title_on_edit(book, vals.get('value', "")): + rename_error = helper.update_dir_structure(book.id, config.config_calibre_dir) + if not rename_error: + ret = Response(json.dumps({'success': True, 'newValue': book.title}), + mimetype='application/json') + else: + ret = Response(json.dumps({'success': False, + 'msg': rename_error}), + mimetype='application/json') + elif param == 'sort': + book.sort = vals['value'] + ret = Response(json.dumps({'success': True, 'newValue': book.sort}), + mimetype='application/json') + elif param == 'comments': + edit_book_comments(vals['value'], book) + ret = Response(json.dumps({'success': True, 'newValue': book.comments[0].text}), + mimetype='application/json') + elif param == 'authors': + input_authors, __, renamed = handle_author_on_edit(book, vals['value'], vals.get('checkA', None) == "true") + rename_error = helper.update_dir_structure(book.id, config.config_calibre_dir, input_authors[0], + renamed_author=renamed) + if not rename_error: + ret = Response(json.dumps({ + 'success': True, + 'newValue': ' & '.join([author.replace('|', ',') for author in input_authors])}), + mimetype='application/json') + else: + ret = Response(json.dumps({'success': False, + 'msg': rename_error}), + mimetype='application/json') + elif param == 'is_archived': + is_archived = change_archived_books(book.id, vals['value'] == "True", + message="Book {} archive bit set to: {}".format(book.id, vals['value'])) + if is_archived: + kobo_sync_status.remove_synced_book(book.id) + return "" + elif param == 'read_status': + ret = helper.edit_book_read_status(book.id, vals['value'] == "True") + if ret: + return ret, 400 + elif param.startswith("custom_column_"): + new_val = dict() + new_val[param] = vals['value'] + edit_single_cc_data(book.id, book, param[14:], new_val) + # ToDo: Very hacky find better solution + if vals['value'] in ["True", "False"]: + ret = "" + else: + ret = Response(json.dumps({'success': True, 'newValue': vals['value']}), + mimetype='application/json') + else: + return _("Parameter not found"), 400 + book.last_modified = datetime.utcnow() + calibre_db.session.commit() # revert change for sort if automatic fields link is deactivated if param == 'title' and vals.get('checkT') == "false": - book.sort = sort + book.sort = sort_param calibre_db.session.commit() except (OperationalError, IntegrityError) as e: calibre_db.session.rollback() - log.error("Database error: %s", e) + log.error_or_exception("Database error: {}".format(e)) + ret = Response(json.dumps({'success': False, + 'msg': 'Database error: {}'.format(e.orig)}), + mimetype='application/json') return ret -@editbook.route("/ajax/sort_value//") +@EditBook.route("/ajax/sort_value//") @login_required def get_sorted_entry(field, bookid): if field in ['title', 'authors', 'sort', 'author_sort']: @@ -1254,7 +1320,7 @@ def get_sorted_entry(field, bookid): return "" -@editbook.route("/ajax/simulatemerge", methods=['POST']) +@EditBook.route("/ajax/simulatemerge", methods=['POST']) @login_required @edit_required def simulate_merge_list_book(): @@ -1263,14 +1329,14 @@ def simulate_merge_list_book(): to_book = calibre_db.get_book(vals[0]).title vals.pop(0) if to_book: + from_book = [] for book_id in vals: - from_book = [] from_book.append(calibre_db.get_book(book_id).title) return json.dumps({'to': to_book, 'from': from_book}) return "" -@editbook.route("/ajax/mergebooks", methods=['POST']) +@EditBook.route("/ajax/mergebooks", methods=['POST']) @login_required @edit_required def merge_list_book(): @@ -1283,8 +1349,9 @@ def merge_list_book(): if to_book: for file in to_book.data: to_file.append(file.format) - to_name = helper.get_valid_filename(to_book.title, chars=96) + ' - ' + \ - helper.get_valid_filename(to_book.authors[0].name, chars=96) + to_name = helper.get_valid_filename(to_book.title, + chars=96) + ' - ' + helper.get_valid_filename(to_book.authors[0].name, + chars=96) for book_id in vals: from_book = calibre_db.get_book(book_id) if from_book: @@ -1302,19 +1369,20 @@ def merge_list_book(): element.format, element.uncompressed_size, to_name)) - delete_book_from_table(from_book.id,"", True) + delete_book_from_table(from_book.id, "", True) return json.dumps({'success': True}) return "" -@editbook.route("/ajax/xchange", methods=['POST']) +@EditBook.route("/ajax/xchange", methods=['POST']) @login_required @edit_required def table_xchange_author_title(): vals = request.get_json().get('xchange') + edited_books_id = False if vals: for val in vals: - modif_date = False + modify_date = False book = calibre_db.get_book(val) authors = book.title book.authors = calibre_db.order_authors([book]) @@ -1323,24 +1391,25 @@ def table_xchange_author_title(): author_names.append(authr.name.replace('|', ',')) title_change = handle_title_on_edit(book, " ".join(author_names)) - input_authors, authorchange, renamed = handle_author_on_edit(book, authors) - if authorchange or title_change: + input_authors, author_change, renamed = handle_author_on_edit(book, authors) + if author_change or title_change: edited_books_id = book.id - modif_date = True + modify_date = True if config.config_use_google_drive: gdriveutils.updateGdriveCalibreFromLocal() if edited_books_id: - helper.update_dir_structure(edited_books_id, config.config_calibre_dir, input_authors[0], - renamed_author=renamed) - if modif_date: + # toDo: Handle error + edit_error = helper.update_dir_structure(edited_books_id, config.config_calibre_dir, input_authors[0], + renamed_author=renamed) + if modify_date: book.last_modified = datetime.utcnow() try: calibre_db.session.commit() except (OperationalError, IntegrityError) as e: calibre_db.session.rollback() - log.error("Database error: %s", e) + log.error_or_exception("Database error: %s", e) return json.dumps({'success': False}) if config.config_use_google_drive: diff --git a/cps/epub.py b/cps/epub.py index b436a755..d358d038 100644 --- a/cps/epub.py +++ b/cps/epub.py @@ -20,23 +20,26 @@ import os import zipfile from lxml import etree -from . import isoLanguages +from . import isoLanguages, cover from .helper import split_authors from .constants import BookMeta -def extract_cover(zip_file, cover_file, cover_path, tmp_file_name): +def _extract_cover(zip_file, cover_file, cover_path, tmp_file_name): if cover_file is None: return None else: + cf = extension = None zip_cover_path = os.path.join(cover_path, cover_file).replace('\\', '/') - cf = zip_file.read(zip_cover_path) + prefix = os.path.splitext(tmp_file_name)[0] tmp_cover_name = prefix + '.' + os.path.basename(zip_cover_path) - image = open(tmp_cover_name, 'wb') - image.write(cf) - image.close() - return tmp_cover_name + ext = os.path.splitext(tmp_cover_name) + if len(ext) > 1: + extension = ext[1].lower() + if extension in cover.COVER_EXTENSIONS: + cf = zip_file.read(zip_cover_path) + return cover.cover_processing(tmp_file_name, cf, extension) def get_epub_info(tmp_file_path, original_file_name, original_file_extension): @@ -50,31 +53,39 @@ def get_epub_info(tmp_file_path, original_file_name, original_file_extension): txt = epub_zip.read('META-INF/container.xml') tree = etree.fromstring(txt) - cfname = tree.xpath('n:rootfiles/n:rootfile/@full-path', namespaces=ns)[0] - cf = epub_zip.read(cfname) + cf_name = tree.xpath('n:rootfiles/n:rootfile/@full-path', namespaces=ns)[0] + cf = epub_zip.read(cf_name) tree = etree.fromstring(cf) - coverpath = os.path.dirname(cfname) + cover_path = os.path.dirname(cf_name) p = tree.xpath('/pkg:package/pkg:metadata', namespaces=ns)[0] epub_metadata = {} - for s in ['title', 'description', 'creator', 'language', 'subject']: + for s in ['title', 'description', 'creator', 'language', 'subject', 'publisher', 'date']: tmp = p.xpath('dc:%s/text()' % s, namespaces=ns) if len(tmp) > 0: if s == 'creator': epub_metadata[s] = ' & '.join(split_authors(tmp)) elif s == 'subject': epub_metadata[s] = ', '.join(tmp) + elif s == 'date': + epub_metadata[s] = tmp[0][:10] else: epub_metadata[s] = tmp[0] else: - epub_metadata[s] = u'Unknown' + epub_metadata[s] = 'Unknown' - if epub_metadata['subject'] == u'Unknown': + if epub_metadata['subject'] == 'Unknown': epub_metadata['subject'] = '' + if epub_metadata['publisher'] == u'Unknown': + epub_metadata['publisher'] = '' + + if epub_metadata['date'] == u'Unknown': + epub_metadata['date'] = '' + if epub_metadata['description'] == u'Unknown': description = tree.xpath("//*[local-name() = 'description']/text()") if len(description) > 0: @@ -87,7 +98,15 @@ def get_epub_info(tmp_file_path, original_file_name, original_file_extension): epub_metadata = parse_epub_series(ns, tree, epub_metadata) - cover_file = parse_epub_cover(ns, tree, epub_zip, coverpath, tmp_file_path) + cover_file = parse_epub_cover(ns, tree, epub_zip, cover_path, tmp_file_path) + + identifiers = [] + for node in p.xpath('dc:identifier', namespaces=ns): + identifier_name=node.attrib.values()[-1]; + identifier_value=node.text; + if identifier_name in ('uuid','calibre'): + continue; + identifiers.append( [identifier_name, identifier_value] ) if not epub_metadata['title']: title = original_file_name @@ -105,15 +124,20 @@ def get_epub_info(tmp_file_path, original_file_name, original_file_extension): series=epub_metadata['series'].encode('utf-8').decode('utf-8'), series_id=epub_metadata['series_id'].encode('utf-8').decode('utf-8'), languages=epub_metadata['language'], - publisher="") + publisher=epub_metadata['publisher'].encode('utf-8').decode('utf-8'), + pubdate=epub_metadata['date'], + identifiers=identifiers) def parse_epub_cover(ns, tree, epub_zip, cover_path, tmp_file_path): cover_section = tree.xpath("/pkg:package/pkg:manifest/pkg:item[@id='cover-image']/@href", namespaces=ns) cover_file = None - if len(cover_section) > 0: - cover_file = extract_cover(epub_zip, cover_section[0], cover_path, tmp_file_path) - else: + # if len(cover_section) > 0: + for cs in cover_section: + cover_file = _extract_cover(epub_zip, cs, cover_path, tmp_file_path) + if cover_file: + break + if not cover_file: meta_cover = tree.xpath("/pkg:package/pkg:metadata/pkg:meta[@name='cover']/@content", namespaces=ns) if len(meta_cover) > 0: cover_section = tree.xpath( @@ -123,10 +147,10 @@ def parse_epub_cover(ns, tree, epub_zip, cover_path, tmp_file_path): "/pkg:package/pkg:manifest/pkg:item[@properties='" + meta_cover[0] + "']/@href", namespaces=ns) else: cover_section = tree.xpath("/pkg:package/pkg:guide/pkg:reference/@href", namespaces=ns) - if len(cover_section) > 0: - filetype = cover_section[0].rsplit('.', 1)[-1] + for cs in cover_section: + filetype = cs.rsplit('.', 1)[-1] if filetype == "xhtml" or filetype == "html": # if cover is (x)html format - markup = epub_zip.read(os.path.join(cover_path, cover_section[0])) + markup = epub_zip.read(os.path.join(cover_path, cs)) markup_tree = etree.fromstring(markup) # no matter xhtml or html with no namespace img_src = markup_tree.xpath("//*[local-name() = 'img']/@src") @@ -137,9 +161,10 @@ def parse_epub_cover(ns, tree, epub_zip, cover_path, tmp_file_path): # img_src maybe start with "../"" so fullpath join then relpath to cwd filename = os.path.relpath(os.path.join(os.path.dirname(os.path.join(cover_path, cover_section[0])), img_src[0])) - cover_file = extract_cover(epub_zip, filename, "", tmp_file_path) + cover_file = _extract_cover(epub_zip, filename, "", tmp_file_path) else: - cover_file = extract_cover(epub_zip, cover_section[0], cover_path, tmp_file_path) + cover_file = _extract_cover(epub_zip, cs, cover_path, tmp_file_path) + if cover_file: break return cover_file diff --git a/cps/error_handler.py b/cps/error_handler.py index 37b7500e..67252a66 100644 --- a/cps/error_handler.py +++ b/cps/error_handler.py @@ -42,8 +42,9 @@ def error_http(error): def internal_error(error): return render_template('http_error.html', - error_code="Internal Server Error", - error_name=str(error), + error_code="500 Internal Server Error", + error_name='The server encountered an internal error and was unable to complete your ' + 'request. There is an error in the application.', issue=True, unconfigured=False, error_stack=traceback.format_exc().split("\n"), diff --git a/cps/fb2.py b/cps/fb2.py index 21586736..c4b89fd6 100644 --- a/cps/fb2.py +++ b/cps/fb2.py @@ -77,4 +77,6 @@ def get_fb2_info(tmp_file_path, original_file_extension): series="", series_id="", languages="", - publisher="") + publisher="", + pubdate="", + identifiers=[]) diff --git a/cps/fs.py b/cps/fs.py new file mode 100644 index 00000000..2f83378d --- /dev/null +++ b/cps/fs.py @@ -0,0 +1,95 @@ +# -*- coding: utf-8 -*- + +# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) +# Copyright (C) 2020 mmonkey +# +# 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 . import logger +from .constants import CACHE_DIR +from os import makedirs, remove +from os.path import isdir, isfile, join +from shutil import rmtree + + +class FileSystem: + _instance = None + _cache_dir = CACHE_DIR + + def __new__(cls): + if cls._instance is None: + cls._instance = super(FileSystem, cls).__new__(cls) + cls.log = logger.create() + return cls._instance + + def get_cache_dir(self, cache_type=None): + if not isdir(self._cache_dir): + try: + makedirs(self._cache_dir) + except OSError: + self.log.info(f'Failed to create path {self._cache_dir} (Permission denied).') + return False + + path = join(self._cache_dir, cache_type) + if cache_type and not isdir(path): + try: + makedirs(path) + except OSError: + self.log.info(f'Failed to create path {path} (Permission denied).') + return False + + return path if cache_type else self._cache_dir + + def get_cache_file_dir(self, filename, cache_type=None): + path = join(self.get_cache_dir(cache_type), filename[:2]) + if not isdir(path): + try: + makedirs(path) + except OSError: + self.log.info(f'Failed to create path {path} (Permission denied).') + return False + + return path + + def get_cache_file_path(self, filename, cache_type=None): + return join(self.get_cache_file_dir(filename, cache_type), filename) if filename else None + + def get_cache_file_exists(self, filename, cache_type=None): + path = self.get_cache_file_path(filename, cache_type) + return isfile(path) + + def delete_cache_dir(self, cache_type=None): + if not cache_type and isdir(self._cache_dir): + try: + rmtree(self._cache_dir) + except OSError: + self.log.info(f'Failed to delete path {self._cache_dir} (Permission denied).') + return False + + path = join(self._cache_dir, cache_type) + if cache_type and isdir(path): + try: + rmtree(path) + except OSError: + self.log.info(f'Failed to delete path {path} (Permission denied).') + return False + + def delete_cache_file(self, filename, cache_type=None): + path = self.get_cache_file_path(filename, cache_type) + if isfile(path): + try: + remove(path) + except OSError: + self.log.info(f'Failed to delete path {path} (Permission denied).') + return False diff --git a/cps/gdrive.py b/cps/gdrive.py index e782cb9e..60e3d47b 100644 --- a/cps/gdrive.py +++ b/cps/gdrive.py @@ -152,7 +152,7 @@ try: move(os.path.join(tmp_dir, "tmp_metadata.db"), dbpath) calibre_db.reconnect_db(config, ub.app_DB_path) except Exception as ex: - log.debug_or_exception(ex) + log.error_or_exception(ex) return '' except AttributeError: pass diff --git a/cps/gdriveutils.py b/cps/gdriveutils.py index 57f272ff..ee8ee953 100644 --- a/cps/gdriveutils.py +++ b/cps/gdriveutils.py @@ -32,13 +32,9 @@ try: from sqlalchemy.orm import declarative_base except ImportError: from sqlalchemy.ext.declarative import declarative_base -from sqlalchemy.exc import OperationalError, InvalidRequestError +from sqlalchemy.exc import OperationalError, InvalidRequestError, IntegrityError from sqlalchemy.sql.expression import text -#try: -# from six import __version__ as six_version -#except ImportError: -# six_version = "not installed" try: from httplib2 import __version__ as httplib2_version except ImportError: @@ -81,7 +77,7 @@ if gdrive_support: if not logger.is_debug_enabled(): logger.get('googleapiclient.discovery').setLevel(logger.logging.ERROR) else: - log.debug("Cannot import pydrive,httplib2, using gdrive will not work: %s", importError) + log.debug("Cannot import pydrive, httplib2, using gdrive will not work: {}".format(importError)) class Singleton: @@ -141,11 +137,12 @@ class Gdrive: def __init__(self): self.drive = getDrive(gauth=Gauth.Instance().auth) + def is_gdrive_ready(): return os.path.exists(SETTINGS_YAML) and os.path.exists(CREDENTIALS) -engine = create_engine('sqlite:///{0}'.format(cli.gdpath), echo=False) +engine = create_engine('sqlite:///{0}'.format(cli.gd_path), echo=False) Base = declarative_base() # Open session for database connection @@ -193,11 +190,11 @@ def migrate(): session.execute('ALTER TABLE gdrive_ids2 RENAME to gdrive_ids') break -if not os.path.exists(cli.gdpath): +if not os.path.exists(cli.gd_path): try: Base.metadata.create_all(engine) except Exception as ex: - log.error("Error connect to database: {} - {}".format(cli.gdpath, ex)) + log.error("Error connect to database: {} - {}".format(cli.gd_path, ex)) raise migrate() @@ -213,9 +210,9 @@ def getDrive(drive=None, gauth=None): try: gauth.Refresh() except RefreshError as e: - log.error("Google Drive error: %s", e) + log.error("Google Drive error: {}".format(e)) except Exception as ex: - log.debug_or_exception(ex) + log.error_or_exception(ex) else: # Initialize the saved creds gauth.Authorize() @@ -225,7 +222,7 @@ def getDrive(drive=None, gauth=None): try: drive.auth.Refresh() except RefreshError as e: - log.error("Google Drive error: %s", e) + log.error("Google Drive error: {}".format(e)) return drive def listRootFolders(): @@ -234,7 +231,7 @@ def listRootFolders(): folder = "'root' in parents and mimeType = 'application/vnd.google-apps.folder' and trashed = false" fileList = drive.ListFile({'q': folder}).GetList() except (ServerNotFoundError, ssl.SSLError, RefreshError) as e: - log.info("GDrive Error %s" % e) + log.info("GDrive Error {}".format(e)) fileList = [] return fileList @@ -272,8 +269,7 @@ def getEbooksFolderId(drive=None): try: session.commit() except OperationalError as ex: - log.error("gdrive.db DB is not Writeable") - log.debug('Database error: %s', ex) + log.error_or_exception('Database error: {}'.format(ex)) session.rollback() return gDriveId.gdrive_id @@ -289,6 +285,7 @@ def getFile(pathId, fileName, drive): def getFolderId(path, drive): # drive = getDrive(drive) + currentFolderId = None try: currentFolderId = getEbooksFolderId(drive) sqlCheckPath = path if path[-1] == '/' else path + '/' @@ -321,9 +318,8 @@ def getFolderId(path, drive): session.commit() else: currentFolderId = storedPathName.gdrive_id - except OperationalError as ex: - log.error("gdrive.db DB is not Writeable") - log.debug('Database error: %s', ex) + except (OperationalError, IntegrityError) as ex: + log.error_or_exception('Database error: {}'.format(ex)) session.rollback() except ApiRequestError as ex: log.error('{} {}'.format(ex.error['message'], path)) @@ -547,8 +543,7 @@ def deleteDatabaseOnChange(): session.commit() except (OperationalError, InvalidRequestError) as ex: session.rollback() - log.debug('Database error: %s', ex) - log.error(u"GDrive DB is not Writeable") + log.error_or_exception('Database error: {}'.format(ex)) def updateGdriveCalibreFromLocal(): @@ -566,8 +561,7 @@ def updateDatabaseOnEdit(ID,newPath): try: session.commit() except OperationalError as ex: - log.error("gdrive.db DB is not Writeable") - log.debug('Database error: %s', ex) + log.error_or_exception('Database error: {}'.format(ex)) session.rollback() @@ -577,8 +571,7 @@ def deleteDatabaseEntry(ID): try: session.commit() except OperationalError as ex: - log.error("gdrive.db DB is not Writeable") - log.debug('Database error: %s', ex) + log.error_or_exception('Database error: {}'.format(ex)) session.rollback() @@ -599,8 +592,7 @@ def get_cover_via_gdrive(cover_path): try: session.commit() except OperationalError as ex: - log.error("gdrive.db DB is not Writeable") - log.debug('Database error: %s', ex) + log.error_or_exception('Database error: {}'.format(ex)) session.rollback() return df.metadata.get('webContentLink') else: @@ -622,7 +614,7 @@ def do_gdrive_download(df, headers, convert_encoding=False): def stream(convert_encoding): for byte in s: - headers = {"Range": 'bytes=%s-%s' % (byte[0], byte[1])} + headers = {"Range": 'bytes={}-{}'.format(byte[0], byte[1])} resp, content = df.auth.Get_Http_Object().request(download_url, headers=headers) if resp.status == 206: if convert_encoding: @@ -630,7 +622,7 @@ def do_gdrive_download(df, headers, convert_encoding=False): content = content.decode(result['encoding']).encode('utf-8') yield content else: - log.warning('An error occurred: %s', resp) + log.warning('An error occurred: {}'.format(resp)) return return Response(stream_with_context(stream(convert_encoding)), headers=headers) diff --git a/cps/gevent_wsgi.py b/cps/gevent_wsgi.py new file mode 100644 index 00000000..b044f31b --- /dev/null +++ b/cps/gevent_wsgi.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- + +# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) +# Copyright (C) 2022 OzzieIsaacs +# +# 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 gevent.pywsgi import WSGIHandler + +class MyWSGIHandler(WSGIHandler): + def get_environ(self): + env = super().get_environ() + path, __ = self.path.split('?', 1) if '?' in self.path else (self.path, '') + env['RAW_URI'] = path + return env + + diff --git a/cps/helper.py b/cps/helper.py index b5495930..d97d6475 100644 --- a/cps/helper.py +++ b/cps/helper.py @@ -19,42 +19,49 @@ import os import io +import sys import mimetypes import re import shutil import socket -import unicodedata from datetime import datetime, timedelta from tempfile import gettempdir -from urllib.parse import urlparse import requests +import unidecode from babel.dates import format_datetime from babel.units import format_unit from flask import send_from_directory, make_response, redirect, abort, url_for from flask_babel import gettext as _ +from flask_babel import lazy_gettext as N_ from flask_login import current_user -from sqlalchemy.sql.expression import true, false, and_, text, func +from sqlalchemy.sql.expression import true, false, and_, or_, text, func from sqlalchemy.exc import InvalidRequestError, OperationalError from werkzeug.datastructures import Headers from werkzeug.security import generate_password_hash from markupsafe import escape from urllib.parse import quote + try: - import unidecode - use_unidecode = True + import advocate + from advocate.exceptions import UnacceptableAddressException + use_advocate = True except ImportError: - use_unidecode = False + use_advocate = False + advocate = requests + UnacceptableAddressException = MissingSchema = BaseException from . import calibre_db, cli from .tasks.convert import TaskConvert -from . import logger, config, get_locale, db, ub, kobo_sync_status +from . import logger, config, get_locale, db, ub, fs from . import gdriveutils as gd -from .constants import STATIC_DIR as _STATIC_DIR +from .constants import STATIC_DIR as _STATIC_DIR, CACHE_TYPE_THUMBNAILS, THUMBNAIL_TYPE_COVER, THUMBNAIL_TYPE_SERIES from .subproc_wrapper import process_wait -from .services.worker import WorkerThread, STAT_WAITING, STAT_FAIL, STAT_STARTED, STAT_FINISH_SUCCESS +from .services.worker import WorkerThread, STAT_WAITING, STAT_FAIL, STAT_STARTED, STAT_FINISH_SUCCESS, STAT_ENDED, \ + STAT_CANCELLED from .tasks.mail import TaskEmail +from .tasks.thumbnail import TaskClearCoverThumbnailCache, TaskGenerateCoverThumbnails log = logger.create() @@ -105,9 +112,10 @@ def convert_book_format(book_id, calibrepath, old_book_format, new_book_format, return None +# Texts are not lazy translated as they are supposed to get send out as is def send_test_mail(kindle_mail, user_name): WorkerThread.add(user_name, TaskEmail(_(u'Calibre-Web test e-mail'), None, None, - config.get_mail_settings(), kindle_mail, _(u"Test e-mail"), + config.get_mail_settings(), kindle_mail, N_(u"Test e-mail"), _(u'This e-mail has been sent via Calibre-Web.'))) return @@ -129,7 +137,7 @@ def send_registration_mail(e_mail, user_name, default_password, resend=False): attachment=None, settings=config.get_mail_settings(), recipient=e_mail, - taskMessage=_(u"Registration e-mail for user: %(name)s", name=user_name), + task_message=N_(u"Registration e-mail for user: %(name)s", name=user_name), text=txt )) return @@ -143,7 +151,7 @@ def check_send_to_kindle_with_converter(formats): 'text': _('Convert %(orig)s to %(format)s and send to Kindle', orig='Epub', format='Mobi')}) - if 'AZW3' in formats and not 'MOBI' in formats: + if 'AZW3' in formats and 'MOBI' not in formats: bookformats.append({'format': 'Mobi', 'convert': 2, 'text': _('Convert %(orig)s to %(format)s and send to Kindle', @@ -185,11 +193,11 @@ def check_send_to_kindle(entry): # Check if a reader is existing for any of the book formats, if not, return empty list, otherwise return # list with supported formats def check_read_formats(entry): - EXTENSIONS_READER = {'TXT', 'PDF', 'EPUB', 'CBZ', 'CBT', 'CBR', 'DJVU'} + extensions_reader = {'TXT', 'PDF', 'EPUB', 'CBZ', 'CBT', 'CBR', 'DJVU'} bookformats = list() if len(entry.data): for ele in iter(entry.data): - if ele.format.upper() in EXTENSIONS_READER: + if ele.format.upper() in extensions_reader: bookformats.append(ele.format.lower()) return bookformats @@ -213,37 +221,45 @@ def send_mail(book_id, book_format, convert, kindle_mail, calibrepath, user_id): if entry.format.upper() == book_format.upper(): converted_file_name = entry.name + '.' + book_format.lower() link = '{}'.format(url_for('web.show_book', book_id=book_id), escape(book.title)) - EmailText = _(u"%(book)s send to Kindle", book=link) + email_text = N_(u"%(book)s send to Kindle", book=link) WorkerThread.add(user_id, TaskEmail(_(u"Send to Kindle"), book.path, converted_file_name, config.get_mail_settings(), kindle_mail, - EmailText, _(u'This e-mail has been sent via Calibre-Web.'))) + email_text, _(u'This e-mail has been sent via Calibre-Web.'))) return return _(u"The requested file could not be read. Maybe wrong permissions?") +def shorten_component(s, by_what): + l = len(s) + if l < by_what: + return s + l = (l - by_what)//2 + if l <= 0: + return s + return s[:l] + s[-l:] + + def get_valid_filename(value, replace_whitespace=True, chars=128): """ Returns the given string converted to a string that can be used for a clean filename. Limits num characters to 128 max. """ + + if value[-1:] == u'.': value = value[:-1]+u'_' value = value.replace("/", "_").replace(":", "_").strip('\0') - if use_unidecode: - if config.config_unicode_filename: - value = (unidecode.unidecode(value)) - else: - value = value.replace(u'§', u'SS') - value = value.replace(u'ß', u'ss') - value = unicodedata.normalize('NFKD', value) - re_slugify = re.compile(r'[\W\s-]', re.UNICODE) - value = re_slugify.sub('', value) + if config.config_unicode_filename: + value = (unidecode.unidecode(value)) if replace_whitespace: # *+:\"/<>? are replaced by _ value = re.sub(r'[*+:\\\"/<>?]+', u'_', value, flags=re.U) # pipe has to be replaced with comma value = re.sub(r'[|]+', u',', value, flags=re.U) - value = value[:chars].strip() + + filename_encoding_for_length = 'utf-16' if sys.platform == "win32" or sys.platform == "darwin" else 'utf-8' + value = value.encode(filename_encoding_for_length)[:chars].decode('utf-8', errors='ignore').strip() + if not value: raise ValueError("Filename cannot be empty") return value @@ -266,6 +282,7 @@ def split_authors(values): def get_sorted_author(value): + value2 = None try: if ',' not in value: regexes = [r"^(JR|SR)\.?$", r"^I{1,3}\.?$", r"^IV\.?$"] @@ -290,6 +307,7 @@ def get_sorted_author(value): value2 = value return value2 + def edit_book_read_status(book_id, read_status=None): if not config.config_read_column: book = ub.session.query(ub.ReadBook).filter(and_(ub.ReadBook.user_id == int(current_user.id), @@ -303,9 +321,9 @@ def edit_book_read_status(book_id, read_status=None): else: book.read_status = ub.ReadBook.STATUS_FINISHED if read_status else ub.ReadBook.STATUS_UNREAD else: - readBook = ub.ReadBook(user_id=current_user.id, book_id = book_id) - readBook.read_status = ub.ReadBook.STATUS_FINISHED - book = readBook + read_book = ub.ReadBook(user_id=current_user.id, book_id=book_id) + read_book.read_status = ub.ReadBook.STATUS_FINISHED + book = read_book if not book.kobo_reading_state: kobo_reading_state = ub.KoboReadingState(user_id=current_user.id, book_id=book_id) kobo_reading_state.current_bookmark = ub.KoboBookmark() @@ -329,15 +347,17 @@ def edit_book_read_status(book_id, read_status=None): new_cc = cc_class(value=read_status or 1, book=book_id) calibre_db.session.add(new_cc) calibre_db.session.commit() - except (KeyError, AttributeError): - log.error(u"Custom Column No.%d is not existing in calibre database", config.config_read_column) + except (KeyError, AttributeError, IndexError): + log.error( + "Custom Column No.{} is not existing in calibre database".format(config.config_read_column)) return "Custom Column No.{} is not existing in calibre database".format(config.config_read_column) - except (OperationalError, InvalidRequestError) as e: + except (OperationalError, InvalidRequestError) as ex: calibre_db.session.rollback() - log.error(u"Read status could not set: {}".format(e)) - return "Read status could not set: {}".format(e), 400 + log.error(u"Read status could not set: {}".format(ex)) + return _("Read status could not set: {}".format(ex.orig)) return "" + # Deletes a book fro the local filestorage, returns True if deleting is successfull, otherwise false def delete_book_file(book, calibrepath, book_format=None): # check that path is 2 elements deep, check that target path has no subfolders @@ -361,15 +381,15 @@ def delete_book_file(book, calibrepath, book_format=None): id=book.id, path=book.path) shutil.rmtree(path) - except (IOError, OSError) as e: - log.error("Deleting book %s failed: %s", book.id, e) - return False, _("Deleting book %(id)s failed: %(message)s", id=book.id, message=e) + except (IOError, OSError) as ex: + log.error("Deleting book %s failed: %s", book.id, ex) + return False, _("Deleting book %(id)s failed: %(message)s", id=book.id, message=ex) authorpath = os.path.join(calibrepath, os.path.split(book.path)[0]) if not os.listdir(authorpath): try: shutil.rmtree(authorpath) - except (IOError, OSError) as e: - log.error("Deleting authorpath for book %s failed: %s", book.id, e) + except (IOError, OSError) as ex: + log.error("Deleting authorpath for book %s failed: %s", book.id, ex) return True, None log.error("Deleting book %s from database only, book path in database not valid: %s", @@ -395,21 +415,21 @@ def clean_author_database(renamed_author, calibre_path="", local_book=None, gdri all_titledir = book.path.split('/')[1] all_new_path = os.path.join(calibre_path, all_new_authordir, all_titledir) all_new_name = get_valid_filename(book.title, chars=42) + ' - ' \ - + get_valid_filename(new_author.name, chars=42) + + get_valid_filename(new_author.name, chars=42) # change location in database to new author/title path book.path = os.path.join(all_new_authordir, all_titledir).replace('\\', '/') for file_format in book.data: if not gdrive: shutil.move(os.path.normcase(os.path.join(all_new_path, file_format.name + '.' + file_format.format.lower())), - os.path.normcase(os.path.join(all_new_path, - all_new_name + '.' + file_format.format.lower()))) + os.path.normcase(os.path.join(all_new_path, + all_new_name + '.' + file_format.format.lower()))) else: - gFile = gd.getFileFromEbooksFolder(all_new_path, - file_format.name + '.' + file_format.format.lower()) - if gFile: - gd.moveGdriveFileRemote(gFile, all_new_name + u'.' + file_format.format.lower()) - gd.updateDatabaseOnEdit(gFile['id'], all_new_name + u'.' + file_format.format.lower()) + g_file = gd.getFileFromEbooksFolder(all_new_path, + file_format.name + '.' + file_format.format.lower()) + if g_file: + gd.moveGdriveFileRemote(g_file, all_new_name + u'.' + file_format.format.lower()) + gd.updateDatabaseOnEdit(g_file['id'], all_new_name + u'.' + file_format.format.lower()) else: log.error("File {} not found on gdrive" .format(all_new_path, file_format.name + '.' + file_format.format.lower())) @@ -426,16 +446,16 @@ def rename_all_authors(first_author, renamed_author, calibre_path="", localbook= old_author_dir = get_valid_filename(r, chars=96) new_author_rename_dir = get_valid_filename(new_author.name, chars=96) if gdrive: - gFile = gd.getFileFromEbooksFolder(None, old_author_dir) - if gFile: - gd.moveGdriveFolderRemote(gFile, new_author_rename_dir) + g_file = gd.getFileFromEbooksFolder(None, old_author_dir) + if g_file: + gd.moveGdriveFolderRemote(g_file, new_author_rename_dir) else: if os.path.isdir(os.path.join(calibre_path, old_author_dir)): try: old_author_path = os.path.join(calibre_path, old_author_dir) new_author_path = os.path.join(calibre_path, new_author_rename_dir) shutil.move(os.path.normcase(old_author_path), os.path.normcase(new_author_path)) - except (OSError) as ex: + except OSError as ex: log.error("Rename author from: %s to %s: %s", old_author_path, new_author_path, ex) log.debug(ex, exc_info=True) return _("Rename author from: '%(src)s' to '%(dest)s' failed with error: %(error)s", @@ -444,34 +464,35 @@ def rename_all_authors(first_author, renamed_author, calibre_path="", localbook= new_authordir = get_valid_filename(localbook.authors[0].name, chars=96) return new_authordir + # Moves files in file storage during author/title rename, or from temp dir to file storage def update_dir_structure_file(book_id, calibre_path, first_author, original_filepath, db_filename, renamed_author): # get book database entry from id, if original path overwrite source with original_filepath - localbook = calibre_db.get_book(book_id) + local_book = calibre_db.get_book(book_id) if original_filepath: path = original_filepath else: - path = os.path.join(calibre_path, localbook.path) + path = os.path.join(calibre_path, local_book.path) - # Create (current) authordir and titledir from database - authordir = localbook.path.split('/')[0] - titledir = localbook.path.split('/')[1] + # Create (current) author_dir and title_dir from database + author_dir = local_book.path.split('/')[0] + title_dir = local_book.path.split('/')[1] - # Create new_authordir from parameter or from database - # Create new titledir from database and add id - new_authordir = rename_all_authors(first_author, renamed_author, calibre_path, localbook) + # Create new_author_dir from parameter or from database + # Create new title_dir from database and add id + new_author_dir = rename_all_authors(first_author, renamed_author, calibre_path, local_book) if first_author: if first_author.lower() in [r.lower() for r in renamed_author]: - if os.path.isdir(os.path.join(calibre_path, new_authordir)): - path = os.path.join(calibre_path, new_authordir, titledir) + if os.path.isdir(os.path.join(calibre_path, new_author_dir)): + path = os.path.join(calibre_path, new_author_dir, title_dir) - new_titledir = get_valid_filename(localbook.title, chars=96) + " (" + str(book_id) + ")" + new_title_dir = get_valid_filename(local_book.title, chars=96) + " (" + str(book_id) + ")" - if titledir != new_titledir or authordir != new_authordir or original_filepath: + if title_dir != new_title_dir or author_dir != new_author_dir or original_filepath: error = move_files_on_change(calibre_path, - new_authordir, - new_titledir, - localbook, + new_author_dir, + new_title_dir, + local_book, db_filename, original_filepath, path) @@ -479,26 +500,23 @@ def update_dir_structure_file(book_id, calibre_path, first_author, original_file return error # Rename all files from old names to new names - return rename_files_on_change(first_author, renamed_author, localbook, original_filepath, path, calibre_path) + return rename_files_on_change(first_author, renamed_author, local_book, original_filepath, path, calibre_path) def upload_new_file_gdrive(book_id, first_author, renamed_author, title, title_dir, original_filepath, filename_ext): - error = False book = calibre_db.get_book(book_id) file_name = get_valid_filename(title, chars=42) + ' - ' + \ - get_valid_filename(first_author, chars=42) + \ - filename_ext + get_valid_filename(first_author, chars=42) + filename_ext rename_all_authors(first_author, renamed_author, gdrive=True) gdrive_path = os.path.join(get_valid_filename(first_author, chars=96), title_dir + " (" + str(book_id) + ")") book.path = gdrive_path.replace("\\", "/") gd.uploadFileToEbooksFolder(os.path.join(gdrive_path, file_name).replace("\\", "/"), original_filepath) - error |= rename_files_on_change(first_author, renamed_author, localbook=book, gdrive=True) - return error + return rename_files_on_change(first_author, renamed_author, local_book=book, gdrive=True) + def update_dir_structure_gdrive(book_id, first_author, renamed_author): - error = False book = calibre_db.get_book(book_id) authordir = book.path.split('/')[0] @@ -507,27 +525,26 @@ def update_dir_structure_gdrive(book_id, first_author, renamed_author): new_titledir = get_valid_filename(book.title, chars=96) + u" (" + str(book_id) + u")" if titledir != new_titledir: - gFile = gd.getFileFromEbooksFolder(os.path.dirname(book.path), titledir) - if gFile: - gd.moveGdriveFileRemote(gFile, new_titledir) + g_file = gd.getFileFromEbooksFolder(os.path.dirname(book.path), titledir) + if g_file: + gd.moveGdriveFileRemote(g_file, new_titledir) book.path = book.path.split('/')[0] + u'/' + new_titledir - gd.updateDatabaseOnEdit(gFile['id'], book.path) # only child folder affected + gd.updateDatabaseOnEdit(g_file['id'], book.path) # only child folder affected else: - error = _(u'File %(file)s not found on Google Drive', file=book.path) # file not found + return _(u'File %(file)s not found on Google Drive', file=book.path) # file not found if authordir != new_authordir and authordir not in renamed_author: - gFile = gd.getFileFromEbooksFolder(os.path.dirname(book.path), new_titledir) - if gFile: - gd.moveGdriveFolderRemote(gFile, new_authordir) + g_file = gd.getFileFromEbooksFolder(os.path.dirname(book.path), new_titledir) + if g_file: + gd.moveGdriveFolderRemote(g_file, new_authordir) book.path = new_authordir + u'/' + book.path.split('/')[1] - gd.updateDatabaseOnEdit(gFile['id'], book.path) + gd.updateDatabaseOnEdit(g_file['id'], book.path) else: - error = _(u'File %(file)s not found on Google Drive', file=authordir) # file not found + return _(u'File %(file)s not found on Google Drive', file=authordir) # file not found # change location in database to new author/title path book.path = os.path.join(new_authordir, new_titledir).replace('\\', '/') - error |= rename_files_on_change(first_author, renamed_author, book, gdrive=True) - return error + return rename_files_on_change(first_author, renamed_author, book, gdrive=True) def move_files_on_change(calibre_path, new_authordir, new_titledir, localbook, db_filename, original_filepath, path): @@ -545,18 +562,17 @@ def move_files_on_change(calibre_path, new_authordir, new_titledir, localbook, d # move original path to new path log.debug("Moving title: %s to %s", path, new_path) shutil.move(os.path.normcase(path), os.path.normcase(new_path)) - else: # path is valid copy only files to new location (merge) + else: # path is valid copy only files to new location (merge) log.info("Moving title: %s into existing: %s", path, new_path) # Take all files and subfolder from old path (strange command) for dir_name, __, file_list in os.walk(path): for file in file_list: shutil.move(os.path.normcase(os.path.join(dir_name, file)), - os.path.normcase(os.path.join(new_path + dir_name[len(path):], file))) + os.path.normcase(os.path.join(new_path + dir_name[len(path):], file))) # change location in database to new author/title path - localbook.path = os.path.join(new_authordir, new_titledir).replace('\\','/') + localbook.path = os.path.join(new_authordir, new_titledir).replace('\\', '/') except OSError as ex: - log.error("Rename title from: %s to %s: %s", path, new_path, ex) - log.debug(ex, exc_info=True) + log.error_or_exception("Rename title from {} to {} failed with error: {}".format(path, new_path, ex)) return _("Rename title from: '%(src)s' to '%(dest)s' failed with error: %(error)s", src=path, dest=new_path, error=str(ex)) return False @@ -564,8 +580,8 @@ def move_files_on_change(calibre_path, new_authordir, new_titledir, localbook, d def rename_files_on_change(first_author, renamed_author, - localbook, - orignal_filepath="", + local_book, + original_filepath="", path="", calibre_path="", gdrive=False): @@ -573,13 +589,12 @@ def rename_files_on_change(first_author, try: clean_author_database(renamed_author, calibre_path, gdrive=gdrive) if first_author and first_author not in renamed_author: - clean_author_database([first_author], calibre_path, localbook, gdrive) - if not gdrive and not renamed_author and not orignal_filepath and len(os.listdir(os.path.dirname(path))) == 0: + clean_author_database([first_author], calibre_path, local_book, gdrive) + if not gdrive and not renamed_author and not original_filepath and len(os.listdir(os.path.dirname(path))) == 0: shutil.rmtree(os.path.dirname(path)) except (OSError, FileNotFoundError) as ex: - log.error("Error in rename file in path %s", ex) - log.debug(ex, exc_info=True) - return _("Error in rename file in path: %(error)s", error=str(ex)) + log.error_or_exception("Error in rename file in path {}".format(ex)) + return _("Error in rename file in path: {}".format(str(ex))) return False @@ -590,12 +605,12 @@ def delete_book_gdrive(book, book_format): for entry in book.data: if entry.format.upper() == book_format: name = entry.name + '.' + book_format - gFile = gd.getFileFromEbooksFolder(book.path, name) + g_file = gd.getFileFromEbooksFolder(book.path, name) else: - gFile = gd.getFileFromEbooksFolder(os.path.dirname(book.path), book.path.split('/')[1]) - if gFile: - gd.deleteDatabaseEntry(gFile['id']) - gFile.Trash() + g_file = gd.getFileFromEbooksFolder(os.path.dirname(book.path), book.path.split('/')[1]) + if g_file: + gd.deleteDatabaseEntry(g_file['id']) + g_file.Trash() else: error = _(u'Book path %(path)s not found on Google Drive', path=book.path) # file not found @@ -627,12 +642,13 @@ def generate_random_password(): def uniq(inpt): output = [] - inpt = [ " ".join(inp.split()) for inp in inpt] + inpt = [" ".join(inp.split()) for inp in inpt] for x in inpt: if x not in output: output.append(x) return output + def check_email(email): email = valid_email(email) if ub.session.query(ub.User).filter(func.lower(ub.User.email) == email.lower()).first(): @@ -645,7 +661,7 @@ def check_username(username): username = username.strip() if ub.session.query(ub.User).filter(func.lower(ub.User.name) == username.lower()).scalar(): log.error(u"This username is already taken") - raise Exception (_(u"This username is already taken")) + raise Exception(_(u"This username is already taken")) return username @@ -679,6 +695,7 @@ def update_dir_structure(book_id, def delete_book(book, calibrepath, book_format): + clear_cover_thumbnail_cache(book.id) if config.config_use_google_drive: return delete_book_gdrive(book, book_format) else: @@ -687,24 +704,38 @@ def delete_book(book, calibrepath, book_format): def get_cover_on_failure(use_generic_cover): if use_generic_cover: - return send_from_directory(_STATIC_DIR, "generic_cover.jpg") - else: - return None + try: + return send_from_directory(_STATIC_DIR, "generic_cover.jpg") + except PermissionError: + log.error("No permission to access generic_cover.jpg file.") + abort(403) + abort(404) -def get_book_cover(book_id): +def get_book_cover(book_id, resolution=None): book = calibre_db.get_filtered_book(book_id, allow_show_archived=True) - return get_book_cover_internal(book, use_generic_cover_on_failure=True) + return get_book_cover_internal(book, use_generic_cover_on_failure=True, resolution=resolution) -def get_book_cover_with_uuid(book_uuid, - use_generic_cover_on_failure=True): +# Called only by kobo sync -> cover not found should be answered with 404 and not with default cover +def get_book_cover_with_uuid(book_uuid, resolution=None): book = calibre_db.get_book_by_uuid(book_uuid) - return get_book_cover_internal(book, use_generic_cover_on_failure) + return get_book_cover_internal(book, use_generic_cover_on_failure=False, resolution=resolution) -def get_book_cover_internal(book, use_generic_cover_on_failure): +def get_book_cover_internal(book, use_generic_cover_on_failure, resolution=None): if book and book.has_cover: + + # Send the book cover thumbnail if it exists in cache + if resolution: + thumbnail = get_book_cover_thumbnail(book, resolution) + if thumbnail: + cache = fs.FileSystem() + if cache.get_cache_file_exists(thumbnail.filename, CACHE_TYPE_THUMBNAILS): + return send_from_directory(cache.get_cache_file_dir(thumbnail.filename, CACHE_TYPE_THUMBNAILS), + thumbnail.filename) + + # Send the book cover from Google Drive if configured if config.config_use_google_drive: try: if not gd.is_gdrive_ready(): @@ -713,11 +744,13 @@ def get_book_cover_internal(book, use_generic_cover_on_failure): if path: return redirect(path) else: - log.error('%s/cover.jpg not found on Google Drive', book.path) + log.error('{}/cover.jpg not found on Google Drive'.format(book.path)) return get_cover_on_failure(use_generic_cover_on_failure) except Exception as ex: - log.debug_or_exception(ex) + log.error_or_exception(ex) return get_cover_on_failure(use_generic_cover_on_failure) + + # Send the book cover from the Calibre directory else: cover_file_path = os.path.join(config.config_calibre_dir, book.path) if os.path.isfile(os.path.join(cover_file_path, "cover.jpg")): @@ -728,27 +761,82 @@ def get_book_cover_internal(book, use_generic_cover_on_failure): return get_cover_on_failure(use_generic_cover_on_failure) +def get_book_cover_thumbnail(book, resolution): + if book and book.has_cover: + return ub.session \ + .query(ub.Thumbnail) \ + .filter(ub.Thumbnail.type == THUMBNAIL_TYPE_COVER) \ + .filter(ub.Thumbnail.entity_id == book.id) \ + .filter(ub.Thumbnail.resolution == resolution) \ + .filter(or_(ub.Thumbnail.expiration.is_(None), ub.Thumbnail.expiration > datetime.utcnow())) \ + .first() + + +def get_series_thumbnail_on_failure(series_id, resolution): + book = calibre_db.session \ + .query(db.Books) \ + .join(db.books_series_link) \ + .join(db.Series) \ + .filter(db.Series.id == series_id) \ + .filter(db.Books.has_cover == 1) \ + .first() + + return get_book_cover_internal(book, use_generic_cover_on_failure=True, resolution=resolution) + + +def get_series_cover_thumbnail(series_id, resolution=None): + return get_series_cover_internal(series_id, resolution) + + +def get_series_cover_internal(series_id, resolution=None): + # Send the series thumbnail if it exists in cache + if resolution: + thumbnail = get_series_thumbnail(series_id, resolution) + if thumbnail: + cache = fs.FileSystem() + if cache.get_cache_file_exists(thumbnail.filename, CACHE_TYPE_THUMBNAILS): + return send_from_directory(cache.get_cache_file_dir(thumbnail.filename, CACHE_TYPE_THUMBNAILS), + thumbnail.filename) + + return get_series_thumbnail_on_failure(series_id, resolution) + + +def get_series_thumbnail(series_id, resolution): + return ub.session \ + .query(ub.Thumbnail) \ + .filter(ub.Thumbnail.type == THUMBNAIL_TYPE_SERIES) \ + .filter(ub.Thumbnail.entity_id == series_id) \ + .filter(ub.Thumbnail.resolution == resolution) \ + .filter(or_(ub.Thumbnail.expiration.is_(None), ub.Thumbnail.expiration > datetime.utcnow())) \ + .first() + + # saves book cover from url def save_cover_from_url(url, book_path): try: - if not cli.allow_localhost: - # 127.0.x.x, localhost, [::1], [::ffff:7f00:1] - ip = socket.getaddrinfo(urlparse(url).hostname, 0)[0][4][0] - if ip.startswith("127.") or ip.startswith('::ffff:7f') or ip == "::1": - log.error("Localhost was accessed for cover upload") - return False, _("You are not allowed to access localhost for cover uploads") - img = requests.get(url, timeout=(10, 200)) # ToDo: Error Handling + if cli.allow_localhost: + img = requests.get(url, timeout=(10, 200), allow_redirects=False) # ToDo: Error Handling + elif use_advocate: + img = advocate.get(url, timeout=(10, 200), allow_redirects=False) # ToDo: Error Handling + else: + log.error("python modul advocate is not installed but is needed") + return False, _("Python modul 'advocate' is not installed but is needed for cover downloads") img.raise_for_status() return save_cover(img, book_path) except (socket.gaierror, requests.exceptions.HTTPError, + requests.exceptions.InvalidURL, requests.exceptions.ConnectionError, requests.exceptions.Timeout) as ex: - log.info(u'Cover Download Error %s', ex) + # "Invalid host" can be the result of a redirect response + log.error(u'Cover Download Error %s', ex) return False, _("Error Downloading Cover") except MissingDelegateError as ex: log.info(u'File Format Error %s', ex) return False, _("Cover Format Error") + except UnacceptableAddressException as e: + log.error("Localhost or local network was accessed for cover upload") + return False, _("You are not allowed to access localhost or the local network for cover uploads") def save_cover_from_filestorage(filepath, saved_filename, img): @@ -783,24 +871,23 @@ def save_cover(img, book_path): content_type = img.headers.get('content-type') if use_IM: - if content_type not in ('image/jpeg', 'image/png', 'image/webp', 'image/bmp'): + if content_type not in ('image/jpeg', 'image/jpg', 'image/png', 'image/webp', 'image/bmp'): log.error("Only jpg/jpeg/png/webp/bmp files are supported as coverfile") return False, _("Only jpg/jpeg/png/webp/bmp files are supported as coverfile") # convert to jpg because calibre only supports jpg - if content_type != 'image/jpg': - try: - if hasattr(img, 'stream'): - imgc = Image(blob=img.stream) - else: - imgc = Image(blob=io.BytesIO(img.content)) - imgc.format = 'jpeg' - imgc.transform_colorspace("rgb") - img = imgc - except (BlobError, MissingDelegateError): - log.error("Invalid cover file content") - return False, _("Invalid cover file content") + try: + if hasattr(img, 'stream'): + imgc = Image(blob=img.stream) + else: + imgc = Image(blob=io.BytesIO(img.content)) + imgc.format = 'jpeg' + imgc.transform_colorspace("rgb") + img = imgc + except (BlobError, MissingDelegateError): + log.error("Invalid cover file content") + return False, _("Invalid cover file content") else: - if content_type not in 'image/jpeg': + if content_type not in ['image/jpeg', 'image/jpg']: log.error("Only jpg/jpeg files are supported as coverfile") return False, _("Only jpg/jpeg files are supported as coverfile") @@ -811,7 +898,7 @@ def save_cover(img, book_path): os.mkdir(tmp_dir) ret, message = save_cover_from_filestorage(tmp_dir, "uploaded_cover.jpg", img) if ret is True: - gd.uploadFileToEbooksFolder(os.path.join(book_path, 'cover.jpg').replace("\\","/"), + gd.uploadFileToEbooksFolder(os.path.join(book_path, 'cover.jpg').replace("\\", "/"), os.path.join(tmp_dir, "uploaded_cover.jpg")) log.info("Cover is saved on Google Drive") return True, None @@ -823,9 +910,9 @@ def save_cover(img, book_path): def do_download_file(book, book_format, client, data, headers): if config.config_use_google_drive: - #startTime = time.time() + # startTime = time.time() df = gd.getFileFromEbooksFolder(book.path, data.name + "." + book_format) - #log.debug('%s', time.time() - startTime) + # log.debug('%s', time.time() - startTime) if df: return gd.do_gdrive_download(df, headers) else: @@ -849,22 +936,22 @@ def do_download_file(book, book_format, client, data, headers): ################################## -def check_unrar(unrarLocation): - if not unrarLocation: +def check_unrar(unrar_location): + if not unrar_location: return - if not os.path.exists(unrarLocation): + if not os.path.exists(unrar_location): return _('Unrar binary file not found') try: - unrarLocation = [unrarLocation] - value = process_wait(unrarLocation, pattern='UNRAR (.*) freeware') + unrar_location = [unrar_location] + value = process_wait(unrar_location, pattern='UNRAR (.*) freeware') if value: version = value.group(1) log.debug("unrar version %s", version) except (OSError, UnicodeDecodeError) as err: - log.debug_or_exception(err) + log.error_or_exception(err) return _('Error excecuting UnRar') @@ -885,25 +972,25 @@ def json_serial(obj): # helper function for displaying the runtime of tasks def format_runtime(runtime): - retVal = "" + ret_val = "" if runtime.days: - retVal = format_unit(runtime.days, 'duration-day', length="long", locale=get_locale()) + ', ' + ret_val = format_unit(runtime.days, 'duration-day', length="long", locale=get_locale()) + ', ' mins, seconds = divmod(runtime.seconds, 60) hours, minutes = divmod(mins, 60) # ToDo: locale.number_symbols._data['timeSeparator'] -> localize time separator ? if hours: - retVal += '{:d}:{:02d}:{:02d}s'.format(hours, minutes, seconds) + ret_val += '{:d}:{:02d}:{:02d}s'.format(hours, minutes, seconds) elif minutes: - retVal += '{:2d}:{:02d}s'.format(minutes, seconds) + ret_val += '{:2d}:{:02d}s'.format(minutes, seconds) else: - retVal += '{:2d}s'.format(seconds) - return retVal + ret_val += '{:2d}s'.format(seconds) + return ret_val # helper function to apply localize status information in tasklist entries def render_task_status(tasklist): renderedtasklist = list() - for __, user, __, task in tasklist: + for __, user, __, task, __ in tasklist: if user == current_user.name or current_user.role_admin(): ret = {} if task.start_time: @@ -920,12 +1007,22 @@ def render_task_status(tasklist): ret['status'] = _(u'Started') elif task.stat == STAT_FINISH_SUCCESS: ret['status'] = _(u'Finished') + elif task.stat == STAT_ENDED: + ret['status'] = _(u'Ended') + elif task.stat == STAT_CANCELLED: + ret['status'] = _(u'Cancelled') else: ret['status'] = _(u'Unknown Status') - ret['taskMessage'] = "{}: {}".format(_(task.name), task.message) + ret['taskMessage'] = "{}: {}".format(task.name, task.message) if task.message else task.name ret['progress'] = "{} %".format(int(task.progress * 100)) ret['user'] = escape(user) # prevent xss + + # Hidden fields + ret['task_id'] = task.id + ret['stat'] = task.stat + ret['is_cancellable'] = task.is_cancellable + renderedtasklist.append(ret) return renderedtasklist @@ -953,27 +1050,10 @@ def check_valid_domain(domain_text): return not len(result) -def get_cc_columns(filter_config_custom_read=False): - tmpcc = calibre_db.session.query(db.Custom_Columns)\ - .filter(db.Custom_Columns.datatype.notin_(db.cc_exceptions)).all() - cc = [] - r = None - if config.config_columns_to_ignore: - r = re.compile(config.config_columns_to_ignore) - - for col in tmpcc: - if filter_config_custom_read and config.config_read_column and config.config_read_column == col.id: - continue - if r and r.match(col.name): - continue - cc.append(col) - - return cc - - def get_download_link(book_id, book_format, client): book_format = book_format.split(".")[0] book = calibre_db.get_filtered_book(book_id, allow_show_archived=True) + data1= "" if book: data1 = calibre_db.get_book_format(book.id, book_format.upper()) else: @@ -994,3 +1074,24 @@ def get_download_link(book_id, book_format, client): return do_download_file(book, book_format, client, data1, headers) else: abort(404) + + +def clear_cover_thumbnail_cache(book_id): + WorkerThread.add(None, TaskClearCoverThumbnailCache(book_id), hidden=True) + + +def replace_cover_thumbnail_cache(book_id): + WorkerThread.add(None, TaskClearCoverThumbnailCache(book_id), hidden=True) + WorkerThread.add(None, TaskGenerateCoverThumbnails(book_id), hidden=True) + + +def delete_thumbnail_cache(): + WorkerThread.add(None, TaskClearCoverThumbnailCache(-1)) + + +def add_book_to_thumbnail_cache(book_id): + WorkerThread.add(None, TaskGenerateCoverThumbnails(book_id), hidden=True) + + +def update_thumbnail_cache(): + WorkerThread.add(None, TaskGenerateCoverThumbnails()) diff --git a/cps/jinjia.py b/cps/jinjia.py index 06e99141..f88b36a2 100644 --- a/cps/jinjia.py +++ b/cps/jinjia.py @@ -31,8 +31,7 @@ from flask import Blueprint, request, url_for from flask_babel import get_locale from flask_login import current_user from markupsafe import escape -from . import logger - +from . import constants, logger jinjia = Blueprint('jinjia', __name__) log = logger.create() @@ -128,12 +127,55 @@ def formatseriesindex_filter(series_index): return series_index return 0 + @jinjia.app_template_filter('escapedlink') def escapedlink_filter(url, text): return "{}".format(url, escape(text)) + @jinjia.app_template_filter('uuidfilter') def uuidfilter(var): return uuid4() +@jinjia.app_template_filter('cache_timestamp') +def cache_timestamp(rolling_period='month'): + if rolling_period == 'day': + return str(int(datetime.datetime.today().replace(hour=1, minute=1).timestamp())) + elif rolling_period == 'year': + return str(int(datetime.datetime.today().replace(day=1).timestamp())) + else: + return str(int(datetime.datetime.today().replace(month=1, day=1).timestamp())) + + +@jinjia.app_template_filter('last_modified') +def book_last_modified(book): + return str(int(book.last_modified.timestamp())) + + +@jinjia.app_template_filter('get_cover_srcset') +def get_cover_srcset(book): + srcset = list() + resolutions = { + constants.COVER_THUMBNAIL_SMALL: 'sm', + constants.COVER_THUMBNAIL_MEDIUM: 'md', + constants.COVER_THUMBNAIL_LARGE: 'lg' + } + for resolution, shortname in resolutions.items(): + url = url_for('web.get_cover', book_id=book.id, resolution=shortname, c=book_last_modified(book)) + srcset.append(f'{url} {resolution}x') + return ', '.join(srcset) + + +@jinjia.app_template_filter('get_series_srcset') +def get_cover_srcset(series): + srcset = list() + resolutions = { + constants.COVER_THUMBNAIL_SMALL: 'sm', + constants.COVER_THUMBNAIL_MEDIUM: 'md', + constants.COVER_THUMBNAIL_LARGE: 'lg' + } + for resolution, shortname in resolutions.items(): + url = url_for('web.get_series_cover', series_id=series.id, resolution=shortname, c=cache_timestamp()) + srcset.append(f'{url} {resolution}x') + return ', '.join(srcset) diff --git a/cps/kobo.py b/cps/kobo.py index d02660b2..46e68acb 100644 --- a/cps/kobo.py +++ b/cps/kobo.py @@ -45,7 +45,7 @@ import requests from . import config, logger, kobo_auth, db, calibre_db, helper, shelf as shelf_lib, ub, csrf, kobo_sync_status -from .constants import sqlalchemy_version2 +from .constants import sqlalchemy_version2, COVER_THUMBNAIL_SMALL from .helper import get_download_link from .services import SyncToken as SyncToken from .web import download_required @@ -148,8 +148,8 @@ def HandleSyncRequest(): sync_token.books_last_created = datetime.datetime.min sync_token.reading_state_last_modified = datetime.datetime.min - new_books_last_modified = sync_token.books_last_modified # needed for sync selected shelfs only - new_books_last_created = sync_token.books_last_created # needed to distinguish between new and changed entitlement + new_books_last_modified = sync_token.books_last_modified # needed for sync selected shelfs only + new_books_last_created = sync_token.books_last_created # needed to distinguish between new and changed entitlement new_reading_state_last_modified = sync_token.reading_state_last_modified new_archived_last_modified = datetime.datetime.min @@ -176,18 +176,17 @@ def HandleSyncRequest(): .join(db.Data).outerjoin(ub.ArchivedBook, and_(db.Books.id == ub.ArchivedBook.book_id, ub.ArchivedBook.user_id == current_user.id)) .filter(db.Books.id.notin_(calibre_db.session.query(ub.KoboSyncedBooks.book_id) - .filter(ub.KoboSyncedBooks.user_id == current_user.id))) - .filter(ub.BookShelf.date_added > sync_token.books_last_modified) - .filter(db.Data.format.in_(KOBO_FORMATS)) - .filter(calibre_db.common_filters(allow_show_archived=True)) - .order_by(db.Books.id) - .order_by(ub.ArchivedBook.last_modified) - .join(ub.BookShelf, db.Books.id == ub.BookShelf.book_id) - .join(ub.Shelf) - .filter(ub.Shelf.user_id == current_user.id) - .filter(ub.Shelf.kobo_sync) - .distinct() - ) + .filter(ub.KoboSyncedBooks.user_id == current_user.id))) + .filter(ub.BookShelf.date_added > sync_token.books_last_modified) + .filter(db.Data.format.in_(KOBO_FORMATS)) + .filter(calibre_db.common_filters(allow_show_archived=True)) + .order_by(db.Books.id) + .order_by(ub.ArchivedBook.last_modified) + .join(ub.BookShelf, db.Books.id == ub.BookShelf.book_id) + .join(ub.Shelf) + .filter(ub.Shelf.user_id == current_user.id) + .filter(ub.Shelf.kobo_sync) + .distinct()) else: if sqlalchemy_version2: changed_entries = select(db.Books, ub.ArchivedBook.last_modified, ub.ArchivedBook.is_archived) @@ -196,16 +195,14 @@ def HandleSyncRequest(): ub.ArchivedBook.last_modified, ub.ArchivedBook.is_archived) changed_entries = (changed_entries - .join(db.Data).outerjoin(ub.ArchivedBook, and_(db.Books.id == ub.ArchivedBook.book_id, - ub.ArchivedBook.user_id == current_user.id)) - .filter(db.Books.id.notin_(calibre_db.session.query(ub.KoboSyncedBooks.book_id) - .filter(ub.KoboSyncedBooks.user_id == current_user.id))) - .filter(calibre_db.common_filters(allow_show_archived=True)) - .filter(db.Data.format.in_(KOBO_FORMATS)) - .order_by(db.Books.last_modified) - .order_by(db.Books.id) - ) - + .join(db.Data).outerjoin(ub.ArchivedBook, and_(db.Books.id == ub.ArchivedBook.book_id, + ub.ArchivedBook.user_id == current_user.id)) + .filter(db.Books.id.notin_(calibre_db.session.query(ub.KoboSyncedBooks.book_id) + .filter(ub.KoboSyncedBooks.user_id == current_user.id))) + .filter(calibre_db.common_filters(allow_show_archived=True)) + .filter(db.Data.format.in_(KOBO_FORMATS)) + .order_by(db.Books.last_modified) + .order_by(db.Books.id)) reading_states_in_new_entitlements = [] if sqlalchemy_version2: @@ -215,7 +212,7 @@ def HandleSyncRequest(): log.debug("Books to Sync: {}".format(len(books.all()))) for book in books: formats = [data.format for data in book.Books.data] - if not 'KEPUB' in formats and config.config_kepubifypath and 'EPUB' in formats: + if 'KEPUB' not in formats and config.config_kepubifypath and 'EPUB' in formats: helper.convert_book_format(book.Books.id, config.config_calibre_dir, 'EPUB', 'KEPUB', current_user.name) kobo_reading_state = get_or_create_reading_state(book.Books.id) @@ -262,7 +259,7 @@ def HandleSyncRequest(): .columns(db.Books).first() else: max_change = changed_entries.from_self().filter(ub.ArchivedBook.is_archived)\ - .filter(ub.ArchivedBook.user_id==current_user.id) \ + .filter(ub.ArchivedBook.user_id == current_user.id) \ .order_by(func.datetime(ub.ArchivedBook.last_modified).desc()).first() max_change = max_change.last_modified if max_change else new_archived_last_modified @@ -425,9 +422,9 @@ def get_author(book): author_list = [] autor_roles = [] for author in book.authors: - autor_roles.append({"Name":author.name}) #.encode('unicode-escape').decode('latin-1') + autor_roles.append({"Name": author.name}) author_list.append(author.name) - return {"ContributorRoles": autor_roles, "Contributors":author_list} + return {"ContributorRoles": autor_roles, "Contributors": author_list} def get_publisher(book): @@ -441,6 +438,7 @@ def get_series(book): return None return book.series[0].name + def get_seriesindex(book): return book.series_index or 1 @@ -485,7 +483,7 @@ def get_metadata(book): "Language": "en", "PhoneticPronunciations": {}, "PublicationDate": convert_to_kobo_timestamp_string(book.pubdate), - "Publisher": {"Imprint": "", "Name": get_publisher(book),}, + "Publisher": {"Imprint": "", "Name": get_publisher(book), }, "RevisionId": book_uuid, "Title": book.title, "WorkId": book_uuid, @@ -504,6 +502,7 @@ def get_metadata(book): return metadata + @csrf.exempt @kobo.route("/v1/library/tags", methods=["POST", "DELETE"]) @requires_kobo_auth @@ -718,7 +717,6 @@ def sync_shelves(sync_token, sync_results, only_kobo_shelves=False): *extra_filters ).distinct().order_by(func.datetime(ub.Shelf.last_modified).asc()) - for shelf in shelflist: if not shelf_lib.check_shelf_view_permissions(shelf): continue @@ -764,6 +762,7 @@ def create_kobo_tag(shelf): ) return {"Tag": tag} + @csrf.exempt @kobo.route("/v1/library//state", methods=["GET", "PUT"]) @requires_kobo_auth @@ -808,7 +807,7 @@ def HandleStateRequest(book_uuid): book_read = kobo_reading_state.book_read_link new_book_read_status = get_ub_read_status(request_status_info["Status"]) if new_book_read_status == ub.ReadBook.STATUS_IN_PROGRESS \ - and new_book_read_status != book_read.read_status: + and new_book_read_status != book_read.read_status: book_read.times_started_reading += 1 book_read.last_time_started_reading = datetime.datetime.utcnow() book_read.read_status = new_book_read_status @@ -848,7 +847,7 @@ def get_ub_read_status(kobo_read_status): def get_or_create_reading_state(book_id): book_read = ub.session.query(ub.ReadBook).filter(ub.ReadBook.book_id == book_id, - ub.ReadBook.user_id == int(current_user.id)).one_or_none() + ub.ReadBook.user_id == int(current_user.id)).one_or_none() if not book_read: book_read = ub.ReadBook(user_id=current_user.id, book_id=book_id) if not book_read.kobo_reading_state: @@ -912,13 +911,12 @@ def get_current_bookmark_response(current_bookmark): } return resp + @kobo.route("/////image.jpg", defaults={'Quality': ""}) @kobo.route("//////image.jpg") @requires_kobo_auth -def HandleCoverImageRequest(book_uuid, width, height,Quality, isGreyscale): - book_cover = helper.get_book_cover_with_uuid( - book_uuid, use_generic_cover_on_failure=False - ) +def HandleCoverImageRequest(book_uuid, width, height, Quality, isGreyscale): + book_cover = helper.get_book_cover_with_uuid(book_uuid, resolution=COVER_THUMBNAIL_SMALL) if not book_cover: if config.config_kobo_proxy: log.debug("Cover for unknown book: %s proxied to kobo" % book_uuid) @@ -991,8 +989,8 @@ def handle_getests(): if config.config_kobo_proxy: return redirect_or_proxy_request() else: - testkey = request.headers.get("X-Kobo-userkey","") - return make_response(jsonify({"Result": "Success", "TestKey":testkey, "Tests": {}})) + testkey = request.headers.get("X-Kobo-userkey", "") + return make_response(jsonify({"Result": "Success", "TestKey": testkey, "Tests": {}})) @csrf.exempt @@ -1022,7 +1020,7 @@ def make_calibre_web_auth_response(): content = request.get_json() AccessToken = base64.b64encode(os.urandom(24)).decode('utf-8') RefreshToken = base64.b64encode(os.urandom(24)).decode('utf-8') - return make_response( + return make_response( jsonify( { "AccessToken": AccessToken, @@ -1160,14 +1158,16 @@ def NATIVE_KOBO_RESOURCES(): "eula_page": "https://www.kobo.com/termsofuse?style=onestore", "exchange_auth": "https://storeapi.kobo.com/v1/auth/exchange", "external_book": "https://storeapi.kobo.com/v1/products/books/external/{Ids}", - "facebook_sso_page": "https://authorize.kobo.com/signin/provider/Facebook/login?returnUrl=http://store.kobobooks.com/", + "facebook_sso_page": + "https://authorize.kobo.com/signin/provider/Facebook/login?returnUrl=http://store.kobobooks.com/", "featured_list": "https://storeapi.kobo.com/v1/products/featured/{FeaturedListId}", "featured_lists": "https://storeapi.kobo.com/v1/products/featured", "free_books_page": { "EN": "https://www.kobo.com/{region}/{language}/p/free-ebooks", "FR": "https://www.kobo.com/{region}/{language}/p/livres-gratuits", "IT": "https://www.kobo.com/{region}/{language}/p/libri-gratuiti", - "NL": "https://www.kobo.com/{region}/{language}/List/bekijk-het-overzicht-van-gratis-ebooks/QpkkVWnUw8sxmgjSlCbJRg", + "NL": "https://www.kobo.com/{region}/{language}/" + "List/bekijk-het-overzicht-van-gratis-ebooks/QpkkVWnUw8sxmgjSlCbJRg", "PT": "https://www.kobo.com/{region}/{language}/p/livros-gratis", }, "fte_feedback": "https://storeapi.kobo.com/v1/products/ftefeedback", @@ -1192,7 +1192,8 @@ def NATIVE_KOBO_RESOURCES(): "library_stack": "https://storeapi.kobo.com/v1/user/library/stacks/{LibraryItemId}", "library_sync": "https://storeapi.kobo.com/v1/library/sync", "love_dashboard_page": "https://store.kobobooks.com/{culture}/kobosuperpoints", - "love_points_redemption_page": "https://store.kobobooks.com/{culture}/KoboSuperPointsRedemption?productId={ProductId}", + "love_points_redemption_page": + "https://store.kobobooks.com/{culture}/KoboSuperPointsRedemption?productId={ProductId}", "magazine_landing_page": "https://store.kobobooks.com/emagazines", "notifications_registration_issue": "https://storeapi.kobo.com/v1/notifications/registration", "oauth_host": "https://oauth.kobo.com", @@ -1208,7 +1209,8 @@ def NATIVE_KOBO_RESOURCES(): "product_recommendations": "https://storeapi.kobo.com/v1/products/{ProductId}/recommendations", "product_reviews": "https://storeapi.kobo.com/v1/products/{ProductIds}/reviews", "products": "https://storeapi.kobo.com/v1/products", - "provider_external_sign_in_page": "https://authorize.kobo.com/ExternalSignIn/{providerName}?returnUrl=http://store.kobobooks.com/", + "provider_external_sign_in_page": + "https://authorize.kobo.com/ExternalSignIn/{providerName}?returnUrl=http://store.kobobooks.com/", "purchase_buy": "https://www.kobo.com/checkout/createpurchase/", "purchase_buy_templated": "https://www.kobo.com/{culture}/checkout/createpurchase/{ProductId}", "quickbuy_checkout": "https://storeapi.kobo.com/v1/store/quickbuy/{PurchaseId}/checkout", diff --git a/cps/logger.py b/cps/logger.py index 053d0bd3..fcc25c27 100644 --- a/cps/logger.py +++ b/cps/logger.py @@ -42,7 +42,7 @@ logging.addLevelName(logging.CRITICAL, "CRIT") class _Logger(logging.Logger): - def debug_or_exception(self, message, stacklevel=2, *args, **kwargs): + def error_or_exception(self, message, stacklevel=2, *args, **kwargs): if sys.version_info > (3, 7): if is_debug_enabled(): self.exception(message, stacklevel=stacklevel, *args, **kwargs) diff --git a/cps/metadata_provider/amazon.py b/cps/metadata_provider/amazon.py index 558edebc..da3aed79 100644 --- a/cps/metadata_provider/amazon.py +++ b/cps/metadata_provider/amazon.py @@ -19,14 +19,22 @@ import concurrent.futures import requests from bs4 import BeautifulSoup as BS # requirement +from typing import List, Optional try: import cchardet #optional for better speed except ImportError: pass +from cps import logger from cps.services.Metadata import MetaRecord, MetaSourceInfo, Metadata +import cps.logger as logger + #from time import time from operator import itemgetter +log = logger.create() + +log = logger.create() + class Amazon(Metadata): __name__ = "Amazon" @@ -46,12 +54,16 @@ class Amazon(Metadata): def search( self, query: str, generic_cover: str = "", locale: str = "en" - ): + ) -> Optional[List[MetaRecord]]: #timer=time() - def inner(link,index)->[dict,int]: - with self.session as session: - r = session.get(f"https://www.amazon.com/{link}") - r.raise_for_status() + def inner(link, index) -> [dict, int]: + with self.session as session: + try: + r = session.get(f"https://www.amazon.com/{link}") + r.raise_for_status() + except Exception as ex: + log.warning(ex) + return long_soup = BS(r.text, "lxml") #~4sec :/ soup2 = long_soup.find("div", attrs={"cel_widget_id": "dpx-books-ppd_csm_instrumentation_wrapper"}) if soup2 is None: @@ -65,7 +77,7 @@ class Amazon(Metadata): description="Amazon Books", link="https://amazon.com/" ), - url = f"https://www.amazon.com/{link}", + url = f"https://www.amazon.com{link}", #the more searches the slower, these are too hard to find in reasonable time or might not even exist publisher= "", # very unreliable publishedDate= "", # very unreliable @@ -102,21 +114,28 @@ class Amazon(Metadata): match.cover = "" return match, index except Exception as e: - print(e) + log.error_or_exception(e) return val = list() if self.active: - results = self.session.get( - f"https://www.amazon.com/s?k={query.replace(' ', '+')}&i=digital-text&sprefix={query.replace(' ', '+')}" - f"%2Cdigital-text&ref=nb_sb_noss", - headers=self.headers) - results.raise_for_status() + try: + results = self.session.get( + f"https://www.amazon.com/s?k={query.replace(' ', '+')}&i=digital-text&sprefix={query.replace(' ', '+')}" + f"%2Cdigital-text&ref=nb_sb_noss", + headers=self.headers) + results.raise_for_status() + except requests.exceptions.HTTPError as e: + log.error_or_exception(e) + return None + except Exception as e: + log.warning(e) + return None soup = BS(results.text, 'html.parser') links_list = [next(filter(lambda i: "digital-text" in i["href"], x.findAll("a")))["href"] for x in soup.findAll("div", attrs={"data-component-type": "s-search-result"})] with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor: fut = {executor.submit(inner, link, index) for index, link in enumerate(links_list[:5])} - val=list(map(lambda x : x.result() ,concurrent.futures.as_completed(fut))) - result=list(filter(lambda x: x, val)) + val = list(map(lambda x : x.result() ,concurrent.futures.as_completed(fut))) + result = list(filter(lambda x: x, val)) return [x[0] for x in sorted(result, key=itemgetter(1))] #sort by amazons listing order for best relevance diff --git a/cps/metadata_provider/comicvine.py b/cps/metadata_provider/comicvine.py index 56618d4b..b4d8d34c 100644 --- a/cps/metadata_provider/comicvine.py +++ b/cps/metadata_provider/comicvine.py @@ -21,8 +21,11 @@ from typing import Dict, List, Optional from urllib.parse import quote import requests +from cps import logger from cps.services.Metadata import MetaRecord, MetaSourceInfo, Metadata +log = logger.create() + class ComicVine(Metadata): __name__ = "ComicVine" @@ -46,10 +49,15 @@ class ComicVine(Metadata): if title_tokens: tokens = [quote(t.encode("utf-8")) for t in title_tokens] query = "%20".join(tokens) - result = requests.get( - f"{ComicVine.BASE_URL}{query}{ComicVine.QUERY_PARAMS}", - headers=ComicVine.HEADERS, - ) + try: + result = requests.get( + f"{ComicVine.BASE_URL}{query}{ComicVine.QUERY_PARAMS}", + headers=ComicVine.HEADERS, + ) + result.raise_for_status() + except Exception as e: + log.warning(e) + return None for result in result.json()["results"]: match = self._parse_search_result( result=result, generic_cover=generic_cover, locale=locale diff --git a/cps/metadata_provider/douban.py b/cps/metadata_provider/douban.py new file mode 100644 index 00000000..ee21f587 --- /dev/null +++ b/cps/metadata_provider/douban.py @@ -0,0 +1,206 @@ +# -*- coding: utf-8 -*- + +# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) +# Copyright (C) 2022 xlivevil +# +# 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 . +import re +from concurrent import futures +from typing import List, Optional + +import requests +from html2text import HTML2Text +from lxml import etree + +from cps import logger +from cps.services.Metadata import Metadata, MetaRecord, MetaSourceInfo + +log = logger.create() + + +def html2text(html: str) -> str: + + h2t = HTML2Text() + h2t.body_width = 0 + h2t.single_line_break = True + h2t.emphasis_mark = "*" + return h2t.handle(html) + + +class Douban(Metadata): + __name__ = "豆瓣" + __id__ = "douban" + DESCRIPTION = "豆瓣" + META_URL = "https://book.douban.com/" + SEARCH_URL = "https://www.douban.com/j/search" + + ID_PATTERN = re.compile(r"sid: (?P\d+),") + AUTHORS_PATTERN = re.compile(r"作者|译者") + PUBLISHER_PATTERN = re.compile(r"出版社") + SUBTITLE_PATTERN = re.compile(r"副标题") + PUBLISHED_DATE_PATTERN = re.compile(r"出版年") + SERIES_PATTERN = re.compile(r"丛书") + IDENTIFIERS_PATTERN = re.compile(r"ISBN|统一书号") + + TITTLE_XPATH = "//span[@property='v:itemreviewed']" + COVER_XPATH = "//a[@class='nbg']" + INFO_XPATH = "//*[@id='info']//span[@class='pl']" + TAGS_XPATH = "//a[contains(@class, 'tag')]" + DESCRIPTION_XPATH = "//div[@id='link-report']//div[@class='intro']" + RATING_XPATH = "//div[@class='rating_self clearfix']/strong" + + session = requests.Session() + session.headers = { + 'user-agent': + 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36 Edg/98.0.1108.56', + } + + def search( + self, query: str, generic_cover: str = "", locale: str = "en" + ) -> Optional[List[MetaRecord]]: + if self.active: + log.debug(f"starting search {query} on douban") + if title_tokens := list( + self.get_title_tokens(query, strip_joiners=False) + ): + query = "+".join(title_tokens) + + try: + r = self.session.get( + self.SEARCH_URL, params={"cat": 1001, "q": query} + ) + r.raise_for_status() + + except Exception as e: + log.warning(e) + return None + + results = r.json() + if results["total"] == 0: + return [] + + book_id_list = [ + self.ID_PATTERN.search(item).group("id") + for item in results["items"][:10] if self.ID_PATTERN.search(item) + ] + + with futures.ThreadPoolExecutor(max_workers=5) as executor: + + fut = [ + executor.submit(self._parse_single_book, book_id, generic_cover) + for book_id in book_id_list + ] + + val = [ + future.result() + for future in futures.as_completed(fut) if future.result() + ] + + return val + + def _parse_single_book( + self, id: str, generic_cover: str = "" + ) -> Optional[MetaRecord]: + url = f"https://book.douban.com/subject/{id}/" + + try: + r = self.session.get(url) + r.raise_for_status() + except Exception as e: + log.warning(e) + return None + + match = MetaRecord( + id=id, + title="", + authors=[], + url=url, + source=MetaSourceInfo( + id=self.__id__, + description=self.DESCRIPTION, + link=self.META_URL, + ), + ) + + html = etree.HTML(r.content.decode("utf8")) + + match.title = html.xpath(self.TITTLE_XPATH)[0].text + match.cover = html.xpath(self.COVER_XPATH)[0].attrib["href"] or generic_cover + try: + rating_num = float(html.xpath(self.RATING_XPATH)[0].text.strip()) + except Exception: + rating_num = 0 + match.rating = int(-1 * rating_num // 2 * -1) if rating_num else 0 + + tag_elements = html.xpath(self.TAGS_XPATH) + if len(tag_elements): + match.tags = [tag_element.text for tag_element in tag_elements] + + description_element = html.xpath(self.DESCRIPTION_XPATH) + if len(description_element): + match.description = html2text(etree.tostring( + description_element[-1], encoding="utf8").decode("utf8")) + + info = html.xpath(self.INFO_XPATH) + + for element in info: + text = element.text + if self.AUTHORS_PATTERN.search(text): + next = element.getnext() + while next is not None and next.tag != "br": + match.authors.append(next.text) + next = next.getnext() + elif self.PUBLISHER_PATTERN.search(text): + match.publisher = element.tail.strip() + elif self.SUBTITLE_PATTERN.search(text): + match.title = f'{match.title}:' + element.tail.strip() + elif self.PUBLISHED_DATE_PATTERN.search(text): + match.publishedDate = self._clean_date(element.tail.strip()) + elif self.SUBTITLE_PATTERN.search(text): + match.series = element.getnext().text + elif i_type := self.IDENTIFIERS_PATTERN.search(text): + match.identifiers[i_type.group()] = element.tail.strip() + + return match + + + def _clean_date(self, date: str) -> str: + """ + Clean up the date string to be in the format YYYY-MM-DD + + Examples of possible patterns: + '2014-7-16', '1988年4月', '1995-04', '2021-8', '2020-12-1', '1996年', + '1972', '2004/11/01', '1959年3月北京第1版第1印' + """ + year = date[:4] + moon = "01" + day = "01" + + if len(date) > 5: + digit = [] + ls = [] + for i in range(5, len(date)): + if date[i].isdigit(): + digit.append(date[i]) + elif digit: + ls.append("".join(digit) if len(digit)==2 else f"0{digit[0]}") + digit = [] + if digit: + ls.append("".join(digit) if len(digit)==2 else f"0{digit[0]}") + + moon = ls[0] + if len(ls)>1: + day = ls[1] + + return f"{year}-{moon}-{day}" diff --git a/cps/metadata_provider/google.py b/cps/metadata_provider/google.py index 11e86aa1..98fadd37 100644 --- a/cps/metadata_provider/google.py +++ b/cps/metadata_provider/google.py @@ -22,9 +22,12 @@ from urllib.parse import quote import requests +from cps import logger from cps.isoLanguages import get_lang3, get_language_name from cps.services.Metadata import MetaRecord, MetaSourceInfo, Metadata +log = logger.create() + class Google(Metadata): __name__ = "Google" @@ -45,8 +48,13 @@ class Google(Metadata): if title_tokens: tokens = [quote(t.encode("utf-8")) for t in title_tokens] query = "+".join(tokens) - results = requests.get(Google.SEARCH_URL + query) - for result in results.json()["items"]: + try: + results = requests.get(Google.SEARCH_URL + query) + results.raise_for_status() + except Exception as e: + log.warning(e) + return None + for result in results.json().get("items", []): val.append( self._parse_search_result( result=result, generic_cover=generic_cover, locale=locale diff --git a/cps/metadata_provider/lubimyczytac.py b/cps/metadata_provider/lubimyczytac.py index 814a785e..e4abe9db 100644 --- a/cps/metadata_provider/lubimyczytac.py +++ b/cps/metadata_provider/lubimyczytac.py @@ -27,9 +27,12 @@ from html2text import HTML2Text from lxml.html import HtmlElement, fromstring, tostring from markdown2 import Markdown +from cps import logger from cps.isoLanguages import get_language_name from cps.services.Metadata import MetaRecord, MetaSourceInfo, Metadata +log = logger.create() + SYMBOLS_TO_TRANSLATE = ( "öÖüÜóÓőŐúÚéÉáÁűŰíÍąĄćĆęĘłŁńŃóÓśŚźŹżŻ", "oOuUoOoOuUeEaAuUiIaAcCeElLnNoOsSzZzZ", @@ -112,7 +115,12 @@ class LubimyCzytac(Metadata): self, query: str, generic_cover: str = "", locale: str = "en" ) -> Optional[List[MetaRecord]]: if self.active: - result = requests.get(self._prepare_query(title=query)) + try: + result = requests.get(self._prepare_query(title=query)) + result.raise_for_status() + except Exception as e: + log.warning(e) + return None root = fromstring(result.text) lc_parser = LubimyCzytacParser(root=root, metadata=self) matches = lc_parser.parse_search_results() @@ -200,7 +208,12 @@ class LubimyCzytacParser: def parse_single_book( self, match: MetaRecord, generic_cover: str, locale: str ) -> MetaRecord: - response = requests.get(match.url) + try: + response = requests.get(match.url) + response.raise_for_status() + except Exception as e: + log.warning(e) + return None self.root = fromstring(response.text) match.cover = self._parse_cover(generic_cover=generic_cover) match.description = self._parse_description() diff --git a/cps/metadata_provider/scholar.py b/cps/metadata_provider/scholar.py index bbf50fb3..7feb0ee9 100644 --- a/cps/metadata_provider/scholar.py +++ b/cps/metadata_provider/scholar.py @@ -17,7 +17,7 @@ # along with this program. If not, see . import itertools from typing import Dict, List, Optional -from urllib.parse import quote +from urllib.parse import quote, unquote try: from fake_useragent.errors import FakeUserAgentError @@ -28,8 +28,12 @@ try: except FakeUserAgentError: raise ImportError("No module named 'scholarly'") +from cps import logger from cps.services.Metadata import MetaRecord, MetaSourceInfo, Metadata +log = logger.create() + + class scholar(Metadata): __name__ = "Google Scholar" __id__ = "googlescholar" @@ -44,10 +48,14 @@ class scholar(Metadata): if title_tokens: tokens = [quote(t.encode("utf-8")) for t in title_tokens] query = " ".join(tokens) - scholar_gen = itertools.islice(scholarly.search_pubs(query), 10) + try: + scholar_gen = itertools.islice(scholarly.search_pubs(query), 10) + except Exception as e: + log.warning(e) + return None for result in scholar_gen: match = self._parse_search_result( - result=result, generic_cover=generic_cover, locale=locale + result=result, generic_cover="", locale=locale ) val.append(match) return val @@ -66,7 +74,7 @@ class scholar(Metadata): ) match.cover = result.get("image", {}).get("original_url", generic_cover) - match.description = result["bib"].get("abstract", "") + match.description = unquote(result["bib"].get("abstract", "")) match.publisher = result["bib"].get("venue", "") match.publishedDate = result["bib"].get("pub_year") + "-01-01" match.identifiers = {"scholar": match.id} diff --git a/cps/oauth_bb.py b/cps/oauth_bb.py index d9efd41e..d9a60c0e 100644 --- a/cps/oauth_bb.py +++ b/cps/oauth_bb.py @@ -149,7 +149,7 @@ def bind_oauth_or_register(provider_id, provider_user_id, redirect_url, provider log.info("Link to {} Succeeded".format(provider_name)) return redirect(url_for('web.profile')) except Exception as ex: - log.debug_or_exception(ex) + log.error_or_exception(ex) ub.session.rollback() else: flash(_(u"Login failed, No User Linked With OAuth Account"), category="error") @@ -197,7 +197,7 @@ def unlink_oauth(provider): flash(_(u"Unlink to %(oauth)s Succeeded", oauth=oauth_check[provider]), category="success") log.info("Unlink to {} Succeeded".format(oauth_check[provider])) except Exception as ex: - log.debug_or_exception(ex) + log.error_or_exception(ex) ub.session.rollback() flash(_(u"Unlink to %(oauth)s Failed", oauth=oauth_check[provider]), category="error") except NoResultFound: diff --git a/cps/opds.py b/cps/opds.py index 1f9b9db4..cb8f397e 100644 --- a/cps/opds.py +++ b/cps/opds.py @@ -27,15 +27,14 @@ from functools import wraps 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_, true +from sqlalchemy.exc import InvalidRequestError, OperationalError from werkzeug.security import check_password_hash -from tornado.httputil import HTTPServerRequest from . import constants, logger, config, db, calibre_db, ub, services, get_locale, isoLanguages from .helper import get_download_link, get_book_cover from .pagination import Pagination from .web import render_read_books from .usermanagement import load_user_from_request from flask_babel import gettext as _ - opds = Blueprint('opds', __name__) log = logger.create() @@ -86,7 +85,7 @@ def feed_osd(): @requires_basic_auth_if_no_ano def feed_cc_search(query): # Handle strange query from Libera Reader with + instead of spaces - plus_query = unquote_plus(request.base_url.split('/opds/search/')[1]).strip() + plus_query = unquote_plus(request.environ['RAW_URI'].split('/opds/search/')[1]).strip() return feed_search(plus_query) @@ -99,26 +98,7 @@ def feed_normal_search(): @opds.route("/opds/books") @requires_basic_auth_if_no_ano def feed_booksindex(): - shift = 0 - off = int(request.args.get("offset") or 0) - entries = calibre_db.session.query(func.upper(func.substr(db.Books.sort, 1, 1)).label('id'))\ - .filter(calibre_db.common_filters()).group_by(func.upper(func.substr(db.Books.sort, 1, 1))).all() - - elements = [] - if off == 0: - elements.append({'id': "00", 'name':_("All")}) - shift = 1 - for entry in entries[ - off + shift - 1: - int(off + int(config.config_books_per_page) - shift)]: - elements.append({'id': entry.id, 'name': entry.id}) - - pagination = Pagination((int(off) / (int(config.config_books_per_page)) + 1), config.config_books_per_page, - len(entries) + 1) - return render_xml_template('feed.xml', - letterelements=elements, - folder='opds.feed_letter_books', - pagination=pagination) + return render_element_index(db.Books.sort, None, 'opds.feed_letter_books') @opds.route("/opds/books/letter/") @@ -129,7 +109,8 @@ def feed_letter_books(book_id): entries, __, pagination = calibre_db.fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1), 0, db.Books, letter, - [db.Books.sort]) + [db.Books.sort], + True, config.config_read_column) return render_xml_template('feed.xml', entries=entries, pagination=pagination) @@ -139,15 +120,16 @@ def feed_letter_books(book_id): def feed_new(): 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()]) + db.Books, True, [db.Books.timestamp.desc()], + True, config.config_read_column) return render_xml_template('feed.xml', entries=entries, pagination=pagination) @opds.route("/opds/discover") @requires_basic_auth_if_no_ano def feed_discover(): - entries = calibre_db.session.query(db.Books).filter(calibre_db.common_filters()).order_by(func.random())\ - .limit(config.config_books_per_page) + 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)) return render_xml_template('feed.xml', entries=entries, pagination=pagination) @@ -158,7 +140,8 @@ def feed_best_rated(): 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), - [db.Books.timestamp.desc()]) + [db.Books.timestamp.desc()], + True, config.config_read_column) return render_xml_template('feed.xml', entries=entries, pagination=pagination) @@ -171,43 +154,23 @@ def feed_hot(): hot_books = all_books.offset(off).limit(config.config_books_per_page) entries = list() for book in hot_books: - downloadBook = calibre_db.get_book(book.Downloads.book_id) - if downloadBook: - entries.append( - calibre_db.get_filtered_book(book.Downloads.book_id) - ) + query = calibre_db.generate_linked_query(config.config_read_column, db.Books) + download_book = query.filter(calibre_db.common_filters()).filter( + book.Downloads.book_id == db.Books.id).first() + if download_book: + entries.append(download_book) else: ub.delete_download(book.Downloads.book_id) - numBooks = entries.__len__() + num_books = entries.__len__() pagination = Pagination((int(off) / (int(config.config_books_per_page)) + 1), - config.config_books_per_page, numBooks) + config.config_books_per_page, num_books) return render_xml_template('feed.xml', entries=entries, pagination=pagination) @opds.route("/opds/author") @requires_basic_auth_if_no_ano def feed_authorindex(): - shift = 0 - off = int(request.args.get("offset") or 0) - entries = calibre_db.session.query(func.upper(func.substr(db.Authors.sort, 1, 1)).label('id'))\ - .join(db.books_authors_link).join(db.Books).filter(calibre_db.common_filters())\ - .group_by(func.upper(func.substr(db.Authors.sort, 1, 1))).all() - - elements = [] - if off == 0: - elements.append({'id': "00", 'name':_("All")}) - shift = 1 - for entry in entries[ - off + shift - 1: - int(off + int(config.config_books_per_page) - shift)]: - elements.append({'id': entry.id, 'name': entry.id}) - - pagination = Pagination((int(off) / (int(config.config_books_per_page)) + 1), config.config_books_per_page, - len(entries) + 1) - return render_xml_template('feed.xml', - letterelements=elements, - folder='opds.feed_letter_author', - pagination=pagination) + return render_element_index(db.Authors.sort, db.books_authors_link, 'opds.feed_letter_author') @opds.route("/opds/author/letter/") @@ -228,12 +191,7 @@ def feed_letter_author(book_id): @opds.route("/opds/author/") @requires_basic_auth_if_no_ano def feed_author(book_id): - 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.authors.any(db.Authors.id == book_id), - [db.Books.timestamp.desc()]) - return render_xml_template('feed.xml', entries=entries, pagination=pagination) + return render_xml_dataset(db.Authors, book_id) @opds.route("/opds/publisher") @@ -254,37 +212,14 @@ def feed_publisherindex(): @opds.route("/opds/publisher/") @requires_basic_auth_if_no_ano def feed_publisher(book_id): - 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.publishers.any(db.Publishers.id == book_id), - [db.Books.timestamp.desc()]) - return render_xml_template('feed.xml', entries=entries, pagination=pagination) + return render_xml_dataset(db.Publishers, book_id) @opds.route("/opds/category") @requires_basic_auth_if_no_ano def feed_categoryindex(): - shift = 0 - off = int(request.args.get("offset") or 0) - entries = calibre_db.session.query(func.upper(func.substr(db.Tags.name, 1, 1)).label('id'))\ - .join(db.books_tags_link).join(db.Books).filter(calibre_db.common_filters())\ - .group_by(func.upper(func.substr(db.Tags.name, 1, 1))).all() - elements = [] - if off == 0: - elements.append({'id': "00", 'name':_("All")}) - shift = 1 - for entry in entries[ - off + shift - 1: - int(off + int(config.config_books_per_page) - shift)]: - elements.append({'id': entry.id, 'name': entry.id}) + return render_element_index(db.Tags.name, db.books_tags_link, 'opds.feed_letter_category') - pagination = Pagination((int(off) / (int(config.config_books_per_page)) + 1), config.config_books_per_page, - len(entries) + 1) - return render_xml_template('feed.xml', - letterelements=elements, - folder='opds.feed_letter_category', - pagination=pagination) @opds.route("/opds/category/letter/") @requires_basic_auth_if_no_ano @@ -306,36 +241,14 @@ def feed_letter_category(book_id): @opds.route("/opds/category/") @requires_basic_auth_if_no_ano def feed_category(book_id): - 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.tags.any(db.Tags.id == book_id), - [db.Books.timestamp.desc()]) - return render_xml_template('feed.xml', entries=entries, pagination=pagination) + return render_xml_dataset(db.Tags, book_id) @opds.route("/opds/series") @requires_basic_auth_if_no_ano def feed_seriesindex(): - shift = 0 - off = int(request.args.get("offset") or 0) - entries = calibre_db.session.query(func.upper(func.substr(db.Series.sort, 1, 1)).label('id'))\ - .join(db.books_series_link).join(db.Books).filter(calibre_db.common_filters())\ - .group_by(func.upper(func.substr(db.Series.sort, 1, 1))).all() - elements = [] - if off == 0: - elements.append({'id': "00", 'name':_("All")}) - shift = 1 - for entry in entries[ - off + shift - 1: - int(off + int(config.config_books_per_page) - shift)]: - elements.append({'id': entry.id, 'name': entry.id}) - pagination = Pagination((int(off) / (int(config.config_books_per_page)) + 1), config.config_books_per_page, - len(entries) + 1) - return render_xml_template('feed.xml', - letterelements=elements, - folder='opds.feed_letter_series', - pagination=pagination) + 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 @@ -361,7 +274,8 @@ def feed_series(book_id): entries, __, pagination = calibre_db.fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1), 0, db.Books, db.Books.series.any(db.Series.id == book_id), - [db.Books.series_index]) + [db.Books.series_index], + True, config.config_read_column) return render_xml_template('feed.xml', entries=entries, pagination=pagination) @@ -370,7 +284,7 @@ def feed_series(book_id): def feed_ratingindex(): 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')) \ + (db.Ratings.rating / 2).label('name')) \ .join(db.books_ratings_link)\ .join(db.Books)\ .filter(calibre_db.common_filters()) \ @@ -388,12 +302,7 @@ def feed_ratingindex(): @opds.route("/opds/ratings/") @requires_basic_auth_if_no_ano def feed_ratings(book_id): - 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.id == book_id), - [db.Books.timestamp.desc()]) - return render_xml_template('feed.xml', entries=entries, pagination=pagination) + return render_xml_dataset(db.Ratings, book_id) @opds.route("/opds/formats") @@ -420,7 +329,8 @@ def feed_format(book_id): entries, __, pagination = calibre_db.fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1), 0, db.Books, db.Books.data.any(db.Data.format == book_id.upper()), - [db.Books.timestamp.desc()]) + [db.Books.timestamp.desc()], + True, config.config_read_column) return render_xml_template('feed.xml', entries=entries, pagination=pagination) @@ -447,7 +357,8 @@ def feed_languages(book_id): entries, __, pagination = calibre_db.fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1), 0, db.Books, db.Books.languages.any(db.Languages.id == book_id), - [db.Books.timestamp.desc()]) + [db.Books.timestamp.desc()], + True, config.config_read_column) return render_xml_template('feed.xml', entries=entries, pagination=pagination) @@ -477,13 +388,25 @@ def feed_shelf(book_id): result = list() # user is allowed to access shelf if shelf: - books_in_shelf = ub.session.query(ub.BookShelf).filter(ub.BookShelf.shelf == book_id).order_by( - ub.BookShelf.order.asc()).all() - for book in books_in_shelf: - cur_book = calibre_db.get_book(book.book_id) - result.append(cur_book) - pagination = Pagination((int(off) / (int(config.config_books_per_page)) + 1), config.config_books_per_page, - len(result)) + result, __, pagination = calibre_db.fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1), + config.config_books_per_page, + db.Books, + ub.BookShelf.shelf == shelf.id, + [ub.BookShelf.order.asc()], + True, config.config_read_column, + ub.BookShelf, ub.BookShelf.book_id == db.Books.id) + # delete shelf entries where book is not existent anymore, can happen if book is deleted outside calibre-web + wrong_entries = calibre_db.session.query(ub.BookShelf) \ + .join(db.Books, ub.BookShelf.book_id == db.Books.id, isouter=True) \ + .filter(db.Books.id == None).all() + for entry in wrong_entries: + log.info('Not existing book {} in {} deleted'.format(entry.book_id, shelf)) + try: + ub.session.query(ub.BookShelf).filter(ub.BookShelf.book_id == entry.book_id).delete() + ub.session.commit() + except (OperationalError, InvalidRequestError) as e: + ub.session.rollback() + log.error_or_exception("Settings Database error: {}".format(e)) return render_xml_template('feed.xml', entries=result, pagination=pagination) @@ -491,7 +414,7 @@ def feed_shelf(book_id): @requires_basic_auth_if_no_ano def opds_download_link(book_id, book_format): # I gave up with this: With enabled ldap login, the user doesn't get logged in, therefore it's always guest - # workaround, loading the user from the request and checking it's download rights here + # workaround, loading the user from the request and checking its download rights here # in case of anonymous browsing user is None user = load_user_from_request(request) or current_user if not user.role_download(): @@ -517,48 +440,6 @@ def get_metadata_calibre_companion(uuid, library): return "" -def feed_search(term): - if term: - entries, __, ___ = calibre_db.get_search_results(term, config_read_column=config.config_read_column) - entries_count = len(entries) if len(entries) > 0 else 1 - pagination = Pagination(1, entries_count, entries_count) - items = [entry[0] for entry in entries] - return render_xml_template('feed.xml', searchterm=term, entries=items, pagination=pagination) - else: - return render_xml_template('feed.xml', searchterm="") - - -def check_auth(username, password): - try: - username = username.encode('windows-1252') - except UnicodeEncodeError: - username = username.encode('utf-8') - user = ub.session.query(ub.User).filter(func.lower(ub.User.name) == - username.decode('utf-8').lower()).first() - if bool(user and check_password_hash(str(user.password), password)): - return True - else: - ip_Address = request.headers.get('X-Forwarded-For', request.remote_addr) - log.warning('OPDS Login failed for user "%s" IP-address: %s', username.decode('utf-8'), ip_Address) - return False - - -def authenticate(): - return Response( - 'Could not verify your access level for that URL.\n' - 'You have to login with proper credentials', 401, - {'WWW-Authenticate': 'Basic realm="Login Required"'}) - - -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) - response = make_response(xml) - response.headers["Content-Type"] = "application/atom+xml; charset=utf-8" - return response - - @opds.route("/opds/thumb_240_240/") @opds.route("/opds/cover_240_240/") @opds.route("/opds/cover_90_90/") @@ -582,3 +463,78 @@ def feed_unread_books(): 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) + + +def feed_search(term): + if term: + entries, __, ___ = calibre_db.get_search_results(term, config=config) + entries_count = len(entries) if len(entries) > 0 else 1 + pagination = Pagination(1, entries_count, entries_count) + return render_xml_template('feed.xml', searchterm=term, entries=entries, pagination=pagination) + else: + return render_xml_template('feed.xml', searchterm="") + + +def check_auth(username, password): + try: + username = username.encode('windows-1252') + except UnicodeEncodeError: + username = username.encode('utf-8') + user = ub.session.query(ub.User).filter(func.lower(ub.User.name) == + username.decode('utf-8').lower()).first() + if bool(user and check_password_hash(str(user.password), password)): + return True + else: + ip_address = request.headers.get('X-Forwarded-For', request.remote_addr) + log.warning('OPDS Login failed for user "%s" IP-address: %s', username.decode('utf-8'), ip_address) + return False + + +def authenticate(): + return Response( + 'Could not verify your access level for that URL.\n' + 'You have to login with proper credentials', 401, + {'WWW-Authenticate': 'Basic realm="Login Required"'}) + + +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) + response = make_response(xml) + response.headers["Content-Type"] = "application/atom+xml; charset=utf-8" + return response + + +def render_xml_dataset(data_table, book_id): + 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, + getattr(db.Books, data_table.__tablename__).any(data_table.id == book_id), + [db.Books.timestamp.desc()], + True, config.config_read_column) + return render_xml_template('feed.xml', entries=entries, pagination=pagination) + + +def render_element_index(database_column, linked_table, folder): + shift = 0 + off = int(request.args.get("offset") or 0) + entries = calibre_db.session.query(func.upper(func.substr(database_column, 1, 1)).label('id'), None, None) + # query = calibre_db.generate_linked_query(config.config_read_column, db.Books) + if linked_table is not None: + entries = entries.join(linked_table).join(db.Books) + entries = entries.filter(calibre_db.common_filters()).group_by(func.upper(func.substr(database_column, 1, 1))).all() + elements = [] + if off == 0: + elements.append({'id': "00", 'name': _("All")}) + shift = 1 + for entry in entries[ + off + shift - 1: + int(off + int(config.config_books_per_page) - shift)]: + elements.append({'id': entry.id, 'name': entry.id}) + pagination = Pagination((int(off) / (int(config.config_books_per_page)) + 1), config.config_books_per_page, + len(entries) + 1) + return render_xml_template('feed.xml', + letterelements=elements, + folder=folder, + pagination=pagination) diff --git a/cps/pagination.py b/cps/pagination.py index 7a9bfb70..bda9f4c8 100644 --- a/cps/pagination.py +++ b/cps/pagination.py @@ -57,10 +57,10 @@ class Pagination(object): def has_next(self): return self.page < self.pages - # right_edge: last right_edges count of all pages are shown as number, means, if 10 pages are paginated -> 9,10 shwn - # left_edge: first left_edges count of all pages are shown as number -> 1,2 shwn - # left_current: left_current count below current page are shown as number, means if current page 5 -> 3,4 shwn - # left_current: right_current count above current page are shown as number, means if current page 5 -> 6,7 shwn + # right_edge: last right_edges count of all pages are shown as number, means, if 10 pages are paginated -> 9,10 shown + # left_edge: first left_edges count of all pages are shown as number -> 1,2 shown + # left_current: left_current count below current page are shown as number, means if current page 5 -> 3,4 shown + # left_current: right_current count above current page are shown as number, means if current page 5 -> 6,7 shown def iter_pages(self, left_edge=2, left_current=2, right_current=4, right_edge=2): last = 0 diff --git a/cps/remotelogin.py b/cps/remotelogin.py index a9994f09..ea613c29 100644 --- a/cps/remotelogin.py +++ b/cps/remotelogin.py @@ -22,6 +22,7 @@ import json from datetime import datetime +from functools import wraps from flask import Blueprint, request, make_response, abort, url_for, flash, redirect from flask_login import login_required, current_user, login_user @@ -31,10 +32,6 @@ from sqlalchemy.sql.expression import true from . import config, logger, ub from .render_template import render_title_template -try: - from functools import wraps -except ImportError: - pass # We're not using Python 3 remotelogin = Blueprint('remotelogin', __name__) log = logger.create() diff --git a/cps/render_template.py b/cps/render_template.py index 7cd341ea..d2f40d6c 100644 --- a/cps/render_template.py +++ b/cps/render_template.py @@ -16,13 +16,13 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -from flask import render_template +from flask import render_template, request from flask_babel import gettext as _ -from flask import g +from flask import g, abort from werkzeug.local import LocalProxy from flask_login import current_user -from . import config, constants, ub, logger, db, calibre_db +from . import config, constants, logger from .ub import User @@ -30,6 +30,8 @@ log = logger.create() def get_sidebar_config(kwargs=None): kwargs = kwargs or [] + simple = bool([e for e in ['kindle', 'tolino', "kobo", "bookeen"] + if (e in request.headers.get('User-Agent', "").lower())]) if 'content' in kwargs: content = kwargs['content'] content = isinstance(content, (User, LocalProxy)) and not content.role_anonymous() @@ -93,14 +95,14 @@ def get_sidebar_config(kwargs=None): {"glyph": "glyphicon-trash", "text": _('Archived Books'), "link": 'web.books_list', "id": "archived", "visibility": constants.SIDEBAR_ARCHIVED, 'public': (not g.user.is_anonymous), "page": "archived", "show_text": _('Show archived books'), "config_show": content}) - sidebar.append( - {"glyph": "glyphicon-th-list", "text": _('Books List'), "link": 'web.books_table', "id": "list", - "visibility": constants.SIDEBAR_LIST, 'public': (not g.user.is_anonymous), "page": "list", - "show_text": _('Show Books List'), "config_show": content}) + if not simple: + sidebar.append( + {"glyph": "glyphicon-th-list", "text": _('Books List'), "link": 'web.books_table', "id": "list", + "visibility": constants.SIDEBAR_LIST, 'public': (not g.user.is_anonymous), "page": "list", + "show_text": _('Show Books List'), "config_show": content}) + return sidebar, simple - return sidebar - -def get_readbooks_ids(): +'''def get_readbooks_ids(): if not config.config_read_column: readBooks = ub.session.query(ub.ReadBook).filter(ub.ReadBook.user_id == int(current_user.id))\ .filter(ub.ReadBook.read_status == ub.ReadBook.STATUS_FINISHED).all() @@ -110,13 +112,17 @@ def get_readbooks_ids(): readBooks = calibre_db.session.query(db.cc_classes[config.config_read_column])\ .filter(db.cc_classes[config.config_read_column].value == True).all() return frozenset([x.book for x in readBooks]) - except (KeyError, AttributeError): - log.error("Custom Column No.%d is not existing in calibre database", config.config_read_column) - return [] + except (KeyError, AttributeError, IndexError): + log.error("Custom Column No.{} is not existing in calibre database".format(config.config_read_column)) + return []''' # Returns the template for rendering and includes the instance name def render_title_template(*args, **kwargs): - sidebar = get_sidebar_config(kwargs) - return render_template(instance=config.config_calibre_web_title, sidebar=sidebar, - accept=constants.EXTENSIONS_UPLOAD, read_book_ids=get_readbooks_ids(), - *args, **kwargs) + sidebar, simple = get_sidebar_config(kwargs) + try: + return render_template(instance=config.config_calibre_web_title, sidebar=sidebar, simple=simple, + accept=constants.EXTENSIONS_UPLOAD, + *args, **kwargs) + except PermissionError: + log.error("No permission to access {} file.".format(args[0])) + abort(403) diff --git a/cps/schedule.py b/cps/schedule.py new file mode 100644 index 00000000..9bc248f1 --- /dev/null +++ b/cps/schedule.py @@ -0,0 +1,97 @@ +# -*- coding: utf-8 -*- + +# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) +# Copyright (C) 2020 mmonkey +# +# 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 . + +import datetime + +from . import config, constants +from .services.background_scheduler import BackgroundScheduler, use_APScheduler +from .tasks.database import TaskReconnectDatabase +from .tasks.thumbnail import TaskGenerateCoverThumbnails, TaskGenerateSeriesThumbnails, TaskClearCoverThumbnailCache +from .services.worker import WorkerThread + + +def get_scheduled_tasks(reconnect=True): + tasks = list() + # config.schedule_reconnect or + # Reconnect Calibre database (metadata.db) + if reconnect: + tasks.append([lambda: TaskReconnectDatabase(), 'reconnect', False]) + + # Generate all missing book cover thumbnails + if config.schedule_generate_book_covers: + tasks.append([lambda: TaskClearCoverThumbnailCache(0), 'delete superfluous book covers', True]) + tasks.append([lambda: TaskGenerateCoverThumbnails(), 'generate book covers', False]) + + # Generate all missing series thumbnails + if config.schedule_generate_series_covers: + tasks.append([lambda: TaskGenerateSeriesThumbnails(), 'generate book covers', False]) + + return tasks + + +def end_scheduled_tasks(): + worker = WorkerThread.get_instance() + for __, __, __, task, __ in worker.tasks: + if task.scheduled and task.is_cancellable: + worker.end_task(task.id) + + +def register_scheduled_tasks(reconnect=True): + scheduler = BackgroundScheduler() + + if scheduler: + # Remove all existing jobs + scheduler.remove_all_jobs() + + start = config.schedule_start_time + duration = config.schedule_duration + + # Register scheduled tasks + scheduler.schedule_tasks(tasks=get_scheduled_tasks(), trigger='cron', hour=start) + end_time = calclulate_end_time(start, duration) + scheduler.schedule(func=end_scheduled_tasks, trigger='cron', name="end scheduled task", hour=end_time.hour, + minute=end_time.minute) + + # Kick-off tasks, if they should currently be running + if should_task_be_running(start, duration): + scheduler.schedule_tasks_immediately(tasks=get_scheduled_tasks(reconnect)) + + +def register_startup_tasks(): + scheduler = BackgroundScheduler() + + if scheduler: + start = config.schedule_start_time + duration = config.schedule_duration + + # Run scheduled tasks immediately for development and testing + # Ignore tasks that should currently be running, as these will be added when registering scheduled tasks + if constants.APP_MODE in ['development', 'test'] and not should_task_be_running(start, duration): + scheduler.schedule_tasks_immediately(tasks=get_scheduled_tasks(False)) + + +def should_task_be_running(start, duration): + now = datetime.datetime.now() + start_time = datetime.datetime.now().replace(hour=start, minute=0, second=0, microsecond=0) + end_time = start_time + datetime.timedelta(hours=duration // 60, minutes=duration % 60) + return start_time < now < end_time + +def calclulate_end_time(start, duration): + start_time = datetime.datetime.now().replace(hour=start, minute=0) + return start_time + datetime.timedelta(hours=duration // 60, minutes=duration % 60) + diff --git a/cps/search_metadata.py b/cps/search_metadata.py index d72273f6..0070e78f 100644 --- a/cps/search_metadata.py +++ b/cps/search_metadata.py @@ -23,7 +23,7 @@ import json import os import sys # from time import time -from dataclasses import asdict + from flask import Blueprint, Response, request, url_for from flask_login import current_user @@ -32,7 +32,7 @@ from sqlalchemy.exc import InvalidRequestError, OperationalError from sqlalchemy.orm.attributes import flag_modified from cps.services.Metadata import Metadata -from . import constants, get_locale, logger, ub +from . import constants, get_locale, logger, ub, web_server # current_milli_time = lambda: int(round(time() * 1000)) @@ -40,6 +40,14 @@ meta = Blueprint("metadata", __name__) log = logger.create() +try: + from dataclasses import asdict +except ImportError: + log.info('*** "dataclasses" is needed for calibre-web to run. Please install it using pip: "pip install dataclasses" ***') + print('*** "dataclasses" is needed for calibre-web to run. Please install it using pip: "pip install dataclasses" ***') + web_server.stop(True) + sys.exit(6) + new_list = list() meta_dir = os.path.join(constants.BASE_DIR, "cps", "metadata_provider") modules = os.listdir(os.path.join(constants.BASE_DIR, "cps", "metadata_provider")) @@ -49,7 +57,7 @@ for f in modules: try: importlib.import_module("cps.metadata_provider." + a) new_list.append(a) - except ImportError as e: + except (ImportError, IndentationError, SyntaxError) as e: log.error("Import error for metadata source: {} - {}".format(a, e)) pass @@ -130,6 +138,6 @@ def metadata_search(): if active.get(c.__id__, True) } for future in concurrent.futures.as_completed(meta): - data.extend([asdict(x) for x in future.result()]) + data.extend([asdict(x) for x in future.result() if x]) # log.info({'Time elapsed {}'.format(current_milli_time()-start)}) return Response(json.dumps(data), mimetype="application/json") diff --git a/cps/server.py b/cps/server.py index e261c50a..0ffdbd18 100644 --- a/cps/server.py +++ b/cps/server.py @@ -25,6 +25,7 @@ import subprocess # nosec try: from gevent.pywsgi import WSGIServer + from .gevent_wsgi import MyWSGIHandler from gevent.pool import Pool from gevent import __version__ as _version from greenlet import GreenletExit @@ -32,7 +33,7 @@ try: VERSION = 'Gevent ' + _version _GEVENT = True except ImportError: - from tornado.wsgi import WSGIContainer + from .tornado_wsgi import MyWSGIContainer from tornado.httpserver import HTTPServer from tornado.ioloop import IOLoop from tornado import version as _version @@ -202,7 +203,8 @@ class WebServer(object): if output is None: output = _readable_listen_address(self.listen_address, self.listen_port) log.info('Starting Gevent server on %s', output) - self.wsgiserver = WSGIServer(sock, self.app, log=self.access_logger, spawn=Pool(), **ssl_args) + self.wsgiserver = WSGIServer(sock, self.app, log=self.access_logger, handler_class=MyWSGIHandler, + spawn=Pool(), **ssl_args) if ssl_args: wrap_socket = self.wsgiserver.wrap_socket def my_wrap_socket(*args, **kwargs): @@ -225,8 +227,8 @@ class WebServer(object): asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy()) log.info('Starting Tornado server on %s', _readable_listen_address(self.listen_address, self.listen_port)) - # Max Buffersize set to 200MB ) - http_server = HTTPServer(WSGIContainer(self.app), + # Max Buffersize set to 200MB + http_server = HTTPServer(MyWSGIContainer(self.app), max_buffer_size=209700000, ssl_options=self.ssl_args) http_server.listen(self.listen_port, self.listen_address) diff --git a/cps/services/background_scheduler.py b/cps/services/background_scheduler.py new file mode 100644 index 00000000..27285fd9 --- /dev/null +++ b/cps/services/background_scheduler.py @@ -0,0 +1,84 @@ +# -*- coding: utf-8 -*- + +# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) +# Copyright (C) 2020 mmonkey +# +# 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 . + +import atexit + +from .. import logger +from .worker import WorkerThread + +try: + from apscheduler.schedulers.background import BackgroundScheduler as BScheduler + use_APScheduler = True +except (ImportError, RuntimeError) as e: + use_APScheduler = False + log = logger.create() + log.info('APScheduler not found. Unable to schedule tasks.') + + +class BackgroundScheduler: + _instance = None + + def __new__(cls): + if not use_APScheduler: + return False + + if cls._instance is None: + cls._instance = super(BackgroundScheduler, cls).__new__(cls) + cls.log = logger.create() + cls.scheduler = BScheduler() + cls.scheduler.start() + + atexit.register(lambda: cls.scheduler.shutdown()) + + return cls._instance + + def schedule(self, func, trigger, name=None, **trigger_args): + if use_APScheduler: + return self.scheduler.add_job(func=func, trigger=trigger, name=name, **trigger_args) + + # Expects a lambda expression for the task + def schedule_task(self, task, user=None, name=None, hidden=False, trigger='cron', **trigger_args): + if use_APScheduler: + def scheduled_task(): + worker_task = task() + worker_task.scheduled = True + WorkerThread.add(user, worker_task, hidden=hidden) + return self.schedule(func=scheduled_task, trigger=trigger, name=name, **trigger_args) + + # Expects a list of lambda expressions for the tasks + def schedule_tasks(self, tasks, user=None, trigger='cron', **trigger_args): + if use_APScheduler: + for task in tasks: + self.schedule_task(task[0], user=user, trigger=trigger, name=task[1], hidden=task[2], **trigger_args) + + # Expects a lambda expression for the task + def schedule_task_immediately(self, task, user=None, name=None, hidden=False): + if use_APScheduler: + def immediate_task(): + WorkerThread.add(user, task(), hidden) + return self.schedule(func=immediate_task, trigger='date', name=name) + + # Expects a list of lambda expressions for the tasks + def schedule_tasks_immediately(self, tasks, user=None): + if use_APScheduler: + for task in tasks: + self.schedule_task_immediately(task[0], user, name="immediately " + task[1], hidden=task[2]) + + # Remove all jobs + def remove_all_jobs(self): + self.scheduler.remove_all_jobs() diff --git a/cps/services/gmail.py b/cps/services/gmail.py index ff36b308..3a4eab7f 100644 --- a/cps/services/gmail.py +++ b/cps/services/gmail.py @@ -25,7 +25,7 @@ from google.oauth2.credentials import Credentials from datetime import datetime import base64 from flask_babel import gettext as _ -from ..constants import BASE_DIR +from ..constants import CONFIG_DIR from .. import logger @@ -53,11 +53,11 @@ def setup_gmail(token): if creds and creds.expired and creds.refresh_token: creds.refresh(Request()) else: - cred_file = os.path.join(BASE_DIR, 'gmail.json') + cred_file = os.path.join(CONFIG_DIR, 'gmail.json') if not os.path.exists(cred_file): raise Exception(_("Found no valid gmail.json file with OAuth information")) flow = InstalledAppFlow.from_client_secrets_file( - os.path.join(BASE_DIR, 'gmail.json'), SCOPES) + os.path.join(CONFIG_DIR, 'gmail.json'), SCOPES) creds = flow.run_local_server(port=0) user_info = get_user_info(creds) return { diff --git a/cps/services/worker.py b/cps/services/worker.py index 076c9104..63d83bfb 100644 --- a/cps/services/worker.py +++ b/cps/services/worker.py @@ -37,11 +37,13 @@ STAT_WAITING = 0 STAT_FAIL = 1 STAT_STARTED = 2 STAT_FINISH_SUCCESS = 3 +STAT_ENDED = 4 +STAT_CANCELLED = 5 # Only retain this many tasks in dequeued list TASK_CLEANUP_TRIGGER = 20 -QueuedTask = namedtuple('QueuedTask', 'num, user, added, task') +QueuedTask = namedtuple('QueuedTask', 'num, user, added, task, hidden') def _get_main_thread(): @@ -51,7 +53,6 @@ def _get_main_thread(): raise Exception("main thread not found?!") - class ImprovedQueue(queue.Queue): def to_list(self): """ @@ -61,12 +62,13 @@ class ImprovedQueue(queue.Queue): with self.mutex: return list(self.queue) + # Class for all worker tasks in the background class WorkerThread(threading.Thread): _instance = None @classmethod - def getInstance(cls): + def get_instance(cls): if cls._instance is None: cls._instance = WorkerThread() return cls._instance @@ -82,15 +84,17 @@ class WorkerThread(threading.Thread): self.start() @classmethod - def add(cls, user, task): - ins = cls.getInstance() + def add(cls, user, task, hidden=False): + ins = cls.get_instance() ins.num += 1 - log.debug("Add Task for user: {} - {}".format(user, task)) + username = user if user is not None else 'System' + log.debug("Add Task for user: {} - {}".format(username, task)) ins.queue.put(QueuedTask( num=ins.num, - user=user, + user=username, added=datetime.now(), task=task, + hidden=hidden )) @property @@ -111,10 +115,10 @@ class WorkerThread(threading.Thread): if delta > TASK_CLEANUP_TRIGGER: ret = alive else: - # otherwise, lop off the oldest dead tasks until we hit the target trigger - ret = sorted(dead, key=lambda x: x.task.end_time)[-TASK_CLEANUP_TRIGGER:] + alive + # otherwise, loop off the oldest dead tasks until we hit the target trigger + ret = sorted(dead, key=lambda y: y.task.end_time)[-TASK_CLEANUP_TRIGGER:] + alive - self.dequeued = sorted(ret, key=lambda x: x.num) + self.dequeued = sorted(ret, key=lambda y: y.num) # Main thread loop starting the different tasks def run(self): @@ -141,11 +145,21 @@ class WorkerThread(threading.Thread): # sometimes tasks (like Upload) don't actually have work to do and are created as already finished if item.task.stat is STAT_WAITING: - # CalibreTask.start() should wrap all exceptions in it's own error handling + # CalibreTask.start() should wrap all exceptions in its own error handling item.task.start(self) + # remove self_cleanup tasks and hidden "System Tasks" from list + if item.task.self_cleanup or item.hidden: + self.dequeued.remove(item) + self.queue.task_done() + def end_task(self, task_id): + ins = self.get_instance() + for __, __, __, task, __ in ins.tasks: + if str(task.id) == str(task_id) and task.is_cancellable: + task.stat = STAT_CANCELLED if task.stat == STAT_WAITING else STAT_ENDED + class CalibreTask: __metaclass__ = abc.ABCMeta @@ -158,10 +172,12 @@ class CalibreTask: self.end_time = None self.message = message self.id = uuid.uuid4() + self.self_cleanup = False + self._scheduled = False @abc.abstractmethod def run(self, worker_thread): - """Provides the caller some human-readable name for this class""" + """The main entry-point for this task""" raise NotImplementedError @abc.abstractmethod @@ -169,6 +185,11 @@ class CalibreTask: """Provides the caller some human-readable name for this class""" raise NotImplementedError + @abc.abstractmethod + def is_cancellable(self): + """Does this task gracefully handle being cancelled (STAT_ENDED, STAT_CANCELLED)?""" + raise NotImplementedError + def start(self, *args): self.start_time = datetime.now() self.stat = STAT_STARTED @@ -178,7 +199,7 @@ class CalibreTask: self.run(*args) except Exception as ex: self._handleError(str(ex)) - log.debug_or_exception(ex) + log.error_or_exception(ex) self.end_time = datetime.now() @@ -219,15 +240,23 @@ class CalibreTask: We have a separate dictating this because there may be certain tasks that want to override this """ # By default, we're good to clean a task if it's "Done" - return self.stat in (STAT_FINISH_SUCCESS, STAT_FAIL) + return self.stat in (STAT_FINISH_SUCCESS, STAT_FAIL, STAT_ENDED, STAT_CANCELLED) - '''@progress.setter - def progress(self, x): - if x > 1: - x = 1 - if x < 0: - x = 0 - self._progress = x''' + @property + def self_cleanup(self): + return self._self_cleanup + + @self_cleanup.setter + def self_cleanup(self, is_self_cleanup): + self._self_cleanup = is_self_cleanup + + @property + def scheduled(self): + return self._scheduled + + @scheduled.setter + def scheduled(self, is_scheduled): + self._scheduled = is_scheduled def _handleError(self, error_message): self.stat = STAT_FAIL diff --git a/cps/shelf.py b/cps/shelf.py index 27939cdc..35f2941d 100644 --- a/cps/shelf.py +++ b/cps/shelf.py @@ -94,10 +94,10 @@ def add_to_shelf(shelf_id, book_id): try: ub.session.merge(shelf) ub.session.commit() - except (OperationalError, InvalidRequestError): + except (OperationalError, InvalidRequestError) as e: ub.session.rollback() - log.error("Settings DB is not Writeable") - flash(_(u"Settings DB is not Writeable"), category="error") + log.error_or_exception("Settings Database error: {}".format(e)) + flash(_(u"Database error: %(error)s.", error=e.orig), category="error") if "HTTP_REFERER" in request.environ: return redirect(request.environ["HTTP_REFERER"]) else: @@ -154,10 +154,10 @@ def search_to_shelf(shelf_id): ub.session.merge(shelf) ub.session.commit() flash(_(u"Books have been added to shelf: %(sname)s", sname=shelf.name), category="success") - except (OperationalError, InvalidRequestError): + except (OperationalError, InvalidRequestError) as e: ub.session.rollback() - log.error("Settings DB is not Writeable") - flash(_("Settings DB is not Writeable"), category="error") + log.error_or_exception("Settings Database error: {}".format(e)) + flash(_(u"Database error: %(error)s.", error=e.orig), category="error") else: log.error("Could not add books to shelf: {}".format(shelf.name)) flash(_(u"Could not add books to shelf: %(sname)s", sname=shelf.name), category="error") @@ -197,10 +197,10 @@ def remove_from_shelf(shelf_id, book_id): ub.session.delete(book_shelf) shelf.last_modified = datetime.utcnow() ub.session.commit() - except (OperationalError, InvalidRequestError): + except (OperationalError, InvalidRequestError) as e: ub.session.rollback() - log.error("Settings DB is not Writeable") - flash(_("Settings DB is not Writeable"), category="error") + log.error_or_exception("Settings Database error: {}".format(e)) + flash(_(u"Database error: %(error)s.", error=e.orig), category="error") if "HTTP_REFERER" in request.environ: return redirect(request.environ["HTTP_REFERER"]) else: @@ -273,12 +273,12 @@ def create_edit_shelf(shelf, page_title, page, shelf_id=False): return redirect(url_for('shelf.show_shelf', shelf_id=shelf.id)) except (OperationalError, InvalidRequestError) as ex: ub.session.rollback() - log.debug_or_exception(ex) - log.error("Settings DB is not Writeable") - flash(_("Settings DB is not Writeable"), category="error") + log.error_or_exception(ex) + log.error_or_exception("Settings Database error: {}".format(ex)) + flash(_(u"Database error: %(error)s.", error=ex.orig), category="error") except Exception as ex: ub.session.rollback() - log.debug_or_exception(ex) + log.error_or_exception(ex) flash(_(u"There was an error"), category="error") return render_title_template('shelf_edit.html', shelf=shelf, @@ -337,10 +337,10 @@ def delete_shelf(shelf_id): flash(_("Error deleting Shelf"), category="error") else: flash(_("Shelf successfully deleted"), category="success") - except InvalidRequestError: + except InvalidRequestError as e: ub.session.rollback() - log.error("Settings DB is not Writeable") - flash(_("Settings DB is not Writeable"), category="error") + log.error_or_exception("Settings Database error: {}".format(e)) + flash(_(u"Database error: %(error)s.", error=e.orig), category="error") return redirect(url_for('web.index')) @@ -374,10 +374,10 @@ def order_shelf(shelf_id): # if order diffrent from before -> shelf.last_modified = datetime.utcnow() try: ub.session.commit() - except (OperationalError, InvalidRequestError): + except (OperationalError, InvalidRequestError) as e: ub.session.rollback() - log.error("Settings DB is not Writeable") - flash(_("Settings DB is not Writeable"), category="error") + log.error_or_exception("Settings Database error: {}".format(e)) + flash(_(u"Database error: %(error)s.", error=e.orig), category="error") result = list() if shelf: @@ -439,7 +439,7 @@ def render_show_shelf(shelf_type, shelf_id, page_no, sort_param): db.Books, ub.BookShelf.shelf == shelf_id, [ub.BookShelf.order.asc()], - False, 0, + True, config.config_read_column, ub.BookShelf, ub.BookShelf.book_id == db.Books.id) # delete chelf entries where book is not existent anymore, can happen if book is deleted outside calibre-web wrong_entries = calibre_db.session.query(ub.BookShelf) \ @@ -450,10 +450,10 @@ def render_show_shelf(shelf_type, shelf_id, page_no, sort_param): try: ub.session.query(ub.BookShelf).filter(ub.BookShelf.book_id == entry.book_id).delete() ub.session.commit() - except (OperationalError, InvalidRequestError): + except (OperationalError, InvalidRequestError) as e: ub.session.rollback() - log.error("Settings DB is not Writeable") - flash(_("Settings DB is not Writeable"), category="error") + log.error_or_exception("Settings Database error: {}".format(e)) + flash(_(u"Database error: %(error)s.", error=e.orig), category="error") return render_title_template(page, entries=result, diff --git a/cps/static/css/caliBlur.css b/cps/static/css/caliBlur.css index 3a980180..b2b35423 100644 --- a/cps/static/css/caliBlur.css +++ b/cps/static/css/caliBlur.css @@ -5150,7 +5150,7 @@ body.login > div.navbar.navbar-default.navbar-static-top > div > div.navbar-head pointer-events: none } -#DeleteDomain:hover:before, #RestartDialog:hover:before, #ShutdownDialog:hover:before, #StatusDialog:hover:before, #deleteButton, #deleteModal:hover:before, body.mailset > div.container-fluid > div > div.col-sm-10 > div.discover td > a:hover { +#DeleteDomain:hover:before, #RestartDialog:hover:before, #ShutdownDialog:hover:before, #StatusDialog:hover:before, #deleteButton, #deleteModal:hover:before, #cancelTaskModal:hover:before, body.mailset > div.container-fluid > div > div.col-sm-10 > div.discover td > a:hover { cursor: pointer } @@ -5237,7 +5237,11 @@ body.admin > div.container-fluid > div > div.col-sm-10 > div.container-fluid > d margin-bottom: 20px } -body.admin:not(.modal-open) .btn-default { +body.admin > div.container-fluid div.scheduled_tasks_details { + margin-bottom: 20px +} + +body.admin .btn-default { margin-bottom: 10px } @@ -5468,7 +5472,7 @@ body.admin.modal-open .navbar { z-index: 0 !important } -#RestartDialog, #ShutdownDialog, #StatusDialog, #deleteModal { +#RestartDialog, #ShutdownDialog, #StatusDialog, #deleteModal, #cancelTaskModal { top: 0; overflow: hidden; padding-top: 70px; @@ -5478,7 +5482,7 @@ body.admin.modal-open .navbar { background: rgba(0, 0, 0, .5) } -#RestartDialog:before, #ShutdownDialog:before, #StatusDialog:before, #deleteModal:before { +#RestartDialog:before, #ShutdownDialog:before, #StatusDialog:before, #deleteModal:before, #cancelTaskModal:before { content: "\E208"; padding-right: 10px; display: block; @@ -5500,18 +5504,18 @@ body.admin.modal-open .navbar { z-index: 99 } -#RestartDialog.in:before, #ShutdownDialog.in:before, #StatusDialog.in:before, #deleteModal.in:before { +#RestartDialog.in:before, #ShutdownDialog.in:before, #StatusDialog.in:before, #deleteModal.in:before, #cancelTaskModal.in:before { -webkit-transform: translate(0, 0); -ms-transform: translate(0, 0); transform: translate(0, 0) } -#RestartDialog > .modal-dialog, #ShutdownDialog > .modal-dialog, #StatusDialog > .modal-dialog, #deleteModal > .modal-dialog { +#RestartDialog > .modal-dialog, #ShutdownDialog > .modal-dialog, #StatusDialog > .modal-dialog, #deleteModal > .modal-dialog, #cancelTaskModal > .modal-dialog { width: 450px; margin: auto } -#RestartDialog > .modal-dialog > .modal-content, #ShutdownDialog > .modal-dialog > .modal-content, #StatusDialog > .modal-dialog > .modal-content, #deleteModal > .modal-dialog > .modal-content { +#RestartDialog > .modal-dialog > .modal-content, #ShutdownDialog > .modal-dialog > .modal-content, #StatusDialog > .modal-dialog > .modal-content, #deleteModal > .modal-dialog > .modal-content, #cancelTaskModal > .modal-dialog > .modal-content { max-height: calc(100% - 90px); -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, .5); box-shadow: 0 5px 15px rgba(0, 0, 0, .5); @@ -5522,7 +5526,7 @@ body.admin.modal-open .navbar { width: 450px } -#RestartDialog > .modal-dialog > .modal-content > .modal-header, #ShutdownDialog > .modal-dialog > .modal-content > .modal-header, #StatusDialog > .modal-dialog > .modal-content > .modal-header, #deleteModal > .modal-dialog > .modal-content > .modal-header { +#RestartDialog > .modal-dialog > .modal-content > .modal-header, #ShutdownDialog > .modal-dialog > .modal-content > .modal-header, #StatusDialog > .modal-dialog > .modal-content > .modal-header, #deleteModal > .modal-dialog > .modal-content > .modal-header, #cancelTaskModal > .modal-dialog > .modal-content > .modal-header { padding: 15px 20px; border-radius: 3px 3px 0 0; line-height: 1.71428571; @@ -5535,7 +5539,7 @@ body.admin.modal-open .navbar { text-align: left } -#RestartDialog > .modal-dialog > .modal-content > .modal-header:before, #ShutdownDialog > .modal-dialog > .modal-content > .modal-header:before, #StatusDialog > .modal-dialog > .modal-content > .modal-header:before, #deleteModal > .modal-dialog > .modal-content > .modal-header:before { +#RestartDialog > .modal-dialog > .modal-content > .modal-header:before, #ShutdownDialog > .modal-dialog > .modal-content > .modal-header:before, #StatusDialog > .modal-dialog > .modal-content > .modal-header:before, #deleteModal > .modal-dialog > .modal-content > .modal-header:before, #cancelTaskModal > .modal-dialog > .modal-content > .modal-header:before { padding-right: 10px; font-size: 18px; color: #999; @@ -5564,6 +5568,11 @@ body.admin.modal-open .navbar { font-family: plex-icons-new, serif } +#cancelTaskModal > .modal-dialog > .modal-content > .modal-header:before { + content: "\EA6D"; + font-family: plex-icons-new, serif +} + #RestartDialog > .modal-dialog > .modal-content > .modal-header:after { content: "Restart Calibre-Web"; display: inline-block; @@ -5588,7 +5597,13 @@ body.admin.modal-open .navbar { font-size: 20px } -#StatusDialog > .modal-dialog > .modal-content > .modal-header > span, #deleteModal > .modal-dialog > .modal-content > .modal-header > span, #loader > center > img, .rating-mobile { +#cancelTaskModal > .modal-dialog > .modal-content > .modal-header:after { + content: "Delete Book"; + display: inline-block; + font-size: 20px +} + +#StatusDialog > .modal-dialog > .modal-content > .modal-header > span, #deleteModal > .modal-dialog > .modal-content > .modal-header > span, #cancelTaskModal > .modal-dialog > .modal-content > .modal-header > span, #loader > center > img, .rating-mobile { display: none } @@ -5602,7 +5617,7 @@ body.admin.modal-open .navbar { text-align: left } -#ShutdownDialog > .modal-dialog > .modal-content > .modal-body, #StatusDialog > .modal-dialog > .modal-content > .modal-body, #deleteModal > .modal-dialog > .modal-content > .modal-body { +#ShutdownDialog > .modal-dialog > .modal-content > .modal-body, #StatusDialog > .modal-dialog > .modal-content > .modal-body, #deleteModal > .modal-dialog > .modal-content > .modal-body, #cancelTaskModal > .modal-dialog > .modal-content > .modal-body { padding: 20px 20px 40px; font-size: 16px; line-height: 1.6em; @@ -5612,7 +5627,7 @@ body.admin.modal-open .navbar { text-align: left } -#RestartDialog > .modal-dialog > .modal-content > .modal-body > p, #ShutdownDialog > .modal-dialog > .modal-content > .modal-body > p, #StatusDialog > .modal-dialog > .modal-content > .modal-body > p, #deleteModal > .modal-dialog > .modal-content > .modal-body > p { +#RestartDialog > .modal-dialog > .modal-content > .modal-body > p, #ShutdownDialog > .modal-dialog > .modal-content > .modal-body > p, #StatusDialog > .modal-dialog > .modal-content > .modal-body > p, #deleteModal > .modal-dialog > .modal-content > .modal-body > p, #cancelTaskModal > .modal-dialog > .modal-content > .modal-body > p { padding: 20px 20px 0 0; font-size: 16px; line-height: 1.6em; @@ -5621,7 +5636,7 @@ body.admin.modal-open .navbar { background: #282828 } -#RestartDialog > .modal-dialog > .modal-content > .modal-body > .btn-default:not(#restart), #ShutdownDialog > .modal-dialog > .modal-content > .modal-body > .btn-default:not(#shutdown), #deleteModal > .modal-dialog > .modal-content > .modal-footer > .btn-default { +#RestartDialog > .modal-dialog > .modal-content > .modal-body > .btn-default:not(#restart), #ShutdownDialog > .modal-dialog > .modal-content > .modal-body > .btn-default:not(#shutdown), #deleteModal > .modal-dialog > .modal-content > .modal-footer > .btn-default, #cancelTaskModal > .modal-dialog > .modal-content > .modal-footer > .btn-default { float: right; z-index: 9; position: relative; @@ -5669,6 +5684,18 @@ body.admin.modal-open .navbar { border-radius: 3px } +#cancelTaskModal > .modal-dialog > .modal-content > .modal-footer > .btn-danger { + float: right; + z-index: 9; + position: relative; + margin: 0 0 0 10px; + min-width: 80px; + padding: 10px 18px; + font-size: 16px; + line-height: 1.33; + border-radius: 3px +} + #RestartDialog > .modal-dialog > .modal-content > .modal-body > .btn-default:not(#restart) { margin: 25px 0 0 10px } @@ -5681,7 +5708,11 @@ body.admin.modal-open .navbar { margin: 0 0 0 10px } -#RestartDialog > .modal-dialog > .modal-content > .modal-body > .btn-default:not(#restart):hover, #ShutdownDialog > .modal-dialog > .modal-content > .modal-body > .btn-default:not(#shutdown):hover, #deleteModal > .modal-dialog > .modal-content > .modal-footer > .btn-default:hover { +#cancelTaskModal > .modal-dialog > .modal-content > .modal-footer > .btn-default { + margin: 0 0 0 10px +} + +#RestartDialog > .modal-dialog > .modal-content > .modal-body > .btn-default:not(#restart):hover, #ShutdownDialog > .modal-dialog > .modal-content > .modal-body > .btn-default:not(#shutdown):hover, #deleteModal > .modal-dialog > .modal-content > .modal-footer > .btn-default:hover, #cancelTaskModal > .modal-dialog > .modal-content > .modal-footer > .btn-default:hover { background-color: hsla(0, 0%, 100%, .3) } @@ -7303,11 +7334,11 @@ body.edituser.admin > div.container-fluid > div.row-fluid > div.col-sm-10 > div. background-color: transparent !important } - #RestartDialog > .modal-dialog, #ShutdownDialog > .modal-dialog, #StatusDialog > .modal-dialog, #deleteModal > .modal-dialog { + #RestartDialog > .modal-dialog, #ShutdownDialog > .modal-dialog, #StatusDialog > .modal-dialog, #deleteModal > .modal-dialog, #cancelTaskModal > .modal-dialog { max-width: calc(100vw - 40px) } - #RestartDialog > .modal-dialog > .modal-content, #ShutdownDialog > .modal-dialog > .modal-content, #StatusDialog > .modal-dialog > .modal-content, #deleteModal > .modal-dialog > .modal-content { + #RestartDialog > .modal-dialog > .modal-content, #ShutdownDialog > .modal-dialog > .modal-content, #StatusDialog > .modal-dialog > .modal-content, #deleteModal > .modal-dialog > .modal-content, #cancelTaskModal > .modal-dialog > .modal-content { max-width: calc(100vw - 40px); left: 0 } @@ -7457,7 +7488,7 @@ body.edituser.admin > div.container-fluid > div.row-fluid > div.col-sm-10 > div. padding: 30px 15px } - #RestartDialog.in:before, #ShutdownDialog.in:before, #StatusDialog.in:before, #deleteModal.in:before { + #RestartDialog.in:before, #ShutdownDialog.in:before, #StatusDialog.in:before, #deleteModal.in:before, #cancelTaskModal.in:before { left: auto; right: 34px } diff --git a/cps/static/js/details.js b/cps/static/js/details.js index 6f99595d..f0259f8c 100644 --- a/cps/static/js/details.js +++ b/cps/static/js/details.js @@ -28,14 +28,24 @@ $("#have_read_cb").on("change", function() { data: $(this).closest("form").serialize(), error: function(response) { var data = [{type:"danger", message:response.responseText}] - $("#flash_success").remove(); + // $("#flash_success").parent().remove(); $("#flash_danger").remove(); + $(".row-fluid.text-center").remove(); if (!jQuery.isEmptyObject(data)) { - data.forEach(function (item) { - $(".navbar").after('
' + - '
' + item.message + '
' + - '
'); - }); + $("#have_read_cb").prop("checked", !$("#have_read_cb").prop("checked")); + if($("#bookDetailsModal").is(":visible")) { + data.forEach(function (item) { + $(".modal-header").after('
' + item.message + '
'); + }); + } else + { + data.forEach(function (item) { + $(".navbar").after('
' + + '
' + item.message + '
' + + '
'); + }); + } } } }); diff --git a/cps/static/js/edit_books.js b/cps/static/js/edit_books.js index 0bfe078c..c1eb319d 100644 --- a/cps/static/js/edit_books.js +++ b/cps/static/js/edit_books.js @@ -33,7 +33,7 @@ $(".datepicker").datepicker({ if (results) { pubDate = new Date(results[1], parseInt(results[2], 10) - 1, results[3]) || new Date(this.value); $(this).next('input') - .val(pubDate.toLocaleDateString(language)) + .val(pubDate.toLocaleDateString(language.replaceAll("_","-"))) .removeClass("hidden"); } }).trigger("change"); diff --git a/cps/static/js/get_meta.js b/cps/static/js/get_meta.js index 6db1a261..43a40fa6 100644 --- a/cps/static/js/get_meta.js +++ b/cps/static/js/get_meta.js @@ -92,14 +92,19 @@ $(function () { data: {"query": keyword}, dataType: "json", success: function success(data) { - $("#meta-info").html("
    "); - data.forEach(function(book) { - var $book = $(templates.bookResult(book)); - $book.find("img").on("click", function () { - populateForm(book); + if (data.length) { + $("#meta-info").html("
      "); + data.forEach(function(book) { + var $book = $(templates.bookResult(book)); + $book.find("img").on("click", function () { + populateForm(book); + }); + $("#book-list").append($book); }); - $("#book-list").append($book); - }); + } + else { + $("#meta-info").html("

      " + msg.no_result + "!

      " + $("#meta-info")[0].innerHTML) + } }, error: function error() { $("#meta-info").html("

      " + msg.search_error + "!

      " + $("#meta-info")[0].innerHTML); diff --git a/cps/static/js/main.js b/cps/static/js/main.js index 75599d9b..04d47d6b 100755 --- a/cps/static/js/main.js +++ b/cps/static/js/main.js @@ -381,8 +381,8 @@ $(function() { //extraScrollPx: 300 }); $loadMore.on( "append.infiniteScroll", function( event, response, path, data ) { + $(".pagination").addClass("hidden").html(() => $(response).find(".pagination").html()); if ($("body").hasClass("blur")) { - $(".pagination").addClass("hidden").html(() => $(response).find(".pagination").html()); $(" a:not(.dropdown-toggle) ") .removeAttr("data-toggle"); } @@ -474,6 +474,17 @@ $(function() { } }); }); + $("#admin_refresh_cover_cache").click(function() { + confirmDialog("admin_refresh_cover_cache", "GeneralChangeModal", 0, function () { + $.ajax({ + method:"post", + contentType: "application/json; charset=utf-8", + dataType: "json", + url: getPath() + "/ajax/updateThumbnails", + }); + }); + }); + $("#restart_database").click(function() { $("#DialogHeader").addClass("hidden"); $("#DialogFinished").addClass("hidden"); @@ -515,6 +526,7 @@ $(function() { $("#bookDetailsModal") .on("show.bs.modal", function(e) { + $("#flash_danger").remove(); var $modalBody = $(this).find(".modal-body"); // Prevent static assets from loading multiple times diff --git a/cps/static/js/table.js b/cps/static/js/table.js index dce1d06c..548ca8c4 100644 --- a/cps/static/js/table.js +++ b/cps/static/js/table.js @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -/* exported TableActions, RestrictionActions, EbookActions, responseHandler */ +/* exported TableActions, RestrictionActions, EbookActions, TaskActions, responseHandler */ /* global getPath, confirmDialog */ var selections = []; @@ -42,6 +42,24 @@ $(function() { }, 1000); } + $("#cancel_task_confirm").click(function() { + //get data-id attribute of the clicked element + var taskId = $(this).data("task-id"); + $.ajax({ + method: "post", + contentType: "application/json; charset=utf-8", + dataType: "json", + url: window.location.pathname + "/../ajax/canceltask", + data: JSON.stringify({"task_id": taskId}), + }); + }); + //triggered when modal is about to be shown + $("#cancelTaskModal").on("show.bs.modal", function(e) { + //get data-id attribute of the clicked element and store in button + var taskId = $(e.relatedTarget).data("task-id"); + $(e.currentTarget).find("#cancel_task_confirm").data("task-id", taskId); + }); + $("#books-table").on("check.bs.table check-all.bs.table uncheck.bs.table uncheck-all.bs.table", function (e, rowsAfter, rowsBefore) { var rows = rowsAfter; @@ -107,8 +125,9 @@ $(function() { url: window.location.pathname + "/../ajax/simulatemerge", data: JSON.stringify({"Merge_books":selections}), success: function success(booTitles) { + $('#merge_from').empty(); $.each(booTitles.from, function(i, item) { - $("- " + item + "").appendTo("#merge_from"); + $("- " + item + "

      ").appendTo("#merge_from"); }); $("#merge_to").text("- " + booTitles.to); @@ -531,7 +550,7 @@ $(function() { $("#user-table").on("click-cell.bs.table", function (field, value, row, $element) { if (value === "denied_column_value") { - ConfirmDialog("btndeluser", "GeneralDeleteModal", $element.id, user_handle); + confirmDialog("btndeluser", "GeneralDeleteModal", $element.id, user_handle); } }); @@ -581,6 +600,7 @@ function handle_header_buttons () { $(".header_select").removeAttr("disabled"); } } + /* Function for deleting domain restrictions */ function TableActions (value, row) { return [ @@ -618,6 +638,19 @@ function UserActions (value, row) { ].join(""); } +/* Function for cancelling tasks */ +function TaskActions (value, row) { + var cancellableStats = [0, 1, 2]; + if (row.task_id && row.is_cancellable && cancellableStats.includes(row.stat)) { + return [ + "
      ", + "", + "
      " + ].join(""); + } + return ''; +} + /* Function for keeping checked rows */ function responseHandler(res) { $.each(res.rows, function (i, row) { @@ -811,11 +844,13 @@ function checkboxChange(checkbox, userId, field, field_index) { function BookCheckboxChange(checkbox, userId, field) { var value = checkbox.checked ? "True" : "False"; + var element = checkbox; $.ajax({ method: "post", url: getPath() + "/ajax/editbooks/" + field, data: {"pk": userId, "value": value}, error: function(data) { + element.checked = !element.checked; handleListServerResponse([{type:"danger", message:data.responseText}]) }, success: handleListServerResponse diff --git a/cps/tasks/convert.py b/cps/tasks/convert.py index e610b14b..e65d314a 100644 --- a/cps/tasks/convert.py +++ b/cps/tasks/convert.py @@ -18,12 +18,12 @@ import os import re - from glob import glob from shutil import copyfile from markupsafe import escape from sqlalchemy.exc import SQLAlchemyError +from flask_babel import lazy_gettext as N_ from cps.services.worker import CalibreTask from cps import db @@ -35,14 +35,16 @@ from cps.ub import init_db_thread from cps.tasks.mail import TaskEmail from cps import gdriveutils + + log = logger.create() class TaskConvert(CalibreTask): - def __init__(self, file_path, bookid, taskMessage, settings, kindle_mail, user=None): - super(TaskConvert, self).__init__(taskMessage) + def __init__(self, file_path, book_id, task_message, settings, kindle_mail, user=None): + super(TaskConvert, self).__init__(task_message) self.file_path = file_path - self.bookid = bookid + self.book_id = book_id self.title = "" self.settings = settings self.kindle_mail = kindle_mail @@ -54,9 +56,9 @@ class TaskConvert(CalibreTask): self.worker_thread = worker_thread if config.config_use_google_drive: worker_db = db.CalibreDB(expire_on_commit=False) - cur_book = worker_db.get_book(self.bookid) + cur_book = worker_db.get_book(self.book_id) self.title = cur_book.title - data = worker_db.get_book_format(self.bookid, self.settings['old_book_format']) + data = worker_db.get_book_format(self.book_id, self.settings['old_book_format']) df = gdriveutils.getFileFromEbooksFolder(cur_book.path, data.name + "." + self.settings['old_book_format'].lower()) if df: @@ -87,7 +89,7 @@ class TaskConvert(CalibreTask): # if we're sending to kindle after converting, create a one-off task and run it immediately # todo: figure out how to incorporate this into the progress try: - EmailText = _(u"%(book)s send to Kindle", book=escape(self.title)) + EmailText = N_(u"%(book)s send to Kindle", book=escape(self.title)) worker_thread.add(self.user, TaskEmail(self.settings['subject'], self.results["path"], filename, @@ -104,7 +106,7 @@ class TaskConvert(CalibreTask): error_message = None local_db = db.CalibreDB(expire_on_commit=False) file_path = self.file_path - book_id = self.bookid + book_id = self.book_id format_old_ext = u'.' + self.settings['old_book_format'].lower() format_new_ext = u'.' + self.settings['new_book_format'].lower() @@ -112,7 +114,7 @@ class TaskConvert(CalibreTask): # if it does - mark the conversion task as complete and return a success # this will allow send to kindle workflow to continue to work if os.path.isfile(file_path + format_new_ext) or\ - local_db.get_book_format(self.bookid, self.settings['new_book_format']): + local_db.get_book_format(self.book_id, self.settings['new_book_format']): log.info("Book id %d already converted to %s", book_id, format_new_ext) cur_book = local_db.get_book(book_id) self.title = cur_book.title @@ -131,7 +133,7 @@ class TaskConvert(CalibreTask): local_db.session.rollback() log.error("Database error: %s", e) local_db.session.close() - self._handleError(error_message) + self._handleError(N_("Database error: %(error)s.", error=e)) return self._handleSuccess() local_db.session.close() @@ -148,8 +150,7 @@ class TaskConvert(CalibreTask): else: # check if calibre converter-executable is existing if not os.path.exists(config.config_converterpath): - # ToDo Text is not translated - self._handleError(_(u"Calibre ebook-convert %(tool)s not found", tool=config.config_converterpath)) + self._handleError(N_(u"Calibre ebook-convert %(tool)s not found", tool=config.config_converterpath)) return check, error_message = self._convert_calibre(file_path, format_old_ext, format_new_ext) @@ -182,11 +183,11 @@ class TaskConvert(CalibreTask): self._handleSuccess() return os.path.basename(file_path + format_new_ext) else: - error_message = _('%(format)s format not found on disk', format=format_new_ext.upper()) + error_message = N_('%(format)s format not found on disk', format=format_new_ext.upper()) local_db.session.close() log.info("ebook converter failed with error while converting book") if not error_message: - error_message = _('Ebook converter failed with unknown error') + error_message = N_('Ebook converter failed with unknown error') self._handleError(error_message) return @@ -196,7 +197,7 @@ class TaskConvert(CalibreTask): try: p = process_open(command, quotes) except OSError as e: - return 1, _(u"Kepubify-converter failed: %(error)s", error=e) + return 1, N_(u"Kepubify-converter failed: %(error)s", error=e) self.progress = 0.01 while True: nextline = p.stdout.readlines() @@ -217,7 +218,7 @@ class TaskConvert(CalibreTask): copyfile(converted_file[0], (file_path + format_new_ext)) os.unlink(converted_file[0]) else: - return 1, _(u"Converted file not found or more than one file in folder %(folder)s", + return 1, N_(u"Converted file not found or more than one file in folder %(folder)s", folder=os.path.dirname(file_path)) return check, None @@ -241,7 +242,7 @@ class TaskConvert(CalibreTask): p = process_open(command, quotes, newlines=False) except OSError as e: - return 1, _(u"Ebook-converter failed: %(error)s", error=e) + return 1, N_(u"Ebook-converter failed: %(error)s", error=e) while p.poll() is None: nextline = p.stdout.readline() @@ -264,12 +265,16 @@ class TaskConvert(CalibreTask): ele = ele.decode('utf-8', errors="ignore").strip('\n') log.debug(ele) if not ele.startswith('Traceback') and not ele.startswith(' File'): - error_message = _("Calibre failed with error: %(error)s", error=ele) + error_message = N_("Calibre failed with error: %(error)s", error=ele) return check, error_message @property def name(self): - return "Convert" + return N_("Convert") def __str__(self): - return "Convert {} {}".format(self.bookid, self.kindle_mail) + return "Convert {} {}".format(self.book_id, self.kindle_mail) + + @property + def is_cancellable(self): + return False diff --git a/cps/tasks/database.py b/cps/tasks/database.py new file mode 100644 index 00000000..afc4db2c --- /dev/null +++ b/cps/tasks/database.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- + +# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) +# Copyright (C) 2020 mmonkey +# +# 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 urllib.request import urlopen + +from flask_babel import lazy_gettext as N_ + +from cps import config, logger +from cps.services.worker import CalibreTask + + +class TaskReconnectDatabase(CalibreTask): + def __init__(self, task_message=N_('Reconnecting Calibre database')): + super(TaskReconnectDatabase, self).__init__(task_message) + self.log = logger.create() + self.listen_address = config.get_config_ipaddress() + self.listen_port = config.config_port + + + def run(self, worker_thread): + address = self.listen_address if self.listen_address else 'localhost' + port = self.listen_port if self.listen_port else 8083 + + try: + urlopen('http://' + address + ':' + str(port) + '/reconnect') + self._handleSuccess() + except Exception as ex: + self._handleError('Unable to reconnect Calibre database: ' + str(ex)) + + @property + def name(self): + return "Reconnect Database" + + @property + def is_cancellable(self): + return False diff --git a/cps/tasks/mail.py b/cps/tasks/mail.py old mode 100644 new mode 100755 index 03526c8b..ad38a400 --- a/cps/tasks/mail.py +++ b/cps/tasks/mail.py @@ -16,28 +16,18 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import sys import os import smtplib import threading import socket import mimetypes -try: - from StringIO import StringIO - from email.MIMEBase import MIMEBase - from email.MIMEMultipart import MIMEMultipart - from email.MIMEText import MIMEText -except ImportError: - from io import StringIO - from email.mime.base import MIMEBase - from email.mime.multipart import MIMEMultipart - from email.mime.text import MIMEText +from io import StringIO +from email.message import EmailMessage +from email.utils import parseaddr - - -from email import encoders -from email.utils import formatdate, make_msgid +from flask_babel import lazy_gettext as N_ +from email.utils import formatdate from email.generator import Generator from cps.services.worker import CalibreTask @@ -45,6 +35,7 @@ from cps.services import gmail from cps import logger, config from cps import gdriveutils +import uuid log = logger.create() @@ -119,31 +110,48 @@ class EmailSSL(EmailBase, smtplib.SMTP_SSL): class TaskEmail(CalibreTask): - def __init__(self, subject, filepath, attachment, settings, recipient, taskMessage, text, internal=False): - super(TaskEmail, self).__init__(taskMessage) + def __init__(self, subject, filepath, attachment, settings, recipient, task_message, text, internal=False): + super(TaskEmail, self).__init__(task_message) self.subject = subject self.attachment = attachment self.settings = settings self.filepath = filepath - self.recipent = recipient + self.recipient = recipient self.text = text self.asyncSMTP = None self.results = dict() + # from calibre code: + # https://github.com/kovidgoyal/calibre/blob/731ccd92a99868de3e2738f65949f19768d9104c/src/calibre/utils/smtp.py#L60 + def get_msgid_domain(self): + try: + # Parse out the address from the From line, and then the domain from that + from_email = parseaddr(self.settings["mail_from"])[1] + msgid_domain = from_email.partition('@')[2].strip() + # This can sometimes sneak through parseaddr if the input is malformed + msgid_domain = msgid_domain.rstrip('>').strip() + except Exception: + msgid_domain = '' + return msgid_domain or 'calibre-web.com' + def prepare_message(self): - message = MIMEMultipart() - message['to'] = self.recipent - message['from'] = self.settings["mail_from"] - message['subject'] = self.subject - message['Message-Id'] = make_msgid('calibre-web') + message = EmailMessage() + # message = MIMEMultipart() + message['From'] = self.settings["mail_from"] + message['To'] = self.recipient + message['Subject'] = self.subject message['Date'] = formatdate(localtime=True) - text = self.text - msg = MIMEText(text.encode('UTF-8'), 'plain', 'UTF-8') - message.attach(msg) + message['Message-Id'] = "{}@{}".format(uuid.uuid4(), self.get_msgid_domain()) # f"<{uuid.uuid4()}@{get_msgid_domain(from_)}>" # make_msgid('calibre-web') + message.set_content(self.text.encode('UTF-8'), "text", "plain") if self.attachment: - result = self._get_attachment(self.filepath, self.attachment) - if result: - message.attach(result) + data = self._get_attachment(self.filepath, self.attachment) + if data: + # Set mimetype + content_type, encoding = mimetypes.guess_type(self.attachment) + if content_type is None or encoding is not None: + content_type = 'application/octet-stream' + main_type, sub_type = content_type.split('/', 1) + message.add_attachment(data, maintype=main_type, subtype=sub_type, filename=self.attachment) else: self._handleError(u"Attachment not found") return @@ -158,10 +166,10 @@ class TaskEmail(CalibreTask): else: self.send_gmail_email(msg) except MemoryError as e: - log.debug_or_exception(e, stacklevel=3) + log.error_or_exception(e, stacklevel=3) self._handleError(u'MemoryError sending e-mail: {}'.format(str(e))) except (smtplib.SMTPException, smtplib.SMTPAuthenticationError) as e: - log.debug_or_exception(e, stacklevel=3) + log.error_or_exception(e, stacklevel=3) if hasattr(e, "smtp_error"): text = e.smtp_error.decode('utf-8').replace("\n", '. ') elif hasattr(e, "message"): @@ -172,10 +180,10 @@ class TaskEmail(CalibreTask): text = '' self._handleError(u'Smtplib Error sending e-mail: {}'.format(text)) except (socket.error) as e: - log.debug_or_exception(e, stacklevel=3) + log.error_or_exception(e, stacklevel=3) self._handleError(u'Socket Error sending e-mail: {}'.format(e.strerror)) except Exception as ex: - log.debug_or_exception(ex, stacklevel=3) + log.error_or_exception(ex, stacklevel=3) self._handleError(u'Error sending e-mail: {}'.format(ex)) def send_standard_email(self, msg): @@ -203,7 +211,7 @@ class TaskEmail(CalibreTask): gen = Generator(fp, mangle_from_=False) gen.flatten(msg) - self.asyncSMTP.sendmail(self.settings["mail_from"], self.recipent, fp.getvalue()) + self.asyncSMTP.sendmail(self.settings["mail_from"], self.recipient, fp.getvalue()) self.asyncSMTP.quit() self._handleSuccess() log.debug("E-mail send successfully") @@ -226,15 +234,15 @@ class TaskEmail(CalibreTask): self._progress = x @classmethod - def _get_attachment(cls, bookpath, filename): + def _get_attachment(cls, book_path, filename): """Get file as MIMEBase message""" calibre_path = config.config_calibre_dir if config.config_use_google_drive: - df = gdriveutils.getFileFromEbooksFolder(bookpath, filename) + df = gdriveutils.getFileFromEbooksFolder(book_path, filename) if df: - datafile = os.path.join(calibre_path, bookpath, filename) - if not os.path.exists(os.path.join(calibre_path, bookpath)): - os.makedirs(os.path.join(calibre_path, bookpath)) + datafile = os.path.join(calibre_path, book_path, filename) + if not os.path.exists(os.path.join(calibre_path, book_path)): + os.makedirs(os.path.join(calibre_path, book_path)) df.GetContentFile(datafile) else: return None @@ -244,27 +252,22 @@ class TaskEmail(CalibreTask): os.remove(datafile) else: try: - file_ = open(os.path.join(calibre_path, bookpath, filename), 'rb') + file_ = open(os.path.join(calibre_path, book_path, filename), 'rb') data = file_.read() file_.close() except IOError as e: - log.debug_or_exception(e, stacklevel=3) + log.error_or_exception(e, stacklevel=3) log.error(u'The requested file could not be read. Maybe wrong permissions?') return None - # Set mimetype - content_type, encoding = mimetypes.guess_type(filename) - if content_type is None or encoding is not None: - content_type = 'application/octet-stream' - main_type, sub_type = content_type.split('/', 1) - attachment = MIMEBase(main_type, sub_type) - attachment.set_payload(data) - encoders.encode_base64(attachment) - attachment.add_header('Content-Disposition', 'attachment', filename=filename) - return attachment + return data @property def name(self): - return "E-mail" + return N_("E-mail") + + @property + def is_cancellable(self): + return False def __str__(self): return "E-mail {}, {}".format(self.name, self.subject) diff --git a/cps/tasks/thumbnail.py b/cps/tasks/thumbnail.py new file mode 100644 index 00000000..dcfd4226 --- /dev/null +++ b/cps/tasks/thumbnail.py @@ -0,0 +1,514 @@ +# -*- coding: utf-8 -*- + +# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) +# Copyright (C) 2020 monkey +# +# 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 . + +import os +from urllib.request import urlopen + +from .. import constants +from cps import config, db, fs, gdriveutils, logger, ub +from cps.services.worker import CalibreTask, STAT_CANCELLED, STAT_ENDED +from datetime import datetime +from sqlalchemy import func, text, or_ +from flask_babel import lazy_gettext as N_ + +try: + from wand.image import Image + use_IM = True +except (ImportError, RuntimeError) as e: + use_IM = False + + +def get_resize_height(resolution): + return int(225 * resolution) + + +def get_resize_width(resolution, original_width, original_height): + height = get_resize_height(resolution) + percent = (height / float(original_height)) + width = int((float(original_width) * float(percent))) + return width if width % 2 == 0 else width + 1 + + +def get_best_fit(width, height, image_width, image_height): + resize_width = int(width / 2.0) + resize_height = int(height / 2.0) + aspect_ratio = image_width / image_height + + # If this image's aspect ratio is different from the first image, then resize this image + # to fill the width and height of the first image + if aspect_ratio < width / height: + resize_width = int(width / 2.0) + resize_height = image_height * int(width / 2.0) / image_width + + elif aspect_ratio > width / height: + resize_width = image_width * int(height / 2.0) / image_height + resize_height = int(height / 2.0) + + return {'width': resize_width, 'height': resize_height} + + +class TaskGenerateCoverThumbnails(CalibreTask): + def __init__(self, book_id=-1, task_message=''): + super(TaskGenerateCoverThumbnails, self).__init__(task_message) + self.log = logger.create() + self.book_id = book_id + self.app_db_session = ub.get_new_session_instance() + self.calibre_db = db.CalibreDB(expire_on_commit=False) + self.cache = fs.FileSystem() + self.resolutions = [ + constants.COVER_THUMBNAIL_SMALL, + constants.COVER_THUMBNAIL_MEDIUM + ] + + def run(self, worker_thread): + if self.calibre_db.session and use_IM and self.stat != STAT_CANCELLED and self.stat != STAT_ENDED: + self.message = 'Scanning Books' + books_with_covers = self.get_books_with_covers(self.book_id) + count = len(books_with_covers) + + total_generated = 0 + for i, book in enumerate(books_with_covers): + + # Generate new thumbnails for missing covers + generated = self.create_book_cover_thumbnails(book) + + # Increment the progress + self.progress = (1.0 / count) * i + + if generated > 0: + total_generated += generated + self.message = N_(u'Generated %(count)s cover thumbnails', count=total_generated) + + # Check if job has been cancelled or ended + if self.stat == STAT_CANCELLED: + self.log.info(f'GenerateCoverThumbnails task has been cancelled.') + return + + if self.stat == STAT_ENDED: + self.log.info(f'GenerateCoverThumbnails task has been ended.') + return + + if total_generated == 0: + self.self_cleanup = True + + self._handleSuccess() + self.app_db_session.remove() + + def get_books_with_covers(self, book_id=-1): + filter_exp = (db.Books.id == book_id) if book_id != -1 else True + return self.calibre_db.session \ + .query(db.Books) \ + .filter(db.Books.has_cover == 1) \ + .filter(filter_exp) \ + .all() + + def get_book_cover_thumbnails(self, book_id): + return self.app_db_session \ + .query(ub.Thumbnail) \ + .filter(ub.Thumbnail.type == constants.THUMBNAIL_TYPE_COVER) \ + .filter(ub.Thumbnail.entity_id == book_id) \ + .filter(or_(ub.Thumbnail.expiration.is_(None), ub.Thumbnail.expiration > datetime.utcnow())) \ + .all() + + def create_book_cover_thumbnails(self, book): + generated = 0 + book_cover_thumbnails = self.get_book_cover_thumbnails(book.id) + + # Generate new thumbnails for missing covers + resolutions = list(map(lambda t: t.resolution, book_cover_thumbnails)) + missing_resolutions = list(set(self.resolutions).difference(resolutions)) + for resolution in missing_resolutions: + generated += 1 + self.create_book_cover_single_thumbnail(book, resolution) + + # Replace outdated or missing thumbnails + for thumbnail in book_cover_thumbnails: + if book.last_modified > thumbnail.generated_at: + generated += 1 + self.update_book_cover_thumbnail(book, thumbnail) + + elif not self.cache.get_cache_file_exists(thumbnail.filename, constants.CACHE_TYPE_THUMBNAILS): + generated += 1 + self.update_book_cover_thumbnail(book, thumbnail) + return generated + + def create_book_cover_single_thumbnail(self, book, resolution): + thumbnail = ub.Thumbnail() + thumbnail.type = constants.THUMBNAIL_TYPE_COVER + thumbnail.entity_id = book.id + thumbnail.format = 'jpeg' + thumbnail.resolution = resolution + + self.app_db_session.add(thumbnail) + try: + self.app_db_session.commit() + self.generate_book_thumbnail(book, thumbnail) + except Exception as ex: + self.log.info('Error creating book thumbnail: ' + str(ex)) + self._handleError('Error creating book thumbnail: ' + str(ex)) + self.app_db_session.rollback() + + def update_book_cover_thumbnail(self, book, thumbnail): + thumbnail.generated_at = datetime.utcnow() + + try: + self.app_db_session.commit() + self.cache.delete_cache_file(thumbnail.filename, constants.CACHE_TYPE_THUMBNAILS) + self.generate_book_thumbnail(book, thumbnail) + except Exception as ex: + self.log.info('Error updating book thumbnail: ' + str(ex)) + self._handleError('Error updating book thumbnail: ' + str(ex)) + self.app_db_session.rollback() + + def generate_book_thumbnail(self, book, thumbnail): + if book and thumbnail: + if config.config_use_google_drive: + if not gdriveutils.is_gdrive_ready(): + raise Exception('Google Drive is configured but not ready') + + web_content_link = gdriveutils.get_cover_via_gdrive(book.path) + if not web_content_link: + raise Exception('Google Drive cover url not found') + + stream = None + try: + stream = urlopen(web_content_link) + with Image(file=stream) as img: + height = get_resize_height(thumbnail.resolution) + if img.height > height: + width = get_resize_width(thumbnail.resolution, img.width, img.height) + img.resize(width=width, height=height, filter='lanczos') + img.format = thumbnail.format + filename = self.cache.get_cache_file_path(thumbnail.filename, + constants.CACHE_TYPE_THUMBNAILS) + img.save(filename=filename) + except Exception as ex: + # Bubble exception to calling function + self.log.info('Error generating thumbnail file: ' + str(ex)) + raise ex + finally: + if stream is not None: + stream.close() + else: + book_cover_filepath = os.path.join(config.config_calibre_dir, book.path, 'cover.jpg') + if not os.path.isfile(book_cover_filepath): + raise Exception('Book cover file not found') + + with Image(filename=book_cover_filepath) as img: + height = get_resize_height(thumbnail.resolution) + if img.height > height: + width = get_resize_width(thumbnail.resolution, img.width, img.height) + img.resize(width=width, height=height, filter='lanczos') + img.format = thumbnail.format + filename = self.cache.get_cache_file_path(thumbnail.filename, constants.CACHE_TYPE_THUMBNAILS) + img.save(filename=filename) + + @property + def name(self): + return N_('Cover Thumbnails') + + def __str__(self): + if self.book_id > 0: + return "Add Cover Thumbnails for Book {}".format(self.book_id) + else: + return "Generate Cover Thumbnails" + + @property + def is_cancellable(self): + return True + + +class TaskGenerateSeriesThumbnails(CalibreTask): + def __init__(self, task_message=''): + super(TaskGenerateSeriesThumbnails, self).__init__(task_message) + self.log = logger.create() + self.app_db_session = ub.get_new_session_instance() + self.calibre_db = db.CalibreDB(expire_on_commit=False) + self.cache = fs.FileSystem() + self.resolutions = [ + constants.COVER_THUMBNAIL_SMALL, + constants.COVER_THUMBNAIL_MEDIUM, + ] + + def run(self, worker_thread): + if self.calibre_db.session and use_IM and self.stat != STAT_CANCELLED and self.stat != STAT_ENDED: + self.message = 'Scanning Series' + all_series = self.get_series_with_four_plus_books() + count = len(all_series) + + total_generated = 0 + for i, series in enumerate(all_series): + generated = 0 + series_thumbnails = self.get_series_thumbnails(series.id) + series_books = self.get_series_books(series.id) + + # Generate new thumbnails for missing covers + resolutions = list(map(lambda t: t.resolution, series_thumbnails)) + missing_resolutions = list(set(self.resolutions).difference(resolutions)) + for resolution in missing_resolutions: + generated += 1 + self.create_series_thumbnail(series, series_books, resolution) + + # Replace outdated or missing thumbnails + for thumbnail in series_thumbnails: + if any(book.last_modified > thumbnail.generated_at for book in series_books): + generated += 1 + self.update_series_thumbnail(series_books, thumbnail) + + elif not self.cache.get_cache_file_exists(thumbnail.filename, constants.CACHE_TYPE_THUMBNAILS): + generated += 1 + self.update_series_thumbnail(series_books, thumbnail) + + # Increment the progress + self.progress = (1.0 / count) * i + + if generated > 0: + total_generated += generated + self.message = N_('Generated {0} series thumbnails').format(total_generated) + + # Check if job has been cancelled or ended + if self.stat == STAT_CANCELLED: + self.log.info(f'GenerateSeriesThumbnails task has been cancelled.') + return + + if self.stat == STAT_ENDED: + self.log.info(f'GenerateSeriesThumbnails task has been ended.') + return + + if total_generated == 0: + self.self_cleanup = True + + self._handleSuccess() + self.app_db_session.remove() + + def get_series_with_four_plus_books(self): + return self.calibre_db.session \ + .query(db.Series) \ + .join(db.books_series_link) \ + .join(db.Books) \ + .filter(db.Books.has_cover == 1) \ + .group_by(text('books_series_link.series')) \ + .having(func.count('book_series_link') > 3) \ + .all() + + def get_series_books(self, series_id): + return self.calibre_db.session \ + .query(db.Books) \ + .join(db.books_series_link) \ + .join(db.Series) \ + .filter(db.Books.has_cover == 1) \ + .filter(db.Series.id == series_id) \ + .all() + + def get_series_thumbnails(self, series_id): + return self.app_db_session \ + .query(ub.Thumbnail) \ + .filter(ub.Thumbnail.type == constants.THUMBNAIL_TYPE_SERIES) \ + .filter(ub.Thumbnail.entity_id == series_id) \ + .filter(or_(ub.Thumbnail.expiration.is_(None), ub.Thumbnail.expiration > datetime.utcnow())) \ + .all() + + def create_series_thumbnail(self, series, series_books, resolution): + thumbnail = ub.Thumbnail() + thumbnail.type = constants.THUMBNAIL_TYPE_SERIES + thumbnail.entity_id = series.id + thumbnail.format = 'jpeg' + thumbnail.resolution = resolution + + self.app_db_session.add(thumbnail) + try: + self.app_db_session.commit() + self.generate_series_thumbnail(series_books, thumbnail) + except Exception as ex: + self.log.info('Error creating book thumbnail: ' + str(ex)) + self._handleError('Error creating book thumbnail: ' + str(ex)) + self.app_db_session.rollback() + + def update_series_thumbnail(self, series_books, thumbnail): + thumbnail.generated_at = datetime.utcnow() + + try: + self.app_db_session.commit() + self.cache.delete_cache_file(thumbnail.filename, constants.CACHE_TYPE_THUMBNAILS) + self.generate_series_thumbnail(series_books, thumbnail) + except Exception as ex: + self.log.info('Error updating book thumbnail: ' + str(ex)) + self._handleError('Error updating book thumbnail: ' + str(ex)) + self.app_db_session.rollback() + + def generate_series_thumbnail(self, series_books, thumbnail): + # Get the last four books in the series based on series_index + books = sorted(series_books, key=lambda b: float(b.series_index), reverse=True)[:4] + + top = 0 + left = 0 + width = 0 + height = 0 + with Image() as canvas: + for book in books: + if config.config_use_google_drive: + if not gdriveutils.is_gdrive_ready(): + raise Exception('Google Drive is configured but not ready') + + web_content_link = gdriveutils.get_cover_via_gdrive(book.path) + if not web_content_link: + raise Exception('Google Drive cover url not found') + + stream = None + try: + stream = urlopen(web_content_link) + with Image(file=stream) as img: + # Use the first image in this set to determine the width and height to scale the + # other images in this set + if width == 0 or height == 0: + width = get_resize_width(thumbnail.resolution, img.width, img.height) + height = get_resize_height(thumbnail.resolution) + canvas.blank(width, height) + + dimensions = get_best_fit(width, height, img.width, img.height) + + # resize and crop the image + img.resize(width=int(dimensions['width']), height=int(dimensions['height']), + filter='lanczos') + img.crop(width=int(width / 2.0), height=int(height / 2.0), gravity='center') + + # add the image to the canvas + canvas.composite(img, left, top) + + except Exception as ex: + self.log.info('Error generating thumbnail file: ' + str(ex)) + raise ex + finally: + if stream is not None: + stream.close() + + book_cover_filepath = os.path.join(config.config_calibre_dir, book.path, 'cover.jpg') + if not os.path.isfile(book_cover_filepath): + raise Exception('Book cover file not found') + + with Image(filename=book_cover_filepath) as img: + # Use the first image in this set to determine the width and height to scale the + # other images in this set + if width == 0 or height == 0: + width = get_resize_width(thumbnail.resolution, img.width, img.height) + height = get_resize_height(thumbnail.resolution) + canvas.blank(width, height) + + dimensions = get_best_fit(width, height, img.width, img.height) + + # resize and crop the image + img.resize(width=int(dimensions['width']), height=int(dimensions['height']), filter='lanczos') + img.crop(width=int(width / 2.0), height=int(height / 2.0), gravity='center') + + # add the image to the canvas + canvas.composite(img, left, top) + + # set the coordinates for the next iteration + if left == 0 and top == 0: + left = int(width / 2.0) + elif left == int(width / 2.0) and top == 0: + left = 0 + top = int(height / 2.0) + else: + left = int(width / 2.0) + + canvas.format = thumbnail.format + filename = self.cache.get_cache_file_path(thumbnail.filename, constants.CACHE_TYPE_THUMBNAILS) + canvas.save(filename=filename) + + @property + def name(self): + return N_('Cover Thumbnails') + + def __str__(self): + return "GenerateSeriesThumbnails" + + @property + def is_cancellable(self): + return True + + +class TaskClearCoverThumbnailCache(CalibreTask): + def __init__(self, book_id, task_message=N_('Clearing cover thumbnail cache')): + super(TaskClearCoverThumbnailCache, self).__init__(task_message) + self.log = logger.create() + self.book_id = book_id + self.calibre_db = db.CalibreDB(expire_on_commit=False) + self.app_db_session = ub.get_new_session_instance() + self.cache = fs.FileSystem() + + def run(self, worker_thread): + if self.app_db_session: + if self.book_id == 0: # delete superfluous thumbnails + thumbnails = (self.calibre_db.session.query(ub.Thumbnail) + .join(db.Books, ub.Thumbnail.entity_id == db.Books.id, isouter=True) + .filter(db.Books.id == None) + .all()) + elif self.book_id > 0: # make sure single book is selected + thumbnails = self.get_thumbnails_for_book(self.book_id) + if self.book_id < 0: + self.delete_all_thumbnails() + else: + for thumbnail in thumbnails: + self.delete_thumbnail(thumbnail) + self._handleSuccess() + self.app_db_session.remove() + + def get_thumbnails_for_book(self, book_id): + return self.app_db_session \ + .query(ub.Thumbnail) \ + .filter(ub.Thumbnail.type == constants.THUMBNAIL_TYPE_COVER) \ + .filter(ub.Thumbnail.entity_id == book_id) \ + .all() + + def delete_thumbnail(self, thumbnail): + try: + self.cache.delete_cache_file(thumbnail.filename, constants.CACHE_TYPE_THUMBNAILS) + self.app_db_session \ + .query(ub.Thumbnail) \ + .filter(ub.Thumbnail.type == constants.THUMBNAIL_TYPE_COVER) \ + .filter(ub.Thumbnail.entity_id == thumbnail.entity_id) \ + .delete() + self.app_db_session.commit() + except Exception as ex: + self.log.info('Error deleting book thumbnail: ' + str(ex)) + self._handleError('Error deleting book thumbnail: ' + str(ex)) + + def delete_all_thumbnails(self): + try: + self.app_db_session.query(ub.Thumbnail).filter(ub.Thumbnail.type == constants.THUMBNAIL_TYPE_COVER).delete() + self.app_db_session.commit() + self.cache.delete_cache_dir(constants.CACHE_TYPE_THUMBNAILS) + except Exception as ex: + self.log.info('Error deleting thumbnail directory: ' + str(ex)) + self._handleError('Error deleting thumbnail directory: ' + str(ex)) + + @property + def name(self): + return N_('Cover Thumbnails') + + # needed for logging + def __str__(self): + if self.book_id > 0: + return "Replace/Delete Cover Thumbnails for book " + str(self.book_id) + else: + return "Delete Thumbnail cache directory" + + @property + def is_cancellable(self): + return False diff --git a/cps/tasks/upload.py b/cps/tasks/upload.py index e0bb0094..bc8ba1e0 100644 --- a/cps/tasks/upload.py +++ b/cps/tasks/upload.py @@ -17,11 +17,14 @@ # along with this program. If not, see . from datetime import datetime + +from flask_babel import lazy_gettext as N_ + from cps.services.worker import CalibreTask, STAT_FINISH_SUCCESS class TaskUpload(CalibreTask): - def __init__(self, taskMessage, book_title): - super(TaskUpload, self).__init__(taskMessage) + def __init__(self, task_message, book_title): + super(TaskUpload, self).__init__(task_message) self.start_time = self.end_time = datetime.now() self.stat = STAT_FINISH_SUCCESS self.progress = 1 @@ -32,7 +35,11 @@ class TaskUpload(CalibreTask): @property def name(self): - return "Upload" + return N_("Upload") def __str__(self): return "Upload {}".format(self.book_title) + + @property + def is_cancellable(self): + return False diff --git a/cps/templates/admin.html b/cps/templates/admin.html index 6cd7815e..8a20b73e 100644 --- a/cps/templates/admin.html +++ b/cps/templates/admin.html @@ -47,7 +47,9 @@ {% endfor %} {% endif %} - {{_('Edit Users')}} + {% if not simple %} + {{_('Edit Users')}} + {% endif %} {{_('Add New User')}} {% if (config.config_login_type == 1) %}
      {{_('Import LDAP Users')}}
      @@ -159,16 +161,51 @@ {{_('Edit UI Configuration')}} +{% if feature_support['scheduler'] %} +
      +
      +

      {{_('Scheduled Tasks')}}

      +
      +
      +
      {{_('Time at which tasks start to run')}}
      +
      {{schedule_time}}
      +
      +
      +
      {{_('Maximum tasks duration')}}
      +
      {{schedule_duration}}
      +
      +
      +
      {{_('Generate book cover thumbnails')}}
      +
      {{ display_bool_setting(config.schedule_generate_book_covers) }}
      +
      + +
      +
      {{_('Reconnect to Calibre Library')}}
      +
      {{ display_bool_setting(config.schedule_reconnect) }}
      +
      -
      -

      {{_('Administration')}}

      - {{_('Download Debug Package')}} - {{_('View Logs')}} +
      + {{_('Edit Scheduled Tasks Settings')}} + {% if config.schedule_generate_book_covers %} + {{_('Refresh Thumbnail Cover Cache')}} + {% endif %}
      -
      -
      {{_('Reconnect Calibre Database')}}
      -
      {{_('Restart')}}
      -
      {{_('Shutdown')}}
      +
      +{% endif %} +
      +

      {{_('Administration')}}

      + {{_('Download Debug Package')}} + {{_('View Logs')}} +
      +
      +
      {{_('Reconnect Calibre Database')}}
      +
      +
      +
      {{_('Restart')}}
      +
      {{_('Shutdown')}}
      @@ -250,3 +287,6 @@
      {% endblock %} +{% block modal %} +{{ change_confirm_modal() }} +{% endblock %} diff --git a/cps/templates/author.html b/cps/templates/author.html index d832ad5c..b991e959 100644 --- a/cps/templates/author.html +++ b/cps/templates/author.html @@ -31,28 +31,27 @@
      - {% if entries[0] %} {% for entry in entries %}
      - -

      {{entry.title|shortentitle}}

      +
      +

      {{entry.Books.title|shortentitle}}

      - {% for author in entry.authors %} + {% for author in entry.Books.authors %} {% if loop.index > g.config_authors_max and g.config_authors_max != 0 %} {% if not loop.first %} & {% endif %} - {{author.name.replace('|',',')|shortentitle(30)}} + {{author.name.replace('|',',')|shortentitle(30)}} {% if loop.last %} (...) {% endif %} @@ -60,26 +59,26 @@ {% if not loop.first %} & {% endif %} - {{author.name.replace('|',',')|shortentitle(30)}} + {{author.name.replace('|',',')|shortentitle(30)}} {% endif %} {% endfor %} - {% for format in entry.data %} + {% for format in entry.Books.data %} {% if format.format|lower in g.constants.EXTENSIONS_AUDIO %} {% endif %} {% endfor %}

      - {% if entry.series.__len__() > 0 %} + {% if entry.Books.series.__len__() > 0 %}

      - - {{entry.series[0].name}} + + {{entry.Books.series[0].name}} - ({{entry.series_index|formatseriesindex}}) + ({{entry.Books.series_index|formatseriesindex}})

      {% endif %} - {% if entry.ratings.__len__() > 0 %} + {% if entry.Books.ratings.__len__() > 0 %}
      - {% for number in range((entry.ratings[0].rating/2)|int(2)) %} + {% for number in range((entry.Books.ratings[0].rating/2)|int(2)) %} {% if loop.last and loop.index < 5 %} {% for numer in range(5 - loop.index) %} @@ -92,7 +91,6 @@
      {% endfor %} - {% endif %}
      @@ -123,7 +121,7 @@

      {% if entry.series.__len__() > 0 %}

      - + {{entry.series[0].name}} ({{entry.series_index|formatseriesindex}}) diff --git a/cps/templates/book_edit.html b/cps/templates/book_edit.html index 57470858..3ce1dbfa 100644 --- a/cps/templates/book_edit.html +++ b/cps/templates/book_edit.html @@ -3,7 +3,8 @@ {% if book %}

      - {{ book.title }} + +
      {% if g.user.role_delete_books() %}
      @@ -22,7 +23,7 @@ {% if source_formats|length > 0 and conversion_formats|length > 0 %}

      {{_('Convert book format:')}}

      -
      +
      @@ -48,7 +49,7 @@ {% endif %}
      - +
      diff --git a/cps/templates/book_exists_flash.html b/cps/templates/book_exists_flash.html index b0855120..b55192ce 100644 --- a/cps/templates/book_exists_flash.html +++ b/cps/templates/book_exists_flash.html @@ -1,3 +1,3 @@ - + {{entry.title|shortentitle}} - \ No newline at end of file + diff --git a/cps/templates/book_table.html b/cps/templates/book_table.html index 4b379b37..9ba173bb 100644 --- a/cps/templates/book_table.html +++ b/cps/templates/book_table.html @@ -6,7 +6,7 @@ data-escape="true" {% if g.user.role_edit() %} data-editable-type="text" - data-editable-url="{{ url_for('editbook.edit_list_book', param=parameter)}}" + data-editable-url="{{ url_for('edit-book.edit_list_book', param=parameter)}}" data-editable-title="{{ edit_text }}" data-edit="true" {% if validate %}data-edit-validate="{{ _('This Field is Required') }}" {% endif %} @@ -66,30 +66,30 @@ {{ text_table_row('authors', _('Enter Authors'),_('Authors'), true, true) }} {{ text_table_row('tags', _('Enter Categories'),_('Categories'), false, true) }} {{ text_table_row('series', _('Enter Series'),_('Series'), false, true) }} - {{_('Series Index')}} + {{_('Series Index')}} {{ text_table_row('languages', _('Enter Languages'),_('Languages'), false, true) }} {{ text_table_row('publishers', _('Enter Publishers'),_('Publishers'), false, true) }} - {{_('Comments')}} + {{_('Comments')}} {% if g.user.check_visibility(32768) %} {{ book_checkbox_row('is_archived', _('Archiv Status'), false)}} {% endif %} {{ book_checkbox_row('read_status', _('Read Status'), false)}} {% for c in cc %} {% if c.datatype == "int" %} - {{c.name}} + {{c.name}} {% elif c.datatype == "rating" %} - {{c.name}} + {{c.name}} {% elif c.datatype == "float" %} - {{c.name}} + {{c.name}} {% elif c.datatype == "enumeration" %} - {{c.name}} + {{c.name}} {% elif c.datatype in ["datetime"] %} {% elif c.datatype == "text" %} {{ text_table_row('custom_column_' + c.id|string, _('Enter ') + c.name, c.name, false, false) }} {% elif c.datatype == "comments" %} - {{c.name}} + {{c.name}} {% elif c.datatype == "bool" %} {{ book_checkbox_row('custom_column_' + c.id|string, c.name, false)}} {% else %} diff --git a/cps/templates/config_view_edit.html b/cps/templates/config_view_edit.html index 1dc02a5e..e4fea44d 100644 --- a/cps/templates/config_view_edit.html +++ b/cps/templates/config_view_edit.html @@ -162,8 +162,10 @@
      + {% if not simple %} {{_('Add Allowed/Denied Tags')}} {{_('Add Allowed/Denied custom column values')}} + {% endif %}
      diff --git a/cps/templates/detail.html b/cps/templates/detail.html index 06357ce8..5d7c846e 100644 --- a/cps/templates/detail.html +++ b/cps/templates/detail.html @@ -4,7 +4,8 @@
      - {{ entry.title }} + +
      @@ -99,7 +100,7 @@

      {{entry.title}}

      - {% for author in entry.authors %} + {% for author in entry.ordered_authors %} {{author.name.replace('|',',')}} {% if not loop.last %} & @@ -138,7 +139,7 @@

      {% for identifier in entry.identifiers %} - {{identifier.formatType()}} + {{identifier.format_type()}} {%endfor%}

      @@ -295,7 +296,7 @@ {% if g.user.role_edit() %} {% endif %} diff --git a/cps/templates/discover.html b/cps/templates/discover.html deleted file mode 100644 index 74448b98..00000000 --- a/cps/templates/discover.html +++ /dev/null @@ -1,65 +0,0 @@ -{% extends "layout.html" %} -{% block body %} -
      -

      {{title}}

      -
      - {% for entry in entries %} -
      -
      - {% if entry.has_cover is defined %} - - - {{ entry.title }} - {% if entry.id in read_book_ids %}{% endif %} - - - {% endif %} -
      -
      - -

      {{entry.title|shortentitle}}

      -
      -

      - {% for author in entry.authors %} - {% if loop.index > g.config_authors_max and g.config_authors_max != 0 %} - {% if not loop.first %} - & - {% endif %} - {{author.name.replace('|',',')|shortentitle(30)}} - {% if loop.last %} - (...) - {% endif %} - {% else %} - {% if not loop.first %} - & - {% endif %} - {{author.name.replace('|',',')|shortentitle(30)}} - {% endif %} - {% endfor %} -

      - {% if entry.series.__len__() > 0 %} -

      - - {{entry.series[0].name}} - - ({{entry.series_index|formatseriesindex}}) -

      - {% endif %} - {% if entry.ratings.__len__() > 0 %} -
      - {% for number in range((entry.ratings[0].rating/2)|int(2)) %} - - {% if loop.last and loop.index < 5 %} - {% for numer in range(5 - loop.index) %} - - {% endfor %} - {% endif %} - {% endfor %} -
      - {% endif %} -
      -
      - {% endfor %} -
      -
      -{% endblock %} diff --git a/cps/templates/email_edit.html b/cps/templates/email_edit.html index 9f23f78b..2a844209 100644 --- a/cps/templates/email_edit.html +++ b/cps/templates/email_edit.html @@ -69,7 +69,7 @@ {% endif %} {{_('Back')}} - {% if g.allow_registration %} + {% if g.allow_registration and not simple%}

      {{_('Allowed Domains (Whitelist)')}}

      diff --git a/cps/templates/feed.xml b/cps/templates/feed.xml index 9073142e..940fb0da 100644 --- a/cps/templates/feed.xml +++ b/cps/templates/feed.xml @@ -40,35 +40,35 @@ {% if entries and entries[0] %} {% for entry in entries %} - {{entry.title}} - urn:uuid:{{entry.uuid}} - {{entry.atom_timestamp}} - {% if entry.authors.__len__() > 0 %} + {{entry.Books.title}} + urn:uuid:{{entry.Books.uuid}} + {{entry.Books.atom_timestamp}} + {% if entry.Books.authors.__len__() > 0 %} - {{entry.authors[0].name}} + {{entry.Books.authors[0].name}} {% endif %} - {% if entry.publishers.__len__() > 0 %} + {% if entry.Books.publishers.__len__() > 0 %} - {{entry.publishers[0].name}} + {{entry.Books.publishers[0].name}} {% endif %} - {% for lang in entry.languages %} + {% for lang in entry.Books.languages %} {{lang.lang_code}} {% endfor %} - {% for tag in entry.tags %} + {% for tag in entry.Books.tags %} {% endfor %} - {% if entry.comments[0] %}{{entry.comments[0].text|striptags}}{% endif %} - {% if entry.has_cover %} - - + {% if entry.Books.comments[0] %}{{entry.Books.comments[0].text|striptags}}{% endif %} + {% if entry.Books.has_cover %} + + {% endif %} - {% for format in entry.data %} - + {% for format in entry.Books.data %} + {% endfor %} {% endfor %} diff --git a/cps/templates/fragment.html b/cps/templates/fragment.html index 1421ea6a..f2e94fb2 100644 --- a/cps/templates/fragment.html +++ b/cps/templates/fragment.html @@ -1,3 +1,4 @@ +{% import 'image.html' as image %}
      {% block body %}{% endblock %}
      diff --git a/cps/templates/grid.html b/cps/templates/grid.html index b9d40961..638b7245 100644 --- a/cps/templates/grid.html +++ b/cps/templates/grid.html @@ -1,3 +1,4 @@ +{% import 'image.html' as image %} {% extends "layout.html" %} {% block body %}

      {{_(title)}}

      @@ -27,7 +28,7 @@
      - {{ entry[0].series[0].name }} + {{ image.series(entry[0].series[0], alt=entry[0].series[0].name|shortentitle) }} {{entry.count}} diff --git a/cps/templates/image.html b/cps/templates/image.html new file mode 100644 index 00000000..0bdba9a5 --- /dev/null +++ b/cps/templates/image.html @@ -0,0 +1,20 @@ +{% macro book_cover(book, alt=None) -%} + {%- set image_title = book.title if book.title else book.name -%} + {%- set image_alt = alt if alt else image_title -%} + {% set srcset = book|get_cover_srcset %} + {{ image_alt }} +{%- endmacro %} + +{% macro series(series, alt=None) -%} + {%- set image_alt = alt if alt else image_title -%} + {% set srcset = series|get_series_srcset %} + {{ book_title }} +{%- endmacro %} diff --git a/cps/templates/index.html b/cps/templates/index.html index 162adc7d..0bb3da72 100644 --- a/cps/templates/index.html +++ b/cps/templates/index.html @@ -1,30 +1,31 @@ +{% import 'image.html' as image %} {% extends "layout.html" %} {% block body %} -{% if g.user.show_detail_random() %} +{% if g.user.show_detail_random() and page != "discover" %}

      {{_('Discover (Random Books)')}}

      {% for entry in random %}
      - -

      {{entry.title|shortentitle}}

      +
      +

      {{entry.Books.title|shortentitle}}

      - {% for author in entry.authors %} + {% for author in entry.Books.authors %} {% if loop.index > g.config_authors_max and g.config_authors_max != 0 %} {% if not loop.first %} & {% endif %} - {{author.name.replace('|',',')|shortentitle(30)}} + {{author.name.replace('|',',')|shortentitle(30)}} {% if loop.last %} (...) {% endif %} @@ -32,21 +33,21 @@ {% if not loop.first %} & {% endif %} - {{author.name.replace('|',',')|shortentitle(30)}} + {{author.name.replace('|',',')|shortentitle(30)}} {% endif %} {% endfor %}

      - {% if entry.series.__len__() > 0 %} + {% if entry.Books.series.__len__() > 0 %}

      - - {{entry.series[0].name}} + + {{entry.Books.series[0].name}} - ({{entry.series_index|formatseriesindex}}) + ({{entry.Books.series_index|formatseriesindex}})

      {% endif %} - {% if entry.ratings.__len__() > 0 %} + {% if entry.Books.ratings.__len__() > 0 %}
      - {% for number in range((entry.ratings[0].rating/2)|int(2)) %} + {% for number in range((entry.Books.ratings[0].rating/2)|int(2)) %} {% if loop.last and loop.index < 5 %} {% for numer in range(5 - loop.index) %} @@ -64,6 +65,7 @@ {% endif %}

      {{title}}

      + {% if page != 'discover' %} - + {% endif %}
      {% if entries[0] %} {% for entry in entries %}
      - -

      {{entry.title|shortentitle}}

      +
      +

      {{entry.Books.title|shortentitle}}

      - {% for author in entry.authors %} + {% for author in entry.Books.authors %} {% if loop.index > g.config_authors_max and g.config_authors_max != 0 %} {% if not loop.first %} & {% endif %} - {{author.name.replace('|',',')|shortentitle(30)}} + {{author.name.replace('|',',')|shortentitle(30)}} {% if loop.last %} (...) {% endif %} @@ -114,26 +116,30 @@ {% if not loop.first %} & {% endif %} - {{author.name.replace('|',',')|shortentitle(30)}} + {{author.name.replace('|',',')|shortentitle(30)}} {% endif %} {% endfor %} - {% for format in entry.data %} + {% for format in entry.Books.data %} {% if format.format|lower in g.constants.EXTENSIONS_AUDIO %} {% endif %} {%endfor%}

      - {% if entry.series.__len__() > 0 %} + {% if entry.Books.series.__len__() > 0 %}

      - - {{entry.series[0].name}} + {% if page != "series" %} + + {{entry.Books.series[0].name}} - ({{entry.series_index|formatseriesindex}}) + {% else %} + {{entry.Books.series[0].name}} + {% endif %} + ({{entry.Books.series_index|formatseriesindex}})

      {% endif %} - {% if entry.ratings.__len__() > 0 %} + {% if entry.Books.ratings.__len__() > 0 %}
      - {% for number in range((entry.ratings[0].rating/2)|int(2)) %} + {% for number in range((entry.Books.ratings[0].rating/2)|int(2)) %} {% if loop.last and loop.index < 5 %} {% for numer in range(5 - loop.index) %} diff --git a/cps/templates/languages.html b/cps/templates/languages.html deleted file mode 100644 index 8331cb94..00000000 --- a/cps/templates/languages.html +++ /dev/null @@ -1,35 +0,0 @@ -{% extends "layout.html" %} -{% block body %} -

      {{title}}

      - -
      -
      - {% for lang in languages %} - {% if loop.index0 == (loop.length/2)|int and loop.length > 20 %} -
      -
      - {% endif %} -
      -
      {{lang[1]}}
      - -
      - {% endfor %} -
      -
      -{% endblock %} -{% block js %} - -{% endblock %} - diff --git a/cps/templates/layout.html b/cps/templates/layout.html index ec69c91b..42012937 100644 --- a/cps/templates/layout.html +++ b/cps/templates/layout.html @@ -1,4 +1,5 @@ {% from 'modal_dialogs.html' import restrict_modal, delete_book, filechooser_modal, delete_confirm_modal, change_confirm_modal %} +{% import 'image.html' as image %} @@ -60,7 +61,7 @@ {% if g.user.is_authenticated or g.allow_anonymous %} {% if g.user.role_upload() and g.allow_upload %}
    • - +
      {{_('Upload')}}
    • {% endif %} - {% if not g.user.is_anonymous %} + {% if not g.user.is_anonymous and not simple%}
    • {% endif %} {% if g.user.role_admin() %} diff --git a/cps/templates/list.html b/cps/templates/list.html index 71dbea11..a9089823 100644 --- a/cps/templates/list.html +++ b/cps/templates/list.html @@ -14,7 +14,7 @@ {% endif %}
      {% for char in charlist%} -
      {{char.char}}
      +
      {{char[0]}}
      {% endfor %}
      @@ -29,8 +29,8 @@
      {% endif %} -
      -
      {{entry.count}}
      +
      +
      {{entry[1]}}
      {% if entry.name %}
      diff --git a/cps/templates/listenmp3.html b/cps/templates/listenmp3.html index 279ec28f..2067bf38 100644 --- a/cps/templates/listenmp3.html +++ b/cps/templates/listenmp3.html @@ -105,7 +105,7 @@ @@ -134,7 +134,7 @@ window.calibre = { filePath: "{{ url_for('static', filename='js/libs/') }}", cssPath: "{{ url_for('static', filename='css/') }}", bookUrl: "{{ url_for('static', filename=mp3file) }}/", - bookmarkUrl: "{{ url_for('web.bookmark', book_id=mp3file, book_format=audioformat.upper()) }}", + bookmarkUrl: "{{ url_for('web.set_bookmark', book_id=mp3file, book_format=audioformat.upper()) }}", bookmark: "{{ bookmark.bookmark_key if bookmark != None }}", useBookmarks: "{{ g.user.is_authenticated | tojson }}" }; diff --git a/cps/templates/read.html b/cps/templates/read.html index 1766eb1b..f69d662f 100644 --- a/cps/templates/read.html +++ b/cps/templates/read.html @@ -86,7 +86,7 @@ window.calibre = { filePath: "{{ url_for('static', filename='js/libs/') }}", cssPath: "{{ url_for('static', filename='css/') }}", - bookmarkUrl: "{{ url_for('web.bookmark', book_id=bookid, book_format='EPUB') }}", + bookmarkUrl: "{{ url_for('web.set_bookmark', book_id=bookid, book_format='EPUB') }}", bookUrl: "{{ url_for('web.serve_book', book_id=bookid, book_format='epub', anyname='file.epub') }}", bookmark: "{{ bookmark.bookmark_key if bookmark != None }}", useBookmarks: "{{ g.user.is_authenticated | tojson }}" diff --git a/cps/templates/schedule_edit.html b/cps/templates/schedule_edit.html new file mode 100644 index 00000000..55658ce7 --- /dev/null +++ b/cps/templates/schedule_edit.html @@ -0,0 +1,44 @@ +{% extends "layout.html" %} +{% block header %} + + +{% endblock %} +{% block body %} +
      +

      {{title}}

      + + +
      + + +
      +
      + + +
      +
      + + +
      + +
      + + +
      + + + {{_('Cancel')}} + +
      +{% endblock %} diff --git a/cps/templates/search.html b/cps/templates/search.html index a7ba5e68..78e30494 100644 --- a/cps/templates/search.html +++ b/cps/templates/search.html @@ -1,3 +1,4 @@ +{% import 'image.html' as image %} {% extends "layout.html" %} {% block body %}
      @@ -43,16 +44,16 @@
      - +

      {{entry.Books.title|shortentitle}}

      @@ -61,7 +62,7 @@ {% if not loop.first %} & {% endif %} - {{author.name.replace('|',',')|shortentitle(30)}} + {{author.name.replace('|',',')|shortentitle(30)}} {% if loop.last %} (...) {% endif %} @@ -69,7 +70,7 @@ {% if not loop.first %} & {% endif %} - {{author.name.replace('|',',')|shortentitle(30)}} + {{author.name.replace('|',',')|shortentitle(30)}} {% endif %} {% endfor %} {% for format in entry.Books.data %} @@ -80,7 +81,7 @@

      {% if entry.Books.series.__len__() > 0 %}

      - + {{entry.Books.series[0].name}} ({{entry.Books.series_index|formatseriesindex}}) diff --git a/cps/templates/shelf.html b/cps/templates/shelf.html index adfead60..b4596f79 100644 --- a/cps/templates/shelf.html +++ b/cps/templates/shelf.html @@ -1,3 +1,4 @@ +{% import 'image.html' as image %} {% extends "layout.html" %} {% block body %}

      @@ -32,24 +33,24 @@ {% for entry in entries %}
      - -

      {{entry.title|shortentitle}}

      +
      +

      {{entry.Books.title|shortentitle}}

      - {% for author in entry.authors %} + {% for author in entry.Books.authors %} {% if loop.index > g.config_authors_max and g.config_authors_max != 0 %} {% if not loop.first %} & {% endif %} - {{author.name.replace('|',',')|shortentitle(30)}} + {{author.name.replace('|',',')|shortentitle(30)}} {% if loop.last %} (...) {% endif %} @@ -57,21 +58,21 @@ {% if not loop.first %} & {% endif %} - {{author.name.replace('|',',')|shortentitle(30)}} + {{author.name.replace('|',',')|shortentitle(30)}} {% endif %} {% endfor %}

      - {% if entry.series.__len__() > 0 %} + {% if entry.Books.series.__len__() > 0 %}

      - - {{entry.series[0].name}} + + {{entry.Books.series[0].name}} - ({{entry.series_index|formatseriesindex}}) + ({{entry.Books.series_index|formatseriesindex}})

      {% endif %} - {% if entry.ratings.__len__() > 0 %} + {% if entry.Books.ratings.__len__() > 0 %}
      - {% for number in range((entry.ratings[0].rating/2)|int(2)) %} + {% for number in range((entry.Books.ratings[0].rating/2)|int(2)) %} {% if loop.last and loop.index < 5 %} {% for numer in range(5 - loop.index) %} diff --git a/cps/templates/shelfdown.html b/cps/templates/shelfdown.html index 1d781310..f1a0b137 100644 --- a/cps/templates/shelfdown.html +++ b/cps/templates/shelfdown.html @@ -35,31 +35,31 @@
      -

      {{entry.title|shortentitle}}

      +

      {{entry.Books.title|shortentitle}}

      - {% for author in entry.authors %} - {{author.name.replace('|',',')}} + {% for author in entry.Books.authors %} + {{author.name.replace('|',',')}} {% if not loop.last %} & {% endif %} {% endfor %}

      - {% if entry.series.__len__() > 0 %} + {% if entry.Books.series.__len__() > 0 %}

      - - {{entry.series[0].name}} + + {{entry.Books.series[0].name}} - ({{entry.series_index}}) + ({{entry.Books.series_index}})

      {% endif %}
      {% if g.user.role_download() %} - {% if entry.data|length %} + {% if entry.Books.data|length %}
      - {% for format in entry.data %} - + {% for format in entry.Books.data %} + {{format.format}} ({{ format.uncompressed_size|filesizeformat }}) {% endfor %} diff --git a/cps/templates/stats.html b/cps/templates/stats.html index 052c920a..62a29308 100644 --- a/cps/templates/stats.html +++ b/cps/templates/stats.html @@ -39,7 +39,7 @@ {% if version %} {{library}} - {{_(version)}} + {{version}} {% endif %} {% endfor %} diff --git a/cps/templates/tasks.html b/cps/templates/tasks.html index 3ef50474..0e5a352b 100644 --- a/cps/templates/tasks.html +++ b/cps/templates/tasks.html @@ -16,6 +16,9 @@ {{_('Progress')}} {{_('Run Time')}} {{_('Start Time')}} + {% if g.user.role_admin() %} + {{_('Actions')}} + {% endif %} @@ -23,6 +26,30 @@
      {% endblock %} +{% block modal %} +{{ delete_book() }} +{% if g.user.role_admin() %} + +{% endif %} +{% endblock %} {% block js %} diff --git a/cps/templates/user_edit.html b/cps/templates/user_edit.html index de7a4fb3..b489cbaf 100644 --- a/cps/templates/user_edit.html +++ b/cps/templates/user_edit.html @@ -83,7 +83,7 @@
      - {% if ( g.user and g.user.role_admin() and not new_user ) %} + {% if ( g.user and g.user.role_admin() and not new_user ) and not simple %} {{_('Add Allowed/Denied Tags')}} {{_('Add allowed/Denied Custom Column Values')}} {% endif %} @@ -131,7 +131,7 @@
      {% endif %} {% endif %} - {% if kobo_support and not content.role_anonymous() %} + {% if kobo_support and not content.role_anonymous() and not simple%}
      diff --git a/cps/tornado_wsgi.py b/cps/tornado_wsgi.py new file mode 100644 index 00000000..af93219c --- /dev/null +++ b/cps/tornado_wsgi.py @@ -0,0 +1,94 @@ +# -*- coding: utf-8 -*- + +# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) +# Copyright (C) 2022 OzzieIsaacs +# +# 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 tornado.wsgi import WSGIContainer +import tornado + +from tornado import escape +from tornado import httputil + +from typing import List, Tuple, Optional, Callable, Any, Dict, Text +from types import TracebackType +import typing + +if typing.TYPE_CHECKING: + from typing import Type # noqa: F401 + from wsgiref.types import WSGIApplication as WSGIAppType # noqa: F4 + +class MyWSGIContainer(WSGIContainer): + + def __call__(self, request: httputil.HTTPServerRequest) -> None: + data = {} # type: Dict[str, Any] + response = [] # type: List[bytes] + + def start_response( + status: str, + headers: List[Tuple[str, str]], + exc_info: Optional[ + Tuple[ + "Optional[Type[BaseException]]", + Optional[BaseException], + Optional[TracebackType], + ] + ] = None, + ) -> Callable[[bytes], Any]: + data["status"] = status + data["headers"] = headers + return response.append + + app_response = self.wsgi_application( + MyWSGIContainer.environ(request), start_response + ) + try: + response.extend(app_response) + body = b"".join(response) + finally: + if hasattr(app_response, "close"): + app_response.close() # type: ignore + if not data: + raise Exception("WSGI app did not call start_response") + + status_code_str, reason = data["status"].split(" ", 1) + status_code = int(status_code_str) + headers = data["headers"] # type: List[Tuple[str, str]] + header_set = set(k.lower() for (k, v) in headers) + body = escape.utf8(body) + if status_code != 304: + if "content-length" not in header_set: + headers.append(("Content-Length", str(len(body)))) + if "content-type" not in header_set: + headers.append(("Content-Type", "text/html; charset=UTF-8")) + if "server" not in header_set: + headers.append(("Server", "TornadoServer/%s" % tornado.version)) + + start_line = httputil.ResponseStartLine("HTTP/1.1", status_code, reason) + header_obj = httputil.HTTPHeaders() + for key, value in headers: + header_obj.add(key, value) + assert request.connection is not None + request.connection.write_headers(start_line, header_obj, chunk=body) + request.connection.finish() + self._log(status_code, request) + + @staticmethod + def environ(request: httputil.HTTPServerRequest) -> Dict[Text, Any]: + environ = WSGIContainer.environ(request) + environ['RAW_URI'] = request.path + return environ + diff --git a/cps/translations/cs/LC_MESSAGES/messages.mo b/cps/translations/cs/LC_MESSAGES/messages.mo index b4984db1..0ae3a98a 100644 Binary files a/cps/translations/cs/LC_MESSAGES/messages.mo and b/cps/translations/cs/LC_MESSAGES/messages.mo differ diff --git a/cps/translations/cs/LC_MESSAGES/messages.po b/cps/translations/cs/LC_MESSAGES/messages.po index 1d6acaba..9066dd54 100644 --- a/cps/translations/cs/LC_MESSAGES/messages.po +++ b/cps/translations/cs/LC_MESSAGES/messages.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: Calibre-Web\n" "Report-Msgid-Bugs-To: https://github.com/janeczku/Calibre-Web\n" -"POT-Creation-Date: 2022-01-15 09:19+0100\n" +"POT-Creation-Date: 2022-04-18 20:01+0200\n" "PO-Revision-Date: 2020-06-09 21:11+0100\n" "Last-Translator: Lukas Heroudek \n" "Language: cs_CZ\n" @@ -15,589 +15,592 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.9.0\n" +"Generated-By: Babel 2.9.1\n" -#: cps/about.py:34 cps/about.py:49 cps/about.py:65 cps/converter.py:31 -msgid "not installed" -msgstr "není nainstalováno" - -#: cps/about.py:47 cps/about.py:63 -msgid "installed" -msgstr "nainstalováno" - -#: cps/about.py:145 +#: cps/about.py:86 msgid "Statistics" msgstr "Statistika" -#: cps/admin.py:144 +#: cps/admin.py:141 msgid "Server restarted, please reload page" msgstr "Server restartován, znovu načtěte stránku" -#: cps/admin.py:146 +#: cps/admin.py:143 msgid "Performing shutdown of server, please close window" msgstr "Vypínám server, zavřete okno" -#: cps/admin.py:154 +#: cps/admin.py:151 msgid "Reconnect successful" msgstr "Úspěšně obnovené připojení" -#: cps/admin.py:157 +#: cps/admin.py:154 msgid "Unknown command" msgstr "Neznámý příkaz" -#: cps/admin.py:167 cps/editbooks.py:707 cps/editbooks.py:721 -#: cps/editbooks.py:866 cps/editbooks.py:868 cps/editbooks.py:895 -#: cps/editbooks.py:911 cps/updater.py:584 cps/uploader.py:93 -#: cps/uploader.py:103 +#: cps/admin.py:176 cps/editbooks.py:713 cps/editbooks.py:892 +#: cps/editbooks.py:894 cps/editbooks.py:930 cps/editbooks.py:947 +#: cps/updater.py:608 cps/uploader.py:93 cps/uploader.py:103 msgid "Unknown" msgstr "Neznámý" -#: cps/admin.py:188 +#: cps/admin.py:197 msgid "Admin page" msgstr "Stránka správce" -#: cps/admin.py:207 +#: cps/admin.py:217 msgid "Basic Configuration" msgstr "Základní konfigurace" -#: cps/admin.py:244 +#: cps/admin.py:255 msgid "UI Configuration" msgstr "Konfigurace uživatelského rozhraní" -#: cps/admin.py:277 cps/templates/admin.html:50 +#: cps/admin.py:289 cps/templates/admin.html:51 #, fuzzy msgid "Edit Users" msgstr "Uživatel admin" -#: cps/admin.py:318 cps/opds.py:109 cps/opds.py:198 cps/opds.py:275 -#: cps/opds.py:327 cps/templates/grid.html:13 cps/templates/languages.html:9 +#: cps/admin.py:333 cps/opds.py:529 cps/templates/grid.html:13 #: cps/templates/list.html:13 msgid "All" msgstr "Vše" -#: cps/admin.py:343 cps/admin.py:1615 +#: cps/admin.py:360 cps/admin.py:1648 msgid "User not found" msgstr "Uživatel nenalezen" -#: cps/admin.py:357 +#: cps/admin.py:374 msgid "{} users deleted successfully" msgstr "" -#: cps/admin.py:379 cps/templates/config_view_edit.html:133 +#: cps/admin.py:397 cps/templates/config_view_edit.html:133 #: cps/templates/user_edit.html:45 cps/templates/user_table.html:81 msgid "Show All" msgstr "Zobrazit vše" -#: cps/admin.py:400 cps/admin.py:406 +#: cps/admin.py:418 cps/admin.py:424 msgid "Malformed request" msgstr "" -#: cps/admin.py:418 cps/admin.py:1493 +#: cps/admin.py:436 cps/admin.py:1526 msgid "Guest Name can't be changed" msgstr "" -#: cps/admin.py:430 +#: cps/admin.py:448 msgid "Guest can't have this role" msgstr "" -#: cps/admin.py:442 cps/admin.py:1451 +#: cps/admin.py:460 cps/admin.py:1484 msgid "No admin user remaining, can't remove admin role" msgstr "Nezbývá žádný správce, nelze odebrat roli správce" -#: cps/admin.py:446 cps/admin.py:460 +#: cps/admin.py:464 cps/admin.py:478 msgid "Value has to be true or false" msgstr "" -#: cps/admin.py:448 +#: cps/admin.py:466 msgid "Invalid role" msgstr "" -#: cps/admin.py:452 +#: cps/admin.py:470 msgid "Guest can't have this view" msgstr "" -#: cps/admin.py:462 +#: cps/admin.py:480 msgid "Invalid view" msgstr "" -#: cps/admin.py:465 +#: cps/admin.py:483 msgid "Guest's Locale is determined automatically and can't be set" msgstr "" -#: cps/admin.py:469 +#: cps/admin.py:487 msgid "No Valid Locale Given" msgstr "" -#: cps/admin.py:480 +#: cps/admin.py:498 msgid "No Valid Book Language Given" msgstr "" -#: cps/admin.py:482 +#: cps/admin.py:500 cps/editbooks.py:1267 msgid "Parameter not found" msgstr "" -#: cps/admin.py:533 +#: cps/admin.py:553 msgid "Invalid Read Column" msgstr "" -#: cps/admin.py:539 +#: cps/admin.py:559 msgid "Invalid Restricted Column" msgstr "" -#: cps/admin.py:560 cps/admin.py:1323 +#: cps/admin.py:579 cps/admin.py:1355 msgid "Calibre-Web configuration updated" msgstr "Konfigurace Calibre-Web aktualizována" -#: cps/admin.py:572 +#: cps/admin.py:591 msgid "Do you really want to delete the Kobo Token?" msgstr "Opravdu chcete odstranit Kobo token?" -#: cps/admin.py:574 +#: cps/admin.py:593 msgid "Do you really want to delete this domain?" msgstr "" -#: cps/admin.py:576 +#: cps/admin.py:595 msgid "Do you really want to delete this user?" msgstr "" -#: cps/admin.py:578 +#: cps/admin.py:597 msgid "Are you sure you want to delete this shelf?" msgstr "Jste si jisti, že chcete odstranit tuto polici?" -#: cps/admin.py:580 +#: cps/admin.py:599 #, fuzzy msgid "Are you sure you want to change locales of selected user(s)?" msgstr "Jste si jisti, že chcete odstranit tuto polici?" -#: cps/admin.py:582 +#: cps/admin.py:601 msgid "Are you sure you want to change visible book languages for selected user(s)?" msgstr "" -#: cps/admin.py:584 +#: cps/admin.py:603 msgid "Are you sure you want to change the selected role for the selected user(s)?" msgstr "" -#: cps/admin.py:586 +#: cps/admin.py:605 #, fuzzy msgid "Are you sure you want to change the selected restrictions for the selected user(s)?" msgstr "Jste si jisti, že chcete odstranit tuto polici?" -#: cps/admin.py:588 +#: cps/admin.py:607 msgid "Are you sure you want to change the selected visibility restrictions for the selected user(s)?" msgstr "" -#: cps/admin.py:590 +#: cps/admin.py:610 #, fuzzy msgid "Are you sure you want to change shelf sync behavior for the selected user(s)?" msgstr "Jste si jisti, že chcete odstranit tuto polici?" -#: cps/admin.py:592 +#: cps/admin.py:612 #, fuzzy msgid "Are you sure you want to change Calibre library location?" msgstr "Opravdu chcete vypnout?" -#: cps/admin.py:594 +#: cps/admin.py:614 msgid "Are you sure you want delete Calibre-Web's sync database to force a full sync with your Kobo Reader?" msgstr "" -#: cps/admin.py:743 +#: cps/admin.py:764 msgid "Tag not found" msgstr "" -#: cps/admin.py:755 +#: cps/admin.py:776 msgid "Invalid Action" msgstr "" -#: cps/admin.py:871 cps/admin.py:877 cps/admin.py:887 cps/admin.py:897 +#: cps/admin.py:893 cps/admin.py:899 cps/admin.py:909 cps/admin.py:919 #: cps/templates/modal_dialogs.html:29 cps/templates/user_table.html:41 #: cps/templates/user_table.html:58 msgid "Deny" msgstr "Zakázat" -#: cps/admin.py:873 cps/admin.py:879 cps/admin.py:889 cps/admin.py:899 +#: cps/admin.py:895 cps/admin.py:901 cps/admin.py:911 cps/admin.py:921 #: cps/templates/modal_dialogs.html:28 cps/templates/user_table.html:44 #: cps/templates/user_table.html:61 msgid "Allow" msgstr "Povolit" -#: cps/admin.py:913 +#: cps/admin.py:936 msgid "{} sync entries deleted" msgstr "" -#: cps/admin.py:1036 +#: cps/admin.py:1059 msgid "client_secrets.json Is Not Configured For Web Application" msgstr "client_secrets.json není nakonfigurováno pro webové aplikace" -#: cps/admin.py:1081 +#: cps/admin.py:1104 msgid "Logfile Location is not Valid, Please Enter Correct Path" msgstr "Umístění zápisového souboru není platné. Určete prosím platnou polohu" -#: cps/admin.py:1087 +#: cps/admin.py:1110 msgid "Access Logfile Location is not Valid, Please Enter Correct Path" msgstr "Umístění zápisového souboru pro přístup není platné. Určete prosím platnou polohu" -#: cps/admin.py:1117 +#: cps/admin.py:1140 msgid "Please Enter a LDAP Provider, Port, DN and User Object Identifier" msgstr "Prosím zadejte LDAP poskytovatele, port, DN a Identifikátor objektu uživatele" -#: cps/admin.py:1123 +#: cps/admin.py:1146 #, fuzzy msgid "Please Enter a LDAP Service Account and Password" msgstr "Zadejte platné uživatelské jméno pro obnovení hesla" -#: cps/admin.py:1126 +#: cps/admin.py:1149 msgid "Please Enter a LDAP Service Account" msgstr "" -#: cps/admin.py:1131 +#: cps/admin.py:1154 #, python-format msgid "LDAP Group Object Filter Needs to Have One \"%s\" Format Identifier" msgstr "Filtr objektů skupiny LDAP musí mít jeden “%s” formátový identifikátor" -#: cps/admin.py:1133 +#: cps/admin.py:1156 msgid "LDAP Group Object Filter Has Unmatched Parenthesis" msgstr "Filtr objektů skupiny LDAP má nesrovnatelnou závorku" -#: cps/admin.py:1137 +#: cps/admin.py:1160 #, python-format msgid "LDAP User Object Filter needs to Have One \"%s\" Format Identifier" msgstr "Filtr uživatelských objektů LDAP musí mít jeden “%s” formátový identifikátor" -#: cps/admin.py:1139 +#: cps/admin.py:1162 msgid "LDAP User Object Filter Has Unmatched Parenthesis" msgstr "Filtr uživatelských objektů LDAP má nesrovnatelnou závorku" -#: cps/admin.py:1146 +#: cps/admin.py:1169 #, python-format msgid "LDAP Member User Filter needs to Have One \"%s\" Format Identifier" msgstr "" -#: cps/admin.py:1148 +#: cps/admin.py:1171 msgid "LDAP Member User Filter Has Unmatched Parenthesis" msgstr "" -#: cps/admin.py:1155 +#: cps/admin.py:1178 msgid "LDAP CACertificate, Certificate or Key Location is not Valid, Please Enter Correct Path" msgstr "" -#: cps/admin.py:1197 cps/admin.py:1308 cps/admin.py:1405 cps/admin.py:1521 -#: cps/admin.py:1590 cps/shelf.py:100 cps/shelf.py:160 cps/shelf.py:203 -#: cps/shelf.py:279 cps/shelf.py:341 cps/shelf.py:376 cps/shelf.py:451 -msgid "Settings DB is not Writeable" -msgstr "" - -#: cps/admin.py:1208 -msgid "DB Location is not Valid, Please Enter Correct Path" -msgstr "Umístění databáze není platné, opravte prosím cestu" - -#: cps/admin.py:1223 -msgid "DB is not Writeable" -msgstr "Databáze není zapisovatelná" - -#: cps/admin.py:1235 -msgid "Keyfile Location is not Valid, Please Enter Correct Path" -msgstr "Umístění souboru klíčů není platné, zadejte prosím správnou cestu" - -#: cps/admin.py:1239 -msgid "Certfile Location is not Valid, Please Enter Correct Path" -msgstr "Umístění certifikátu není platné, zadejte prosím správnou cestu" - -#: cps/admin.py:1346 -#, fuzzy -msgid "Database Settings updated" -msgstr "Nastavení e-mailového serveru aktualizováno" - -#: cps/admin.py:1354 -#, fuzzy -msgid "Database Configuration" -msgstr "Konfigurace funkcí" - -#: cps/admin.py:1370 cps/web.py:1479 -msgid "Please fill out all fields!" -msgstr "Vyplňte všechna pole!" - -#: cps/admin.py:1378 -msgid "E-mail is not from valid domain" -msgstr "E-mail není z platné domény" - -#: cps/admin.py:1384 cps/admin.py:1543 -msgid "Add new user" -msgstr "Přidat nového uživatele" - -#: cps/admin.py:1395 -#, python-format -msgid "User '%(user)s' created" -msgstr "Uživatel '%(user)s' vytvořen" - -#: cps/admin.py:1401 -#, fuzzy -msgid "Found an existing account for this e-mail address or name." -msgstr "Byl nalezen existující účet pro tuto e-mailovou adresu nebo přezdívku." - -#: cps/admin.py:1430 -#, python-format -msgid "User '%(nick)s' deleted" -msgstr "Uživatel '%(nick)s' smazán" - -#: cps/admin.py:1432 cps/admin.py:1433 -msgid "Can't delete Guest User" -msgstr "" - -#: cps/admin.py:1436 -msgid "No admin user remaining, can't delete user" -msgstr "Nezbývá žádný správce, nemůžete jej odstranit" - -#: cps/admin.py:1509 cps/admin.py:1634 -#, python-format -msgid "Edit User %(nick)s" -msgstr "Upravit uživatele %(nick)s" - -#: cps/admin.py:1513 -#, python-format -msgid "User '%(nick)s' updated" -msgstr "Uživatel '%(nick)s' aktualizován" - -#: cps/admin.py:1517 cps/admin.py:1649 cps/web.py:1504 cps/web.py:1564 -msgid "An unknown error occurred. Please try again later." -msgstr "Neznámá chyba. Opakujte prosím později." - -#: cps/admin.py:1552 cps/templates/admin.html:98 -msgid "Edit E-mail Server Settings" -msgstr "Změnit SMTP nastavení" - -#: cps/admin.py:1571 -msgid "Gmail Account Verification Successful" -msgstr "" - -#: cps/admin.py:1597 -#, python-format -msgid "Test e-mail queued for sending to %(email)s, please check Tasks for result" -msgstr "" - -#: cps/admin.py:1600 -#, python-format -msgid "There was an error sending the Test e-mail: %(res)s" -msgstr "Při odesílání zkušebního e-mailu došlo k chybě: %(res)s" - -#: cps/admin.py:1602 -msgid "Please configure your e-mail address first..." -msgstr "Prvně nastavte svou e-mailovou adresu..." - -#: cps/admin.py:1604 -msgid "E-mail server settings updated" -msgstr "Nastavení e-mailového serveru aktualizováno" - -#: cps/admin.py:1646 -#, python-format -msgid "Password for user %(user)s reset" -msgstr "Heslo pro uživatele %(user)s resetováno" - -#: cps/admin.py:1652 cps/web.py:1444 -msgid "Please configure the SMTP mail settings first..." -msgstr "Nejprve nakonfigurujte nastavení pošty SMTP..." - -#: cps/admin.py:1663 -msgid "Logfile viewer" -msgstr "Prohlížeč log souborů" - -#: cps/admin.py:1729 -msgid "Requesting update package" -msgstr "Požadování balíčku aktualizace" - -#: cps/admin.py:1730 -msgid "Downloading update package" -msgstr "Stahování balíčku aktualizace" - -#: cps/admin.py:1731 -msgid "Unzipping update package" -msgstr "Rozbalování balíčku aktualizace" - -#: cps/admin.py:1732 -msgid "Replacing files" -msgstr "Nahrazování souborů" - -#: cps/admin.py:1733 -msgid "Database connections are closed" -msgstr "Databázová připojení jsou uzavřena" - -#: cps/admin.py:1734 -msgid "Stopping server" -msgstr "Zastavuji server" - -#: cps/admin.py:1735 -msgid "Update finished, please press okay and reload page" -msgstr "Aktualizace dokončena, klepněte na tlačítko OK a znovu načtěte stránku" - -#: cps/admin.py:1736 cps/admin.py:1737 cps/admin.py:1738 cps/admin.py:1739 -#: cps/admin.py:1740 cps/admin.py:1741 -msgid "Update failed:" -msgstr "Aktualizace selhala:" - -#: cps/admin.py:1736 cps/updater.py:385 cps/updater.py:595 cps/updater.py:597 -msgid "HTTP Error" -msgstr "HTTP chyba" - -#: cps/admin.py:1737 cps/updater.py:387 cps/updater.py:599 -msgid "Connection error" -msgstr "Chyba připojení" - -#: cps/admin.py:1738 cps/updater.py:389 cps/updater.py:601 -msgid "Timeout while establishing connection" -msgstr "Vypršel časový limit při navazování spojení" - -#: cps/admin.py:1739 cps/updater.py:391 cps/updater.py:603 -msgid "General error" -msgstr "Všeobecná chyba" - -#: cps/admin.py:1740 -#, fuzzy -msgid "Update file could not be saved in temp dir" -msgstr "Aktualizační soubor nemohl být uložen do Temp Dir" - -#: cps/admin.py:1741 -msgid "Files could not be replaced during update" -msgstr "" - -#: cps/admin.py:1765 -#, fuzzy -msgid "Failed to extract at least One LDAP User" -msgstr "Nepodařilo se vytvořit nejméně jednoho uživatele LDAP" - -#: cps/admin.py:1810 -msgid "Failed to Create at Least One LDAP User" -msgstr "Nepodařilo se vytvořit nejméně jednoho uživatele LDAP" - -#: cps/admin.py:1823 -#, python-format -msgid "Error: %(ldaperror)s" -msgstr "Chyba: %(ldaperror)s" - -#: cps/admin.py:1827 -msgid "Error: No user returned in response of LDAP server" -msgstr "Chyba: Žádná reakce od uživatele LDAP serveru" - -#: cps/admin.py:1860 -msgid "At Least One LDAP User Not Found in Database" -msgstr "Nejméně jeden uživatel LDAP nenalezen v databázi" - -#: cps/admin.py:1862 -msgid "{} User Successfully Imported" -msgstr "" - -#: cps/converter.py:30 -msgid "not configured" -msgstr "není nakonfigurováno" - -#: cps/converter.py:32 -msgid "Execution permissions missing" -msgstr "Chybí povolení k exekuci" - -#: cps/db.py:651 cps/web.py:667 cps/web.py:1155 -#, python-format -msgid "Custom Column No.%(column)d is not existing in calibre database" -msgstr "Vlastní sloupec %(column)d neexistuje v databázi" - -#: cps/editbooks.py:300 cps/editbooks.py:302 -msgid "Book Format Successfully Deleted" -msgstr "Formát knihy úspěšně smazán" - -#: cps/editbooks.py:309 cps/editbooks.py:311 -msgid "Book Successfully Deleted" -msgstr "Kniha úspěšně smazána" - -#: cps/editbooks.py:361 -msgid "You are missing permissions to delete books" -msgstr "" - -#: cps/editbooks.py:376 cps/editbooks.py:763 cps/web.py:523 cps/web.py:1703 -#: cps/web.py:1744 cps/web.py:1811 -msgid "Oops! Selected book title is unavailable. File does not exist or is not accessible" -msgstr "Jejda! Vybraná kniha není k dispozici. Soubor neexistuje nebo není přístupný" - -#: cps/editbooks.py:410 -msgid "edit metadata" -msgstr "upravit metadata" - -#: cps/editbooks.py:458 -#, python-format -msgid "%(seriesindex)s is not a valid number, skipping" -msgstr "" - -#: cps/editbooks.py:494 cps/editbooks.py:958 -#, fuzzy, python-format -msgid "'%(langname)s' is not a valid language" -msgstr "%(langname)s není platným jazykem" - -#: cps/editbooks.py:634 cps/editbooks.py:985 -#, python-format -msgid "File extension '%(ext)s' is not allowed to be uploaded to this server" -msgstr "Soubor s příponou '%(ext)s' nelze odeslat na tento server" - -#: cps/editbooks.py:638 cps/editbooks.py:989 -msgid "File to be uploaded must have an extension" -msgstr "Soubor, který má být odeslán musí mít příponu" - -#: cps/editbooks.py:650 -#, python-format -msgid "Failed to create path %(path)s (Permission denied)." -msgstr "Nepodařilo se vytvořit cestu %(path)s (oprávnění odepřeno)." - -#: cps/editbooks.py:655 -#, python-format -msgid "Failed to store file %(file)s." -msgstr "Uložení souboru %(file)s se nezdařilo." - -#: cps/editbooks.py:673 cps/editbooks.py:1076 cps/web.py:1664 +#: cps/admin.py:1223 cps/admin.py:1339 cps/admin.py:1437 cps/admin.py:1554 +#: cps/admin.py:1623 cps/editbooks.py:678 cps/editbooks.py:882 +#: cps/editbooks.py:1130 cps/shelf.py:100 cps/shelf.py:160 cps/shelf.py:203 +#: cps/shelf.py:278 cps/shelf.py:343 cps/shelf.py:380 cps/shelf.py:456 +#: cps/web.py:1742 #, python-format msgid "Database error: %(error)s." msgstr "Chyba databáze: %(error)s." -#: cps/editbooks.py:678 +#: cps/admin.py:1235 +msgid "DB Location is not Valid, Please Enter Correct Path" +msgstr "Umístění databáze není platné, opravte prosím cestu" + +#: cps/admin.py:1253 +msgid "DB is not Writeable" +msgstr "Databáze není zapisovatelná" + +#: cps/admin.py:1266 +msgid "Keyfile Location is not Valid, Please Enter Correct Path" +msgstr "Umístění souboru klíčů není platné, zadejte prosím správnou cestu" + +#: cps/admin.py:1270 +msgid "Certfile Location is not Valid, Please Enter Correct Path" +msgstr "Umístění certifikátu není platné, zadejte prosím správnou cestu" + +#: cps/admin.py:1378 +#, fuzzy +msgid "Database Settings updated" +msgstr "Nastavení e-mailového serveru aktualizováno" + +#: cps/admin.py:1386 +#, fuzzy +msgid "Database Configuration" +msgstr "Konfigurace funkcí" + +#: cps/admin.py:1402 cps/web.py:1557 +msgid "Please fill out all fields!" +msgstr "Vyplňte všechna pole!" + +#: cps/admin.py:1410 +msgid "E-mail is not from valid domain" +msgstr "E-mail není z platné domény" + +#: cps/admin.py:1416 cps/admin.py:1576 +msgid "Add new user" +msgstr "Přidat nového uživatele" + +#: cps/admin.py:1427 +#, python-format +msgid "User '%(user)s' created" +msgstr "Uživatel '%(user)s' vytvořen" + +#: cps/admin.py:1433 +#, fuzzy +msgid "Found an existing account for this e-mail address or name." +msgstr "Byl nalezen existující účet pro tuto e-mailovou adresu nebo přezdívku." + +#: cps/admin.py:1463 +#, python-format +msgid "User '%(nick)s' deleted" +msgstr "Uživatel '%(nick)s' smazán" + +#: cps/admin.py:1465 cps/admin.py:1466 +msgid "Can't delete Guest User" +msgstr "" + +#: cps/admin.py:1469 +msgid "No admin user remaining, can't delete user" +msgstr "Nezbývá žádný správce, nemůžete jej odstranit" + +#: cps/admin.py:1542 cps/admin.py:1667 +#, python-format +msgid "Edit User %(nick)s" +msgstr "Upravit uživatele %(nick)s" + +#: cps/admin.py:1546 +#, python-format +msgid "User '%(nick)s' updated" +msgstr "Uživatel '%(nick)s' aktualizován" + +#: cps/admin.py:1550 cps/admin.py:1682 cps/web.py:1582 cps/web.py:1642 +msgid "An unknown error occurred. Please try again later." +msgstr "Neznámá chyba. Opakujte prosím později." + +#: cps/admin.py:1585 cps/templates/admin.html:100 +msgid "Edit E-mail Server Settings" +msgstr "Změnit SMTP nastavení" + +#: cps/admin.py:1604 +msgid "Gmail Account Verification Successful" +msgstr "" + +#: cps/admin.py:1630 +#, python-format +msgid "Test e-mail queued for sending to %(email)s, please check Tasks for result" +msgstr "" + +#: cps/admin.py:1633 +#, python-format +msgid "There was an error sending the Test e-mail: %(res)s" +msgstr "Při odesílání zkušebního e-mailu došlo k chybě: %(res)s" + +#: cps/admin.py:1635 +msgid "Please configure your e-mail address first..." +msgstr "Prvně nastavte svou e-mailovou adresu..." + +#: cps/admin.py:1637 +msgid "E-mail server settings updated" +msgstr "Nastavení e-mailového serveru aktualizováno" + +#: cps/admin.py:1679 +#, python-format +msgid "Password for user %(user)s reset" +msgstr "Heslo pro uživatele %(user)s resetováno" + +#: cps/admin.py:1685 cps/web.py:1522 +msgid "Please configure the SMTP mail settings first..." +msgstr "Nejprve nakonfigurujte nastavení pošty SMTP..." + +#: cps/admin.py:1696 +msgid "Logfile viewer" +msgstr "Prohlížeč log souborů" + +#: cps/admin.py:1762 +msgid "Requesting update package" +msgstr "Požadování balíčku aktualizace" + +#: cps/admin.py:1763 +msgid "Downloading update package" +msgstr "Stahování balíčku aktualizace" + +#: cps/admin.py:1764 +msgid "Unzipping update package" +msgstr "Rozbalování balíčku aktualizace" + +#: cps/admin.py:1765 +msgid "Replacing files" +msgstr "Nahrazování souborů" + +#: cps/admin.py:1766 +msgid "Database connections are closed" +msgstr "Databázová připojení jsou uzavřena" + +#: cps/admin.py:1767 +msgid "Stopping server" +msgstr "Zastavuji server" + +#: cps/admin.py:1768 +msgid "Update finished, please press okay and reload page" +msgstr "Aktualizace dokončena, klepněte na tlačítko OK a znovu načtěte stránku" + +#: cps/admin.py:1769 cps/admin.py:1770 cps/admin.py:1771 cps/admin.py:1772 +#: cps/admin.py:1773 cps/admin.py:1774 +msgid "Update failed:" +msgstr "Aktualizace selhala:" + +#: cps/admin.py:1769 cps/updater.py:384 cps/updater.py:619 cps/updater.py:621 +msgid "HTTP Error" +msgstr "HTTP chyba" + +#: cps/admin.py:1770 cps/updater.py:386 cps/updater.py:623 +msgid "Connection error" +msgstr "Chyba připojení" + +#: cps/admin.py:1771 cps/updater.py:388 cps/updater.py:625 +msgid "Timeout while establishing connection" +msgstr "Vypršel časový limit při navazování spojení" + +#: cps/admin.py:1772 cps/updater.py:390 cps/updater.py:627 +msgid "General error" +msgstr "Všeobecná chyba" + +#: cps/admin.py:1773 +#, fuzzy +msgid "Update file could not be saved in temp dir" +msgstr "Aktualizační soubor nemohl být uložen do Temp Dir" + +#: cps/admin.py:1774 +msgid "Files could not be replaced during update" +msgstr "" + +#: cps/admin.py:1798 +#, fuzzy +msgid "Failed to extract at least One LDAP User" +msgstr "Nepodařilo se vytvořit nejméně jednoho uživatele LDAP" + +#: cps/admin.py:1843 +msgid "Failed to Create at Least One LDAP User" +msgstr "Nepodařilo se vytvořit nejméně jednoho uživatele LDAP" + +#: cps/admin.py:1856 +#, python-format +msgid "Error: %(ldaperror)s" +msgstr "Chyba: %(ldaperror)s" + +#: cps/admin.py:1860 +msgid "Error: No user returned in response of LDAP server" +msgstr "Chyba: Žádná reakce od uživatele LDAP serveru" + +#: cps/admin.py:1893 +msgid "At Least One LDAP User Not Found in Database" +msgstr "Nejméně jeden uživatel LDAP nenalezen v databázi" + +#: cps/admin.py:1895 +msgid "{} User Successfully Imported" +msgstr "" + +#: cps/converter.py:30 +msgid "not installed" +msgstr "není nainstalováno" + +#: cps/converter.py:31 +msgid "Execution permissions missing" +msgstr "Chybí povolení k exekuci" + +#: cps/db.py:674 cps/web.py:710 cps/web.py:1222 +#, python-format +msgid "Custom Column No.%(column)d is not existing in calibre database" +msgstr "Vlastní sloupec %(column)d neexistuje v databázi" + +#: cps/db.py:917 cps/templates/config_edit.html:204 +#: cps/templates/config_view_edit.html:62 cps/templates/email_edit.html:41 +#: cps/web.py:551 cps/web.py:585 cps/web.py:646 cps/web.py:671 cps/web.py:1003 +#: cps/web.py:1032 cps/web.py:1066 cps/web.py:1093 cps/web.py:1132 +msgid "None" +msgstr "Žádné" + +#: cps/editbooks.py:295 cps/editbooks.py:297 +msgid "Book Format Successfully Deleted" +msgstr "Formát knihy úspěšně smazán" + +#: cps/editbooks.py:304 cps/editbooks.py:306 +msgid "Book Successfully Deleted" +msgstr "Kniha úspěšně smazána" + +#: cps/editbooks.py:358 +msgid "You are missing permissions to delete books" +msgstr "" + +#: cps/editbooks.py:373 cps/editbooks.py:765 cps/web.py:518 cps/web.py:1783 +#: cps/web.py:1825 cps/web.py:1870 +msgid "Oops! Selected book title is unavailable. File does not exist or is not accessible" +msgstr "Jejda! Vybraná kniha není k dispozici. Soubor neexistuje nebo není přístupný" + +#: cps/editbooks.py:408 +msgid "edit metadata" +msgstr "upravit metadata" + +#: cps/editbooks.py:457 +#, python-format +msgid "%(seriesindex)s is not a valid number, skipping" +msgstr "" + +#: cps/editbooks.py:493 cps/editbooks.py:1001 +#, fuzzy, python-format +msgid "'%(langname)s' is not a valid language" +msgstr "%(langname)s není platným jazykem" + +#: cps/editbooks.py:634 +msgid "User has no rights to upload additional file formats" +msgstr "" + +#: cps/editbooks.py:639 cps/editbooks.py:1029 +#, python-format +msgid "File extension '%(ext)s' is not allowed to be uploaded to this server" +msgstr "Soubor s příponou '%(ext)s' nelze odeslat na tento server" + +#: cps/editbooks.py:643 cps/editbooks.py:1033 +msgid "File to be uploaded must have an extension" +msgstr "Soubor, který má být odeslán musí mít příponu" + +#: cps/editbooks.py:655 +#, python-format +msgid "Failed to create path %(path)s (Permission denied)." +msgstr "Nepodařilo se vytvořit cestu %(path)s (oprávnění odepřeno)." + +#: cps/editbooks.py:660 +#, python-format +msgid "Failed to store file %(file)s." +msgstr "Uložení souboru %(file)s se nezdařilo." + +#: cps/editbooks.py:683 #, python-format msgid "File format %(ext)s added to %(book)s" msgstr "Formát souboru %(ext)s přidán do %(book)s" -#: cps/editbooks.py:814 +#: cps/editbooks.py:697 cps/editbooks.py:809 +msgid "User has no rights to upload cover" +msgstr "" + +#: cps/editbooks.py:828 msgid "Identifiers are not Case Sensitive, Overwriting Old Identifier" msgstr "" -#: cps/editbooks.py:848 +#: cps/editbooks.py:869 msgid "Metadata successfully updated" msgstr "Metadata úspěšně aktualizována" -#: cps/editbooks.py:861 -msgid "Error editing book, please check logfile for details" -msgstr "Chyba při úpravách knihy, zkontrolujte prosím log pro podrobnosti" +#: cps/editbooks.py:887 +msgid "Error editing book: {}" +msgstr "" -#: cps/editbooks.py:899 +#: cps/editbooks.py:951 msgid "Uploaded book probably exists in the library, consider to change before upload new: " msgstr "Nahraná kniha pravděpodobně existuje v knihovně, zvažte prosím změnu před nahráním nové: " -#: cps/editbooks.py:997 +#: cps/editbooks.py:1041 #, python-format msgid "File %(filename)s could not saved to temp dir" msgstr "Soubor %(filename)s nemohl být uložen do dočasného adresáře" -#: cps/editbooks.py:1016 +#: cps/editbooks.py:1061 #, python-format msgid "Failed to Move Cover File %(file)s: %(error)s" msgstr "Nepodařilo se přesunout soubor obalu %(file)s: %(error)s" -#: cps/editbooks.py:1063 +#: cps/editbooks.py:1117 #, python-format msgid "File %(file)s uploaded" msgstr "Soubor %(file)s nahrán" -#: cps/editbooks.py:1088 +#: cps/editbooks.py:1143 msgid "Source or destination format for conversion missing" msgstr "Chybí zdrojový nebo cílový formát pro převod" -#: cps/editbooks.py:1096 +#: cps/editbooks.py:1151 #, python-format msgid "Book successfully queued for converting to %(book_format)s" msgstr "Kniha byla úspěšně zařazena do fronty pro převod do %(book_format)s" -#: cps/editbooks.py:1100 +#: cps/editbooks.py:1155 #, python-format msgid "There was an error converting this book: %(res)s" msgstr "Při převodu této knihy došlo k chybě: %(res)s" @@ -610,175 +613,192 @@ msgstr "Google Drive nastavení nebylo dokončeno, zkuste znovu deaktivovat a a msgid "Callback domain is not verified, please follow steps to verify domain in google developer console" msgstr "Doména zpětného volání není ověřena, postupujte podle pokynů k ověření domény v konzole pro vývojáře google" -#: cps/helper.py:77 +#: cps/helper.py:81 #, python-format msgid "%(format)s format not found for book id: %(book)d" msgstr "%(format)s formát pro knihu: %(book)d nenalezen" -#: cps/helper.py:83 cps/tasks/convert.py:73 +#: cps/helper.py:87 cps/tasks/convert.py:75 #, python-format msgid "%(format)s not found on Google Drive: %(fn)s" msgstr "%(format)s nenalezen na Google Drive: %(fn)s" -#: cps/helper.py:88 +#: cps/helper.py:92 #, python-format msgid "%(format)s not found: %(fn)s" msgstr "%(format)s nenalezen: %(fn)s" -#: cps/helper.py:93 cps/helper.py:217 cps/templates/detail.html:41 +#: cps/helper.py:97 cps/helper.py:221 cps/templates/detail.html:41 #: cps/templates/detail.html:45 msgid "Send to Kindle" msgstr "Poslat do Kindle" -#: cps/helper.py:94 cps/helper.py:111 cps/helper.py:219 +#: cps/helper.py:98 cps/helper.py:115 cps/helper.py:223 msgid "This e-mail has been sent via Calibre-Web." msgstr "Tento e-mail byl odeslán přes Calibre-Web." -#: cps/helper.py:109 +#: cps/helper.py:113 msgid "Calibre-Web test e-mail" msgstr "Calibre-Web zkušební e-mail" -#: cps/helper.py:110 +#: cps/helper.py:114 msgid "Test e-mail" msgstr "Zkušební e-mail" -#: cps/helper.py:127 +#: cps/helper.py:131 msgid "Get Started with Calibre-Web" msgstr "Začínáme s Calibre-Web" -#: cps/helper.py:132 +#: cps/helper.py:136 #, python-format msgid "Registration e-mail for user: %(name)s" msgstr "Registrační e-mail pro uživatele: %(name)s" -#: cps/helper.py:143 cps/helper.py:149 +#: cps/helper.py:147 cps/helper.py:153 #, python-format msgid "Convert %(orig)s to %(format)s and send to Kindle" msgstr "Převést %(orig)s do %(format)s a poslat do Kindle" -#: cps/helper.py:168 cps/helper.py:172 cps/helper.py:176 +#: cps/helper.py:172 cps/helper.py:176 cps/helper.py:180 #, python-format msgid "Send %(format)s to Kindle" msgstr "Poslat %(format)s do Kindle" -#: cps/helper.py:216 cps/tasks/convert.py:90 +#: cps/helper.py:220 cps/tasks/convert.py:92 #, fuzzy, python-format msgid "%(book)s send to Kindle" msgstr "Poslat do Kindle" -#: cps/helper.py:221 +#: cps/helper.py:225 msgid "The requested file could not be read. Maybe wrong permissions?" msgstr "Požadovaný soubor nelze přečíst. Možná nesprávná oprávnění?" -#: cps/helper.py:313 +#: cps/helper.py:353 +msgid "Read status could not set: {}" +msgstr "" + +#: cps/helper.py:376 #, python-format msgid "Deleting bookfolder for book %(id)s failed, path has subfolders: %(path)s" msgstr "" -#: cps/helper.py:319 +#: cps/helper.py:382 #, python-format msgid "Deleting book %(id)s failed: %(message)s" msgstr "Mazání knihy selhalo %(id)s failed: %(message)s" -#: cps/helper.py:330 +#: cps/helper.py:393 #, fuzzy, python-format msgid "Deleting book %(id)s from database only, book path in database not valid: %(path)s" msgstr "Mazání knihy %(id)s, cesta ke knize není platná %(path)s" -#: cps/helper.py:385 -#, python-format -msgid "Rename title from: '%(src)s' to '%(dest)s' failed with error: %(error)s" +#: cps/helper.py:458 +#, fuzzy, python-format +msgid "Rename author from: '%(src)s' to '%(dest)s' failed with error: %(error)s" msgstr "Přejmenování názvu z: '%(src)s' na '%(dest)s' selhalo chybou: %(error)s" -#: cps/helper.py:400 -#, python-format -msgid "Rename file in path '%(src)s' to '%(dest)s' failed with error: %(error)s" -msgstr "Přejmenování souboru v cestě '%(src)s' na '%(dest)s' selhalo chybou: %(error)s" - -#: cps/helper.py:425 cps/helper.py:435 cps/helper.py:443 +#: cps/helper.py:529 cps/helper.py:538 #, python-format msgid "File %(file)s not found on Google Drive" msgstr "Soubor %(file)s nenalezen na Google Drive" -#: cps/helper.py:464 +#: cps/helper.py:572 +#, python-format +msgid "Rename title from: '%(src)s' to '%(dest)s' failed with error: %(error)s" +msgstr "Přejmenování názvu z: '%(src)s' na '%(dest)s' selhalo chybou: %(error)s" + +#: cps/helper.py:592 +msgid "Error in rename file in path: {}" +msgstr "" + +#: cps/helper.py:610 #, python-format msgid "Book path %(path)s not found on Google Drive" msgstr "Cesta ke knize %(path)s nebyla nalezena na Google Drive" -#: cps/helper.py:504 cps/web.py:1659 +#: cps/helper.py:651 cps/web.py:1737 #, fuzzy msgid "Found an existing account for this e-mail address" msgstr "Byl nalezen existující účet pro tuto e-mailovou adresu." -#: cps/helper.py:512 +#: cps/helper.py:659 msgid "This username is already taken" msgstr "Zadané uživatelské jméno je již použito" -#: cps/helper.py:522 +#: cps/helper.py:669 msgid "Invalid e-mail address format" msgstr "" -#: cps/helper.py:595 +#: cps/helper.py:754 +msgid "Python modul 'advocate' is not installed but is needed for cover downloads" +msgstr "" + +#: cps/helper.py:767 msgid "Error Downloading Cover" msgstr "Chyba stahování obalu" -#: cps/helper.py:598 +#: cps/helper.py:770 msgid "Cover Format Error" msgstr "Chyba formátu obalu" -#: cps/helper.py:608 +#: cps/helper.py:773 +msgid "You are not allowed to access localhost or the local network for cover uploads" +msgstr "" + +#: cps/helper.py:783 msgid "Failed to create path for cover" msgstr "Vytvoření cesty obalu selhalo" -#: cps/helper.py:624 +#: cps/helper.py:799 msgid "Cover-file is not a valid image file, or could not be stored" msgstr "Soubor obalu není platný, nebo nelze uložit" -#: cps/helper.py:635 +#: cps/helper.py:810 msgid "Only jpg/jpeg/png/webp/bmp files are supported as coverfile" msgstr "" -#: cps/helper.py:648 +#: cps/helper.py:822 msgid "Invalid cover file content" msgstr "" -#: cps/helper.py:652 +#: cps/helper.py:826 msgid "Only jpg/jpeg files are supported as coverfile" msgstr "Pouze jpg/jpeg jsou podporované soubory pro obal" -#: cps/helper.py:704 +#: cps/helper.py:878 msgid "Unrar binary file not found" msgstr "Unrar binární soubor nenalezen" -#: cps/helper.py:715 +#: cps/helper.py:889 msgid "Error excecuting UnRar" msgstr "Chyba provádění UnRar" -#: cps/helper.py:763 +#: cps/helper.py:937 msgid "Waiting" msgstr "Čekám" -#: cps/helper.py:765 +#: cps/helper.py:939 msgid "Failed" msgstr "Selhalo" -#: cps/helper.py:767 +#: cps/helper.py:941 msgid "Started" msgstr "Spuštěno" -#: cps/helper.py:769 +#: cps/helper.py:943 msgid "Finished" msgstr "Dokončeno" -#: cps/helper.py:771 +#: cps/helper.py:945 msgid "Unknown Status" msgstr "Neznámý stav" -#: cps/kobo_auth.py:127 -msgid "PLease access calibre-web from non localhost to get valid api_endpoint for kobo device" +#: cps/kobo_auth.py:128 +#, fuzzy +msgid "Please access Calibre-Web from non localhost to get valid api_endpoint for kobo device" msgstr "Pro získání platného api_endpoint pro zařízení Kobo, přístupte na calibre-web bez localhost" -#: cps/kobo_auth.py:130 cps/kobo_auth.py:158 +#: cps/kobo_auth.py:154 msgid "Kobo Setup" msgstr "Kobo nastavení" @@ -787,7 +807,7 @@ msgstr "Kobo nastavení" msgid "Register with %(provider)s" msgstr "Registrovat s %(provider)s" -#: cps/oauth_bb.py:138 cps/remotelogin.py:133 cps/web.py:1535 +#: cps/oauth_bb.py:138 cps/remotelogin.py:130 cps/web.py:1613 #, python-format msgid "you are now logged in as: '%(nickname)s'" msgstr "nyní jste přihlášen jako: '%(nickname)s'" @@ -848,163 +868,163 @@ msgstr "Google Oauth chyba, prosím opakujte později." msgid "Google Oauth error: {}" msgstr "" -#: cps/opds.py:384 +#: cps/opds.py:298 msgid "{} Stars" msgstr "" -#: cps/remotelogin.py:65 cps/templates/layout.html:84 -#: cps/templates/login.html:4 cps/templates/login.html:21 cps/web.py:1584 +#: cps/remotelogin.py:62 cps/templates/layout.html:84 +#: cps/templates/login.html:4 cps/templates/login.html:21 cps/web.py:1662 msgid "Login" msgstr "Přihlásit" -#: cps/remotelogin.py:77 cps/remotelogin.py:111 +#: cps/remotelogin.py:74 cps/remotelogin.py:108 msgid "Token not found" msgstr "Token nenalezen" -#: cps/remotelogin.py:86 cps/remotelogin.py:119 +#: cps/remotelogin.py:83 cps/remotelogin.py:116 msgid "Token has expired" msgstr "Token vypršel" -#: cps/remotelogin.py:95 +#: cps/remotelogin.py:92 msgid "Success! Please return to your device" msgstr "Úspěch! Vraťte se prosím do zařízení" -#: cps/render_template.py:39 cps/web.py:416 +#: cps/render_template.py:41 cps/web.py:407 msgid "Books" msgstr "Knihy" -#: cps/render_template.py:41 +#: cps/render_template.py:43 msgid "Show recent books" msgstr "Zobrazit nedávné knihy" -#: cps/render_template.py:42 cps/templates/index.xml:25 +#: cps/render_template.py:44 cps/templates/index.xml:25 msgid "Hot Books" msgstr "Žhavé knihy" -#: cps/render_template.py:44 +#: cps/render_template.py:46 msgid "Show Hot Books" msgstr "Zobrazit žhavé knihy" -#: cps/render_template.py:46 cps/render_template.py:51 +#: cps/render_template.py:48 cps/render_template.py:53 msgid "Downloaded Books" msgstr "" -#: cps/render_template.py:48 cps/render_template.py:53 +#: cps/render_template.py:50 cps/render_template.py:55 #: cps/templates/user_table.html:167 msgid "Show Downloaded Books" msgstr "" -#: cps/render_template.py:56 cps/templates/index.xml:32 cps/web.py:430 +#: cps/render_template.py:58 cps/templates/index.xml:32 cps/web.py:422 msgid "Top Rated Books" msgstr "Nejlépe hodnocené knihy" -#: cps/render_template.py:58 cps/templates/user_table.html:161 +#: cps/render_template.py:60 cps/templates/user_table.html:161 msgid "Show Top Rated Books" msgstr "Zobrazit nejlépe hodnocené knihy" -#: cps/render_template.py:59 cps/templates/index.xml:54 -#: cps/templates/index.xml:58 cps/web.py:676 +#: cps/render_template.py:61 cps/templates/index.xml:54 +#: cps/templates/index.xml:58 cps/web.py:729 msgid "Read Books" msgstr "Přečtené knihy" -#: cps/render_template.py:61 +#: cps/render_template.py:63 msgid "Show read and unread" msgstr "Zobrazit prečtené a nepřečtené" -#: cps/render_template.py:63 cps/templates/index.xml:61 -#: cps/templates/index.xml:65 cps/web.py:679 +#: cps/render_template.py:65 cps/templates/index.xml:61 +#: cps/templates/index.xml:65 cps/web.py:732 msgid "Unread Books" msgstr "Nepřečtené knihy" -#: cps/render_template.py:65 +#: cps/render_template.py:67 msgid "Show unread" msgstr "Zobrazit nepřečtené" -#: cps/render_template.py:66 +#: cps/render_template.py:68 msgid "Discover" msgstr "Objevte" -#: cps/render_template.py:68 cps/templates/index.xml:50 +#: cps/render_template.py:70 cps/templates/index.xml:50 #: cps/templates/user_table.html:162 msgid "Show Random Books" msgstr "Zobrazit náhodné knihy" -#: cps/render_template.py:69 cps/templates/book_table.html:67 -#: cps/templates/index.xml:83 cps/web.py:1041 +#: cps/render_template.py:71 cps/templates/book_table.html:67 +#: cps/templates/index.xml:83 cps/web.py:1135 msgid "Categories" msgstr "Kategorie" -#: cps/render_template.py:71 cps/templates/user_table.html:158 +#: cps/render_template.py:73 cps/templates/user_table.html:158 msgid "Show category selection" msgstr "Zobrazit výběr kategorie" -#: cps/render_template.py:72 cps/templates/book_edit.html:90 +#: cps/render_template.py:74 cps/templates/book_edit.html:90 #: cps/templates/book_table.html:68 cps/templates/index.xml:90 -#: cps/templates/search_form.html:69 cps/web.py:948 cps/web.py:959 +#: cps/templates/search_form.html:69 cps/web.py:1034 cps/web.py:1041 msgid "Series" msgstr "Série" -#: cps/render_template.py:74 cps/templates/user_table.html:157 +#: cps/render_template.py:76 cps/templates/user_table.html:157 msgid "Show series selection" msgstr "Zobrazit výběr sérií" -#: cps/render_template.py:75 cps/templates/book_table.html:66 +#: cps/render_template.py:77 cps/templates/book_table.html:66 #: cps/templates/index.xml:69 msgid "Authors" msgstr "Autoři" -#: cps/render_template.py:77 cps/templates/user_table.html:160 +#: cps/render_template.py:79 cps/templates/user_table.html:160 msgid "Show author selection" msgstr "Zobrazit výběr autora" -#: cps/render_template.py:79 cps/templates/book_table.html:72 -#: cps/templates/index.xml:76 cps/web.py:925 +#: cps/render_template.py:81 cps/templates/book_table.html:72 +#: cps/templates/index.xml:76 cps/web.py:1006 msgid "Publishers" msgstr "Vydavatelé" -#: cps/render_template.py:81 cps/templates/user_table.html:163 +#: cps/render_template.py:83 cps/templates/user_table.html:163 msgid "Show publisher selection" msgstr "Zobrazit výběr vydavatele" -#: cps/render_template.py:82 cps/templates/book_table.html:70 +#: cps/render_template.py:84 cps/templates/book_table.html:70 #: cps/templates/index.xml:97 cps/templates/search_form.html:107 -#: cps/web.py:1018 +#: cps/web.py:1108 msgid "Languages" msgstr "Jazyky" -#: cps/render_template.py:85 cps/templates/user_table.html:155 +#: cps/render_template.py:87 cps/templates/user_table.html:155 msgid "Show language selection" msgstr "Zobrazit výběr jazyka" -#: cps/render_template.py:86 cps/templates/index.xml:104 +#: cps/render_template.py:88 cps/templates/index.xml:104 msgid "Ratings" msgstr "Hodnocení" -#: cps/render_template.py:88 cps/templates/user_table.html:164 +#: cps/render_template.py:90 cps/templates/user_table.html:164 msgid "Show ratings selection" msgstr "Zobrazit výběr hodnocení" -#: cps/render_template.py:89 cps/templates/index.xml:112 +#: cps/render_template.py:91 cps/templates/index.xml:112 msgid "File formats" msgstr "Formáty souborů" -#: cps/render_template.py:91 cps/templates/user_table.html:165 +#: cps/render_template.py:93 cps/templates/user_table.html:165 msgid "Show file formats selection" msgstr "Zobrazit výběr formátů" -#: cps/render_template.py:93 cps/web.py:703 +#: cps/render_template.py:95 cps/web.py:755 msgid "Archived Books" msgstr "Archivované knihy" -#: cps/render_template.py:95 cps/templates/user_table.html:166 +#: cps/render_template.py:97 cps/templates/user_table.html:166 msgid "Show archived books" msgstr "Zobrazit archivované knihy" -#: cps/render_template.py:97 cps/web.py:780 +#: cps/render_template.py:100 cps/web.py:837 msgid "Books List" msgstr "" -#: cps/render_template.py:99 cps/templates/user_table.html:168 +#: cps/render_template.py:102 cps/templates/user_table.html:168 msgid "Show Books List" msgstr "" @@ -1059,262 +1079,266 @@ msgstr "" msgid "Create a Shelf" msgstr "Vytvořit polici" -#: cps/shelf.py:237 +#: cps/shelf.py:236 #, fuzzy msgid "Sorry you are not allowed to edit this shelf" msgstr "Lituji, nejste oprávněni odebrat knihu z této police: %(sname)s" -#: cps/shelf.py:239 +#: cps/shelf.py:238 msgid "Edit a shelf" msgstr "Upravit polici" -#: cps/shelf.py:249 +#: cps/shelf.py:248 msgid "Sorry you are not allowed to create a public shelf" msgstr "" -#: cps/shelf.py:266 +#: cps/shelf.py:265 #, python-format msgid "Shelf %(title)s created" msgstr "Police %(title)s vytvořena" -#: cps/shelf.py:269 +#: cps/shelf.py:268 #, python-format msgid "Shelf %(title)s changed" msgstr "Police %(title)s změněna" -#: cps/shelf.py:283 +#: cps/shelf.py:282 msgid "There was an error" msgstr "Došlo k chybě" -#: cps/shelf.py:305 +#: cps/shelf.py:304 #, python-format msgid "A public shelf with the name '%(title)s' already exists." msgstr "Veřejná police s názvem '%(title)s' již existuje." -#: cps/shelf.py:316 +#: cps/shelf.py:315 #, python-format msgid "A private shelf with the name '%(title)s' already exists." msgstr "Osobní police s názvem ‘%(title)s’ již existuje." #: cps/shelf.py:337 +msgid "Error deleting Shelf" +msgstr "" + +#: cps/shelf.py:339 #, fuzzy msgid "Shelf successfully deleted" msgstr "Kniha úspěšně smazána" -#: cps/shelf.py:386 +#: cps/shelf.py:389 #, python-format msgid "Change order of Shelf: '%(name)s'" msgstr "Změnit pořadí Police: '%(name)s'" -#: cps/shelf.py:456 +#: cps/shelf.py:461 #, python-format msgid "Shelf: '%(name)s'" msgstr "Police: '%(name)s'" -#: cps/shelf.py:460 +#: cps/shelf.py:465 msgid "Error opening shelf. Shelf does not exist or is not accessible" msgstr "Chyba otevírání police. Police neexistuje nebo není přístupná" -#: cps/updater.py:403 cps/updater.py:414 cps/updater.py:514 cps/updater.py:529 +#: cps/updater.py:426 cps/updater.py:437 cps/updater.py:538 cps/updater.py:553 msgid "Unexpected data while reading update information" msgstr "Neočekávaná data při čtení informací o aktualizaci" -#: cps/updater.py:410 cps/updater.py:521 +#: cps/updater.py:433 cps/updater.py:545 msgid "No update available. You already have the latest version installed" msgstr "Aktualizace není k dispozici. Máte nainstalovanou nejnovější verzi" -#: cps/updater.py:428 +#: cps/updater.py:451 msgid "A new update is available. Click on the button below to update to the latest version." msgstr "Nová aktualizace k dispozici. Klepnutím na tlačítko níže aktualizujte na nejnovější verzi." -#: cps/updater.py:446 +#: cps/updater.py:469 msgid "Could not fetch update information" msgstr "Nelze získat informace o aktualizaci" -#: cps/updater.py:456 +#: cps/updater.py:479 msgid "Click on the button below to update to the latest stable version." msgstr "Klepnutím na tlačítko níže aktualizujte na nejnovější stabilní verzi." -#: cps/updater.py:465 cps/updater.py:479 cps/updater.py:490 +#: cps/updater.py:488 cps/updater.py:502 cps/updater.py:513 #, python-format msgid "A new update is available. Click on the button below to update to version: %(version)s" msgstr "Nová aktualizace k dispozici. Klepnutím na tlačítko níže aktualizujte na verzi: %(version)s" -#: cps/updater.py:507 +#: cps/updater.py:531 msgid "No release information available" msgstr "Nejsou k dispozici žádné informace o verzi" -#: cps/templates/index.html:5 cps/web.py:440 +#: cps/templates/index.html:5 cps/web.py:434 msgid "Discover (Random Books)" msgstr "Objevte (Náhodné knihy)" -#: cps/web.py:471 +#: cps/web.py:470 msgid "Hot Books (Most Downloaded)" msgstr "Žhavé knihy (Nejstahovanější)" -#: cps/web.py:507 +#: cps/web.py:501 #, python-format msgid "Downloaded books by %(user)s" msgstr "" -#: cps/web.py:539 +#: cps/web.py:534 #, python-format msgid "Author: %(name)s" msgstr "Autoři: %(name)s" -#: cps/web.py:554 +#: cps/web.py:570 #, python-format msgid "Publisher: %(name)s" msgstr "Vydavatel: %(name)s" -#: cps/web.py:569 +#: cps/web.py:598 #, python-format msgid "Series: %(serie)s" msgstr "Série: %(serie)s" -#: cps/web.py:582 +#: cps/web.py:610 #, python-format msgid "Rating: %(rating)s stars" msgstr "Hodnocení: %(rating)s stars" -#: cps/web.py:597 +#: cps/web.py:626 #, python-format msgid "File format: %(format)s" msgstr "Soubor formátů: %(format)s" -#: cps/web.py:615 +#: cps/web.py:663 #, python-format msgid "Category: %(name)s" msgstr "Kategorie: %(name)s" -#: cps/web.py:631 +#: cps/web.py:690 #, python-format msgid "Language: %(name)s" msgstr "Jazyky: %(name)s" -#: cps/templates/layout.html:56 cps/web.py:737 cps/web.py:1371 +#: cps/templates/layout.html:56 cps/web.py:789 cps/web.py:1444 msgid "Advanced Search" msgstr "Rozšířené hledání" #: cps/templates/book_edit.html:235 cps/templates/feed.xml:33 #: cps/templates/index.xml:11 cps/templates/layout.html:45 #: cps/templates/layout.html:48 cps/templates/search_form.html:226 -#: cps/web.py:750 cps/web.py:1077 +#: cps/web.py:807 cps/web.py:1164 msgid "Search" msgstr "Hledat" -#: cps/templates/admin.html:16 cps/web.py:903 +#: cps/templates/admin.html:16 cps/web.py:979 msgid "Downloads" msgstr "Stáhnutí" -#: cps/web.py:980 +#: cps/web.py:1068 msgid "Ratings list" msgstr "Seznam hodnocení" -#: cps/web.py:1001 +#: cps/web.py:1095 msgid "File formats list" msgstr "Seznam formátů" -#: cps/templates/layout.html:73 cps/templates/tasks.html:7 cps/web.py:1055 +#: cps/templates/layout.html:73 cps/templates/tasks.html:7 cps/web.py:1149 msgid "Tasks" msgstr "Úlohy" -#: cps/web.py:1215 +#: cps/web.py:1286 msgid "Published after " msgstr "Vydáno po " -#: cps/web.py:1222 +#: cps/web.py:1293 msgid "Published before " msgstr "Vydáno před " -#: cps/web.py:1244 +#: cps/web.py:1315 #, python-format msgid "Rating <= %(rating)s" msgstr "Hodnocení <= %(rating)s" -#: cps/web.py:1246 +#: cps/web.py:1317 #, python-format msgid "Rating >= %(rating)s" msgstr "Hodnocení >= %(rating)s" -#: cps/web.py:1248 +#: cps/web.py:1319 #, python-format msgid "Read Status = %(status)s" msgstr "" -#: cps/web.py:1353 +#: cps/web.py:1425 msgid "Error on search for custom columns, please restart Calibre-Web" msgstr "" -#: cps/web.py:1449 +#: cps/web.py:1527 #, python-format msgid "Book successfully queued for sending to %(kindlemail)s" msgstr "Kniha byla úspěšně zařazena do fronty pro odeslání na %(kindlemail)s" -#: cps/web.py:1453 +#: cps/web.py:1531 #, python-format msgid "Oops! There was an error sending this book: %(res)s" msgstr "Při odesílání této knihy došlo k chybě: %(res)s" -#: cps/web.py:1455 +#: cps/web.py:1533 msgid "Please update your profile with a valid Send to Kindle E-mail Address." msgstr "Nejprve nakonfigurujte vaši kindle e-mailovou adresu.." -#: cps/web.py:1472 +#: cps/web.py:1550 msgid "E-Mail server is not configured, please contact your administrator!" msgstr "E-mailový server není nakonfigurován, kontaktujte svého správce!" -#: cps/templates/layout.html:85 cps/templates/register.html:17 cps/web.py:1473 -#: cps/web.py:1480 cps/web.py:1486 cps/web.py:1505 cps/web.py:1509 -#: cps/web.py:1515 +#: cps/templates/layout.html:85 cps/templates/register.html:17 cps/web.py:1551 +#: cps/web.py:1558 cps/web.py:1564 cps/web.py:1583 cps/web.py:1587 +#: cps/web.py:1593 msgid "Register" msgstr "Registrovat" -#: cps/web.py:1507 +#: cps/web.py:1585 msgid "Your e-mail is not allowed to register" msgstr "Váš e-mail nemá povolení k registraci" -#: cps/web.py:1510 +#: cps/web.py:1588 msgid "Confirmation e-mail was send to your e-mail account." msgstr "Potvrzovací e-mail byl odeslán na váš účet." -#: cps/web.py:1524 +#: cps/web.py:1602 msgid "Cannot activate LDAP authentication" msgstr "Nelze aktivovat ověření LDAP" -#: cps/web.py:1543 +#: cps/web.py:1621 #, python-format msgid "Fallback Login as: '%(nickname)s', LDAP Server not reachable, or user not known" msgstr "Záložní přihlášení jako: ‘%(nickname)s’, server LDAP není dosažitelný nebo neznámý uživatel" -#: cps/web.py:1549 +#: cps/web.py:1627 #, python-format msgid "Could not login: %(message)s" msgstr "Nelze se přihlásit: %(message)s" -#: cps/web.py:1553 cps/web.py:1578 +#: cps/web.py:1631 cps/web.py:1656 msgid "Wrong Username or Password" msgstr "Špatné uživatelské jméno nebo heslo" -#: cps/web.py:1560 +#: cps/web.py:1638 msgid "New Password was send to your email address" msgstr "Nové heslo bylo zasláno na vaši emailovou adresu" -#: cps/web.py:1566 +#: cps/web.py:1644 msgid "Please enter valid username to reset password" msgstr "Zadejte platné uživatelské jméno pro obnovení hesla" -#: cps/web.py:1573 +#: cps/web.py:1651 #, python-format msgid "You are now logged in as: '%(nickname)s'" msgstr "Nyní jste přihlášeni jako: '%(nickname)s'" -#: cps/web.py:1639 cps/web.py:1688 +#: cps/web.py:1717 cps/web.py:1766 #, python-format msgid "%(name)s's profile" msgstr "%(name)s profil" -#: cps/web.py:1655 +#: cps/web.py:1733 msgid "Profile updated" msgstr "Profil aktualizován" @@ -1322,36 +1346,36 @@ msgstr "Profil aktualizován" msgid "Found no valid gmail.json file with OAuth information" msgstr "" -#: cps/tasks/convert.py:137 +#: cps/tasks/convert.py:154 #, python-format msgid "Calibre ebook-convert %(tool)s not found" msgstr "Calibre převaděč %(tool)s nenalezen" -#: cps/tasks/convert.py:163 +#: cps/tasks/convert.py:187 #, python-format msgid "%(format)s format not found on disk" msgstr "" -#: cps/tasks/convert.py:167 +#: cps/tasks/convert.py:191 msgid "Ebook converter failed with unknown error" msgstr "" -#: cps/tasks/convert.py:177 +#: cps/tasks/convert.py:201 #, python-format msgid "Kepubify-converter failed: %(error)s" msgstr "Kepubify-převaděč selhal: %(error)s" -#: cps/tasks/convert.py:199 +#: cps/tasks/convert.py:223 #, python-format msgid "Converted file not found or more than one file in folder %(folder)s" msgstr "Převedený soubor nebyl nalezen nebo více než jeden soubor ve složce %(folder)s" -#: cps/tasks/convert.py:222 +#: cps/tasks/convert.py:246 #, python-format msgid "Ebook-converter failed: %(error)s" msgstr "Převaděč eknih selhal: %(error)s" -#: cps/tasks/convert.py:245 +#: cps/tasks/convert.py:269 #, python-format msgid "Calibre failed with error: %(error)s" msgstr "" @@ -1406,7 +1430,7 @@ msgid "Edit" msgstr "Upravovat" #: cps/templates/admin.html:25 cps/templates/book_edit.html:16 -#: cps/templates/book_table.html:97 cps/templates/modal_dialogs.html:63 +#: cps/templates/book_table.html:100 cps/templates/modal_dialogs.html:63 #: cps/templates/modal_dialogs.html:116 cps/templates/user_edit.html:67 #: cps/templates/user_table.html:149 msgid "Delete" @@ -1416,180 +1440,180 @@ msgstr "Smazat" msgid "Public Shelf" msgstr "Veřejná police" -#: cps/templates/admin.html:51 +#: cps/templates/admin.html:53 msgid "Add New User" msgstr "Přidat nového uživatele" -#: cps/templates/admin.html:53 +#: cps/templates/admin.html:55 msgid "Import LDAP Users" msgstr "Importovat LDAP uživatele" -#: cps/templates/admin.html:60 +#: cps/templates/admin.html:62 msgid "E-mail Server Settings" msgstr "Nastavení e-mailového serveru SMTP" -#: cps/templates/admin.html:65 cps/templates/email_edit.html:31 +#: cps/templates/admin.html:67 cps/templates/email_edit.html:31 msgid "SMTP Hostname" msgstr "SMTP hostitel" -#: cps/templates/admin.html:69 cps/templates/email_edit.html:35 +#: cps/templates/admin.html:71 cps/templates/email_edit.html:35 msgid "SMTP Port" msgstr "SMTP port" -#: cps/templates/admin.html:73 cps/templates/email_edit.html:39 +#: cps/templates/admin.html:75 cps/templates/email_edit.html:39 msgid "Encryption" msgstr "Šifrování" -#: cps/templates/admin.html:77 cps/templates/email_edit.html:47 +#: cps/templates/admin.html:79 cps/templates/email_edit.html:47 msgid "SMTP Login" msgstr "SMTP přihlášení" -#: cps/templates/admin.html:81 cps/templates/admin.html:92 +#: cps/templates/admin.html:83 cps/templates/admin.html:94 #: cps/templates/email_edit.html:55 msgid "From E-mail" msgstr "Z e-mailu" -#: cps/templates/admin.html:88 +#: cps/templates/admin.html:90 msgid "E-Mail Service" msgstr "" -#: cps/templates/admin.html:89 +#: cps/templates/admin.html:91 msgid "Gmail via Oauth2" msgstr "" -#: cps/templates/admin.html:104 +#: cps/templates/admin.html:106 msgid "Configuration" msgstr "Konfigurace" -#: cps/templates/admin.html:107 +#: cps/templates/admin.html:109 msgid "Calibre Database Directory" msgstr "Calibre DB adresář" -#: cps/templates/admin.html:111 cps/templates/config_edit.html:68 +#: cps/templates/admin.html:113 cps/templates/config_edit.html:68 msgid "Log Level" msgstr "Úroveň logu" -#: cps/templates/admin.html:115 +#: cps/templates/admin.html:117 msgid "Port" msgstr "Port" -#: cps/templates/admin.html:120 +#: cps/templates/admin.html:122 msgid "External Port" msgstr "" -#: cps/templates/admin.html:127 cps/templates/config_view_edit.html:28 +#: cps/templates/admin.html:129 cps/templates/config_view_edit.html:28 msgid "Books per Page" msgstr "Knihy na stránku" -#: cps/templates/admin.html:131 +#: cps/templates/admin.html:133 msgid "Uploads" msgstr "Nahrávání" -#: cps/templates/admin.html:135 +#: cps/templates/admin.html:137 msgid "Anonymous Browsing" msgstr "Anonymní prohlížení" -#: cps/templates/admin.html:139 +#: cps/templates/admin.html:141 msgid "Public Registration" msgstr "Veřejná registrace" -#: cps/templates/admin.html:143 +#: cps/templates/admin.html:145 msgid "Magic Link Remote Login" msgstr "Magic Link vzdálené přihlášení" -#: cps/templates/admin.html:147 +#: cps/templates/admin.html:149 msgid "Reverse Proxy Login" msgstr "Reverzní proxy přihlášení" -#: cps/templates/admin.html:152 cps/templates/config_edit.html:173 +#: cps/templates/admin.html:154 cps/templates/config_edit.html:173 msgid "Reverse Proxy Header Name" msgstr "Název záhlaví reverzního proxy" -#: cps/templates/admin.html:157 +#: cps/templates/admin.html:159 #, fuzzy msgid "Edit Calibre Database Configuration" msgstr "Upravit základní konfiguraci" -#: cps/templates/admin.html:158 +#: cps/templates/admin.html:160 msgid "Edit Basic Configuration" msgstr "Upravit základní konfiguraci" -#: cps/templates/admin.html:159 +#: cps/templates/admin.html:161 msgid "Edit UI Configuration" msgstr "Upravit konfiguraci uživatelského rozhraní" -#: cps/templates/admin.html:164 +#: cps/templates/admin.html:166 msgid "Administration" msgstr "Správa" -#: cps/templates/admin.html:165 +#: cps/templates/admin.html:167 msgid "Download Debug Package" msgstr "" -#: cps/templates/admin.html:166 +#: cps/templates/admin.html:168 msgid "View Logs" msgstr "Zobrazit log" -#: cps/templates/admin.html:169 +#: cps/templates/admin.html:171 msgid "Reconnect Calibre Database" msgstr "Znovupřipojení ke Calibre databázi" -#: cps/templates/admin.html:170 +#: cps/templates/admin.html:172 msgid "Restart" msgstr "Restartovat" -#: cps/templates/admin.html:171 +#: cps/templates/admin.html:173 msgid "Shutdown" msgstr "Vypnout" -#: cps/templates/admin.html:176 +#: cps/templates/admin.html:178 msgid "Update" msgstr "Aktualizovat" -#: cps/templates/admin.html:180 +#: cps/templates/admin.html:182 msgid "Version" msgstr "Verze" -#: cps/templates/admin.html:181 +#: cps/templates/admin.html:183 msgid "Details" msgstr "Detaily" -#: cps/templates/admin.html:187 +#: cps/templates/admin.html:189 msgid "Current version" msgstr "Současná verze" -#: cps/templates/admin.html:194 +#: cps/templates/admin.html:196 msgid "Check for Update" msgstr "Zkontrolovat aktualizace" -#: cps/templates/admin.html:195 +#: cps/templates/admin.html:197 msgid "Perform Update" msgstr "Provést aktualizaci" -#: cps/templates/admin.html:208 +#: cps/templates/admin.html:210 msgid "Are you sure you want to restart?" msgstr "Opravdu chcete restartovat?" -#: cps/templates/admin.html:213 cps/templates/admin.html:227 -#: cps/templates/admin.html:247 cps/templates/config_db.html:70 +#: cps/templates/admin.html:215 cps/templates/admin.html:229 +#: cps/templates/admin.html:249 cps/templates/config_db.html:70 msgid "OK" msgstr "OK" -#: cps/templates/admin.html:214 cps/templates/admin.html:228 -#: cps/templates/book_edit.html:213 cps/templates/book_table.html:124 +#: cps/templates/admin.html:216 cps/templates/admin.html:230 +#: cps/templates/book_edit.html:213 cps/templates/book_table.html:127 #: cps/templates/config_db.html:54 cps/templates/config_edit.html:359 -#: cps/templates/config_view_edit.html:173 cps/templates/modal_dialogs.html:64 +#: cps/templates/config_view_edit.html:175 cps/templates/modal_dialogs.html:64 #: cps/templates/modal_dialogs.html:99 cps/templates/modal_dialogs.html:117 #: cps/templates/modal_dialogs.html:135 cps/templates/shelf_edit.html:27 #: cps/templates/user_edit.html:144 msgid "Cancel" msgstr "Zrušit" -#: cps/templates/admin.html:226 +#: cps/templates/admin.html:228 msgid "Are you sure you want to shutdown?" msgstr "Opravdu chcete vypnout?" -#: cps/templates/admin.html:238 +#: cps/templates/admin.html:240 msgid "Updating, please do not reload this page" msgstr "Probíhá aktualizace, prosím nenačítejte stránku znovu" @@ -1601,44 +1625,43 @@ msgstr "přes" msgid "In Library" msgstr "V knihovně" -#: cps/templates/author.html:26 cps/templates/index.html:72 -#: cps/templates/search.html:29 cps/templates/shelf.html:19 +#: cps/templates/author.html:26 cps/templates/index.html:73 +#: cps/templates/search.html:30 cps/templates/shelf.html:19 msgid "Sort according to book date, newest first" msgstr "" -#: cps/templates/author.html:27 cps/templates/index.html:73 -#: cps/templates/search.html:30 cps/templates/shelf.html:20 +#: cps/templates/author.html:27 cps/templates/index.html:74 +#: cps/templates/search.html:31 cps/templates/shelf.html:20 msgid "Sort according to book date, oldest first" msgstr "" -#: cps/templates/author.html:28 cps/templates/index.html:74 -#: cps/templates/search.html:31 cps/templates/shelf.html:21 +#: cps/templates/author.html:28 cps/templates/index.html:75 +#: cps/templates/search.html:32 cps/templates/shelf.html:21 msgid "Sort title in alphabetical order" msgstr "" -#: cps/templates/author.html:29 cps/templates/index.html:75 -#: cps/templates/search.html:32 cps/templates/shelf.html:22 +#: cps/templates/author.html:29 cps/templates/index.html:76 +#: cps/templates/search.html:33 cps/templates/shelf.html:22 msgid "Sort title in reverse alphabetical order" msgstr "" -#: cps/templates/author.html:30 cps/templates/index.html:78 -#: cps/templates/search.html:35 cps/templates/shelf.html:25 +#: cps/templates/author.html:30 cps/templates/index.html:79 +#: cps/templates/search.html:36 cps/templates/shelf.html:25 msgid "Sort according to publishing date, newest first" msgstr "" -#: cps/templates/author.html:31 cps/templates/index.html:79 -#: cps/templates/search.html:36 cps/templates/shelf.html:26 +#: cps/templates/author.html:31 cps/templates/index.html:80 +#: cps/templates/search.html:37 cps/templates/shelf.html:26 msgid "Sort according to publishing date, oldest first" msgstr "" -#: cps/templates/author.html:57 cps/templates/author.html:117 -#: cps/templates/discover.html:30 cps/templates/index.html:29 -#: cps/templates/index.html:111 cps/templates/search.html:65 -#: cps/templates/shelf.html:54 +#: cps/templates/author.html:56 cps/templates/author.html:115 +#: cps/templates/index.html:29 cps/templates/index.html:112 +#: cps/templates/search.html:66 cps/templates/shelf.html:54 msgid "reduce" msgstr "redukovat" -#: cps/templates/author.html:101 +#: cps/templates/author.html:99 msgid "More by" msgstr "Více od" @@ -1763,7 +1786,7 @@ msgid "Fetch Metadata" msgstr "Získat metadata" #: cps/templates/book_edit.html:212 cps/templates/config_db.html:53 -#: cps/templates/config_edit.html:358 cps/templates/config_view_edit.html:172 +#: cps/templates/config_edit.html:358 cps/templates/config_view_edit.html:174 #: cps/templates/email_edit.html:65 cps/templates/shelf_edit.html:25 #: cps/templates/shelf_order.html:41 cps/templates/user_edit.html:142 msgid "Save" @@ -1892,27 +1915,35 @@ msgstr "Zadejte jméno domény" msgid "Comments" msgstr "" -#: cps/templates/book_table.html:77 cps/templates/book_table.html:79 -#: cps/templates/book_table.html:81 cps/templates/book_table.html:83 -#: cps/templates/book_table.html:87 cps/templates/book_table.html:89 -#: cps/templates/book_table.html:91 cps/templates/book_table.html:93 +#: cps/templates/book_table.html:75 +msgid "Archiv Status" +msgstr "" + +#: cps/templates/book_table.html:77 cps/templates/search_form.html:42 +msgid "Read Status" +msgstr "" + +#: cps/templates/book_table.html:80 cps/templates/book_table.html:82 +#: cps/templates/book_table.html:84 cps/templates/book_table.html:86 +#: cps/templates/book_table.html:90 cps/templates/book_table.html:92 +#: cps/templates/book_table.html:96 #, fuzzy msgid "Enter " msgstr "Identifikátory" -#: cps/templates/book_table.html:110 cps/templates/modal_dialogs.html:46 +#: cps/templates/book_table.html:113 cps/templates/modal_dialogs.html:46 msgid "Are you really sure?" msgstr "Jste si opravdu jisti?" -#: cps/templates/book_table.html:114 +#: cps/templates/book_table.html:117 msgid "Books with Title will be merged from:" msgstr "" -#: cps/templates/book_table.html:118 +#: cps/templates/book_table.html:121 msgid "Into Book with Title:" msgstr "" -#: cps/templates/book_table.html:123 +#: cps/templates/book_table.html:126 msgid "Merge" msgstr "" @@ -2089,11 +2120,6 @@ msgstr "LDAP Server Port" msgid "LDAP Encryption" msgstr "LDAP Šifrování" -#: cps/templates/config_edit.html:204 cps/templates/config_view_edit.html:62 -#: cps/templates/email_edit.html:41 -msgid "None" -msgstr "Žádné" - #: cps/templates/config_edit.html:205 msgid "TLS" msgstr "TLS" @@ -2312,11 +2338,11 @@ msgstr "Výchozí zobrazení pro nové uživatele" msgid "Show Random Books in Detail View" msgstr "Zobrazit náhodné knihy v podrobném zobrazení" -#: cps/templates/config_view_edit.html:165 cps/templates/user_edit.html:87 +#: cps/templates/config_view_edit.html:166 cps/templates/user_edit.html:87 msgid "Add Allowed/Denied Tags" msgstr "Přidat povolené/zakázané štítky" -#: cps/templates/config_view_edit.html:166 +#: cps/templates/config_view_edit.html:167 msgid "Add Allowed/Denied custom column values" msgstr "Přidat povolené/zakázané hodnoty vlastních sloupců" @@ -2365,13 +2391,13 @@ msgstr "Archivováno" msgid "Description:" msgstr "Popis:" -#: cps/templates/detail.html:256 cps/templates/search.html:14 +#: cps/templates/detail.html:256 cps/templates/search.html:15 msgid "Add to shelf" msgstr "Přidat do police" #: cps/templates/detail.html:267 cps/templates/detail.html:284 #: cps/templates/feed.xml:79 cps/templates/layout.html:137 -#: cps/templates/search.html:20 +#: cps/templates/search.html:21 msgid "(Public)" msgstr "(Veřejné)" @@ -2449,10 +2475,15 @@ msgstr "Zakázané domény pro registraci" msgid "Next" msgstr "Další" -#: cps/templates/generate_kobo_auth_url.html:5 +#: cps/templates/generate_kobo_auth_url.html:6 msgid "Open the .kobo/Kobo eReader.conf file in a text editor and add (or edit):" msgstr "Otevřte soubor .kobo/Kobo eReader.conf v textovém editoru a vložte (nebo upravte):" +#: cps/templates/generate_kobo_auth_url.html:11 +#, fuzzy +msgid "Kobo Token:" +msgstr "Kobo Sync token" + #: cps/templates/http_error.html:31 #, fuzzy msgid "Calibre-Web Instance is unconfigured, please contact your administrator" @@ -2470,29 +2501,29 @@ msgstr "Zpět domů" msgid "Logout User" msgstr "" -#: cps/templates/index.html:69 +#: cps/templates/index.html:70 msgid "Sort ascending according to download count" msgstr "" -#: cps/templates/index.html:70 +#: cps/templates/index.html:71 msgid "Sort descending according to download count" msgstr "" -#: cps/templates/index.html:76 cps/templates/search.html:33 +#: cps/templates/index.html:77 cps/templates/search.html:34 #: cps/templates/shelf.html:23 msgid "Sort authors in alphabetical order" msgstr "" -#: cps/templates/index.html:77 cps/templates/search.html:34 +#: cps/templates/index.html:78 cps/templates/search.html:35 #: cps/templates/shelf.html:24 msgid "Sort authors in reverse alphabetical order" msgstr "" -#: cps/templates/index.html:81 +#: cps/templates/index.html:82 msgid "Sort ascending according to series index" msgstr "" -#: cps/templates/index.html:82 +#: cps/templates/index.html:83 msgid "Sort descending according to series index" msgstr "" @@ -2928,10 +2959,6 @@ msgstr "Datum vydání od" msgid "Published Date To" msgstr "Datum vydání do" -#: cps/templates/search_form.html:42 -msgid "Read Status" -msgstr "" - #: cps/templates/search_form.html:59 msgid "Exclude Tags" msgstr "Vynechat štítky" diff --git a/cps/translations/de/LC_MESSAGES/messages.mo b/cps/translations/de/LC_MESSAGES/messages.mo index b53a9c59..9095d5bb 100644 Binary files a/cps/translations/de/LC_MESSAGES/messages.mo and b/cps/translations/de/LC_MESSAGES/messages.mo differ diff --git a/cps/translations/de/LC_MESSAGES/messages.po b/cps/translations/de/LC_MESSAGES/messages.po index 7112ce22..5aba0fe8 100644 --- a/cps/translations/de/LC_MESSAGES/messages.po +++ b/cps/translations/de/LC_MESSAGES/messages.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Calibre-Web\n" "Report-Msgid-Bugs-To: https://github.com/janeczku/Calibre-Web\n" -"POT-Creation-Date: 2022-01-15 09:19+0100\n" +"POT-Creation-Date: 2022-04-18 20:01+0200\n" "PO-Revision-Date: 2022-01-10 17:37+0100\n" "Last-Translator: Ozzie Isaacs\n" "Language: de\n" @@ -16,578 +16,581 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.9.0\n" +"Generated-By: Babel 2.9.1\n" -#: cps/about.py:34 cps/about.py:49 cps/about.py:65 cps/converter.py:31 -msgid "not installed" -msgstr "Nicht installiert" - -#: cps/about.py:47 cps/about.py:63 -msgid "installed" -msgstr "Installiert" - -#: cps/about.py:145 +#: cps/about.py:86 msgid "Statistics" msgstr "Statistiken" -#: cps/admin.py:144 +#: cps/admin.py:141 msgid "Server restarted, please reload page" msgstr "Server neu gestartet, Seite bitte neu laden" -#: cps/admin.py:146 +#: cps/admin.py:143 msgid "Performing shutdown of server, please close window" msgstr "Server wird heruntergefahren, Fenster bitte schließen" -#: cps/admin.py:154 +#: cps/admin.py:151 msgid "Reconnect successful" msgstr "Erfolgreich neu verbunden" -#: cps/admin.py:157 +#: cps/admin.py:154 msgid "Unknown command" msgstr "Unbekannter Befehl" -#: cps/admin.py:167 cps/editbooks.py:707 cps/editbooks.py:721 -#: cps/editbooks.py:866 cps/editbooks.py:868 cps/editbooks.py:895 -#: cps/editbooks.py:911 cps/updater.py:584 cps/uploader.py:93 -#: cps/uploader.py:103 +#: cps/admin.py:176 cps/editbooks.py:713 cps/editbooks.py:892 +#: cps/editbooks.py:894 cps/editbooks.py:930 cps/editbooks.py:947 +#: cps/updater.py:608 cps/uploader.py:93 cps/uploader.py:103 msgid "Unknown" msgstr "Unbekannt" -#: cps/admin.py:188 +#: cps/admin.py:197 msgid "Admin page" msgstr "Admin Seite" -#: cps/admin.py:207 +#: cps/admin.py:217 msgid "Basic Configuration" msgstr "Basiskonfiguration" -#: cps/admin.py:244 +#: cps/admin.py:255 msgid "UI Configuration" msgstr "Benutzeroberflächenkonfiguration" -#: cps/admin.py:277 cps/templates/admin.html:50 +#: cps/admin.py:289 cps/templates/admin.html:51 msgid "Edit Users" msgstr "Benutzer bearbeiten" -#: cps/admin.py:318 cps/opds.py:109 cps/opds.py:198 cps/opds.py:275 -#: cps/opds.py:327 cps/templates/grid.html:13 cps/templates/languages.html:9 +#: cps/admin.py:333 cps/opds.py:529 cps/templates/grid.html:13 #: cps/templates/list.html:13 msgid "All" msgstr "Alle" -#: cps/admin.py:343 cps/admin.py:1615 +#: cps/admin.py:360 cps/admin.py:1648 msgid "User not found" msgstr "Benutzer nicht gefunden" -#: cps/admin.py:357 +#: cps/admin.py:374 msgid "{} users deleted successfully" msgstr "{} Benutzer erfolgreich gelöscht" -#: cps/admin.py:379 cps/templates/config_view_edit.html:133 +#: cps/admin.py:397 cps/templates/config_view_edit.html:133 #: cps/templates/user_edit.html:45 cps/templates/user_table.html:81 msgid "Show All" msgstr "Zeige alle" -#: cps/admin.py:400 cps/admin.py:406 +#: cps/admin.py:418 cps/admin.py:424 msgid "Malformed request" msgstr "Ungültige Anfrage" -#: cps/admin.py:418 cps/admin.py:1493 +#: cps/admin.py:436 cps/admin.py:1526 msgid "Guest Name can't be changed" msgstr "Guest Name kann nicht geändert werden" -#: cps/admin.py:430 +#: cps/admin.py:448 msgid "Guest can't have this role" msgstr "Guest Benutzer kann diese Rolle nicht haben" -#: cps/admin.py:442 cps/admin.py:1451 +#: cps/admin.py:460 cps/admin.py:1484 msgid "No admin user remaining, can't remove admin role" msgstr "Kein Admin Benutzer verblieben Admin Berechtigung kann nicht entfernt werden" -#: cps/admin.py:446 cps/admin.py:460 +#: cps/admin.py:464 cps/admin.py:478 msgid "Value has to be true or false" msgstr "Wert muss true oder false sein" -#: cps/admin.py:448 +#: cps/admin.py:466 msgid "Invalid role" msgstr "Ungültige Rolle" -#: cps/admin.py:452 +#: cps/admin.py:470 msgid "Guest can't have this view" msgstr "Guest Benutzer kann diese Sichtbarkeit nicht haben" -#: cps/admin.py:462 +#: cps/admin.py:480 msgid "Invalid view" msgstr "Ungültige Sichtbarkeit" -#: cps/admin.py:465 +#: cps/admin.py:483 msgid "Guest's Locale is determined automatically and can't be set" msgstr "Guest Sprache wird automatisch bestimmt und kann nicht eingestellt werden" -#: cps/admin.py:469 +#: cps/admin.py:487 msgid "No Valid Locale Given" msgstr "Keine gültige Sprache gewählt" -#: cps/admin.py:480 +#: cps/admin.py:498 msgid "No Valid Book Language Given" msgstr "Keine gültige Buchsprache gewählt" -#: cps/admin.py:482 +#: cps/admin.py:500 cps/editbooks.py:1267 msgid "Parameter not found" msgstr "Parameter wurde nicht gefunden" -#: cps/admin.py:533 +#: cps/admin.py:553 msgid "Invalid Read Column" msgstr "Ungültige Lese Spalte" -#: cps/admin.py:539 +#: cps/admin.py:559 msgid "Invalid Restricted Column" msgstr "Ungültiger Spaltenname für Einschränkung" -#: cps/admin.py:560 cps/admin.py:1323 +#: cps/admin.py:579 cps/admin.py:1355 msgid "Calibre-Web configuration updated" msgstr "Konfiguration von Calibre-Web wurde aktualisiert" -#: cps/admin.py:572 +#: cps/admin.py:591 msgid "Do you really want to delete the Kobo Token?" msgstr "Möchten Sie wirklich den Kobo Token löschen?" -#: cps/admin.py:574 +#: cps/admin.py:593 msgid "Do you really want to delete this domain?" msgstr "Möchten Sie wirklich diese Domain löschen?" -#: cps/admin.py:576 +#: cps/admin.py:595 msgid "Do you really want to delete this user?" msgstr "Möchten Sie wirklich diesen Benutzer löschen?" -#: cps/admin.py:578 +#: cps/admin.py:597 msgid "Are you sure you want to delete this shelf?" msgstr "Möchten Sie wirklich dieses Bücherregal löschen?" -#: cps/admin.py:580 +#: cps/admin.py:599 msgid "Are you sure you want to change locales of selected user(s)?" msgstr "Möchten Sie wirklich die Anzeigesprache der ausgewählten Benutzer ändern?" -#: cps/admin.py:582 +#: cps/admin.py:601 msgid "Are you sure you want to change visible book languages for selected user(s)?" msgstr "Möchten Sie wirklich die Büchersprachen für die ausgewählten Benutzer ändern?" -#: cps/admin.py:584 +#: cps/admin.py:603 msgid "Are you sure you want to change the selected role for the selected user(s)?" msgstr "Möchten Sie wirklich die ausgewählte Rolle für die ausgewählten Benutzer verändern?" -#: cps/admin.py:586 +#: cps/admin.py:605 msgid "Are you sure you want to change the selected restrictions for the selected user(s)?" msgstr "Möchten Sie wirklich die ausgewählten Sichtbarkeitsbeschränkungen der ausgewählten Benutzer ändern?" -#: cps/admin.py:588 +#: cps/admin.py:607 msgid "Are you sure you want to change the selected visibility restrictions for the selected user(s)?" msgstr "Möchten Sie wirklich die Sichtbarkeiten für die ausgewählten Benutzer verändern?" -#: cps/admin.py:590 +#: cps/admin.py:610 msgid "Are you sure you want to change shelf sync behavior for the selected user(s)?" msgstr "Möchten Sie wirklich die Synchronisation von Bücherregalen für die ausgewählten Benutzer verändern?" -#: cps/admin.py:592 +#: cps/admin.py:612 msgid "Are you sure you want to change Calibre library location?" msgstr "Ort der Calibre Datenbank editieren?" -#: cps/admin.py:594 +#: cps/admin.py:614 msgid "Are you sure you want delete Calibre-Web's sync database to force a full sync with your Kobo Reader?" msgstr "Möchten Sie wirklich die Synchronisationsdatenbank von Calibre-Web löschen, um eine komplette Synchronisation zu erzwingen?" -#: cps/admin.py:743 +#: cps/admin.py:764 msgid "Tag not found" msgstr "Tag nicht gefunden" -#: cps/admin.py:755 +#: cps/admin.py:776 msgid "Invalid Action" msgstr "Ungültige Aktion" -#: cps/admin.py:871 cps/admin.py:877 cps/admin.py:887 cps/admin.py:897 +#: cps/admin.py:893 cps/admin.py:899 cps/admin.py:909 cps/admin.py:919 #: cps/templates/modal_dialogs.html:29 cps/templates/user_table.html:41 #: cps/templates/user_table.html:58 msgid "Deny" msgstr "Verbieten" -#: cps/admin.py:873 cps/admin.py:879 cps/admin.py:889 cps/admin.py:899 +#: cps/admin.py:895 cps/admin.py:901 cps/admin.py:911 cps/admin.py:921 #: cps/templates/modal_dialogs.html:28 cps/templates/user_table.html:44 #: cps/templates/user_table.html:61 msgid "Allow" msgstr "Erlauben" -#: cps/admin.py:913 +#: cps/admin.py:936 msgid "{} sync entries deleted" msgstr "{} Synchronisationseinträge gelöscht" -#: cps/admin.py:1036 +#: cps/admin.py:1059 msgid "client_secrets.json Is Not Configured For Web Application" msgstr "client_secrets.json ist nicht für Web Anwendungen konfiguriert" -#: cps/admin.py:1081 +#: cps/admin.py:1104 msgid "Logfile Location is not Valid, Please Enter Correct Path" msgstr "Logdatei Pfad ist ungültig, bitte einen gültigen Pfad angeben" -#: cps/admin.py:1087 +#: cps/admin.py:1110 msgid "Access Logfile Location is not Valid, Please Enter Correct Path" msgstr "Zugriffs Logdatei Pfad ist ungültig, bitte einen gültigen Pfad angeben" -#: cps/admin.py:1117 +#: cps/admin.py:1140 msgid "Please Enter a LDAP Provider, Port, DN and User Object Identifier" msgstr "Bitte einen LDAP Server, Port, DN und Benutzer Objekt angeben" -#: cps/admin.py:1123 +#: cps/admin.py:1146 msgid "Please Enter a LDAP Service Account and Password" msgstr "Bitte einen LDAP Service Account und Password eingeben" -#: cps/admin.py:1126 +#: cps/admin.py:1149 msgid "Please Enter a LDAP Service Account" msgstr "Bitte einen LDAP Service Account eingeben" -#: cps/admin.py:1131 +#: cps/admin.py:1154 #, python-format msgid "LDAP Group Object Filter Needs to Have One \"%s\" Format Identifier" msgstr "LDAP Gruppen Objekt Filter benötigt genau eine \"%s\" Format Kennung" -#: cps/admin.py:1133 +#: cps/admin.py:1156 msgid "LDAP Group Object Filter Has Unmatched Parenthesis" msgstr "LDAP Gruppen Objekt Filter hat ungleiche Anzahl von Klammern" -#: cps/admin.py:1137 +#: cps/admin.py:1160 #, python-format msgid "LDAP User Object Filter needs to Have One \"%s\" Format Identifier" msgstr "LDAP Benutzer Objekt Filter benötigt genau eine \"%s\" Format Kennung" -#: cps/admin.py:1139 +#: cps/admin.py:1162 msgid "LDAP User Object Filter Has Unmatched Parenthesis" msgstr "LDAP Benutzer Objekt Filter hat ungleiche Anzahl von Klammern" -#: cps/admin.py:1146 +#: cps/admin.py:1169 #, python-format msgid "LDAP Member User Filter needs to Have One \"%s\" Format Identifier" msgstr "Der LDAP Member User Filter benötigt genau eine \"%s\" Formatierungsmarkierung" -#: cps/admin.py:1148 +#: cps/admin.py:1171 msgid "LDAP Member User Filter Has Unmatched Parenthesis" msgstr "LDAP Member User Filter hat eine ungleiche Anzahl von geöffneten und geschlossenen Klammern" -#: cps/admin.py:1155 +#: cps/admin.py:1178 msgid "LDAP CACertificate, Certificate or Key Location is not Valid, Please Enter Correct Path" msgstr "LDAP CA-Zertifikat, Zertifikat oder Key Datei ist kein gültiger Pfad" -#: cps/admin.py:1197 cps/admin.py:1308 cps/admin.py:1405 cps/admin.py:1521 -#: cps/admin.py:1590 cps/shelf.py:100 cps/shelf.py:160 cps/shelf.py:203 -#: cps/shelf.py:279 cps/shelf.py:341 cps/shelf.py:376 cps/shelf.py:451 -msgid "Settings DB is not Writeable" -msgstr "Einstellungsdatenbank ist nicht schreibbar" - -#: cps/admin.py:1208 -msgid "DB Location is not Valid, Please Enter Correct Path" -msgstr "DB Pfad ist nicht gültig, bitte einen gültigen Pfad angeben" - -#: cps/admin.py:1223 -msgid "DB is not Writeable" -msgstr "Datenbank ist nicht schreibbar" - -#: cps/admin.py:1235 -msgid "Keyfile Location is not Valid, Please Enter Correct Path" -msgstr "Schlüsseldatei ist ungültig, bitte einen gültigen Pfad angeben" - -#: cps/admin.py:1239 -msgid "Certfile Location is not Valid, Please Enter Correct Path" -msgstr "Zertifikatsdatei ist ungültig, bitte einen gültigen Pfad angeben" - -#: cps/admin.py:1346 -msgid "Database Settings updated" -msgstr "Datenbankeinstellung aktualisiert" - -#: cps/admin.py:1354 -msgid "Database Configuration" -msgstr "Datenbank-Konfiguration" - -#: cps/admin.py:1370 cps/web.py:1479 -msgid "Please fill out all fields!" -msgstr "Bitte alle Felder ausfüllen!" - -#: cps/admin.py:1378 -msgid "E-mail is not from valid domain" -msgstr "E-Mail bezieht sich nicht auf eine gültige Domain" - -#: cps/admin.py:1384 cps/admin.py:1543 -msgid "Add new user" -msgstr "Neuen Benutzer hinzufügen" - -#: cps/admin.py:1395 -#, python-format -msgid "User '%(user)s' created" -msgstr "Benutzer '%(user)s' angelegt" - -#: cps/admin.py:1401 -msgid "Found an existing account for this e-mail address or name." -msgstr "Es existiert bereits ein Account für diese E-Mailadresse oder diesen Benutzernamen." - -#: cps/admin.py:1430 -#, python-format -msgid "User '%(nick)s' deleted" -msgstr "Benutzer '%(nick)s' gelöscht" - -#: cps/admin.py:1432 cps/admin.py:1433 -msgid "Can't delete Guest User" -msgstr "Guest Benutzer kann nicht gelöscht werden" - -#: cps/admin.py:1436 -msgid "No admin user remaining, can't delete user" -msgstr "Benutzer kann nicht gelöscht werden, es wäre kein Admin Benutzer übrig" - -#: cps/admin.py:1509 cps/admin.py:1634 -#, python-format -msgid "Edit User %(nick)s" -msgstr "Benutzer %(nick)s bearbeiten" - -#: cps/admin.py:1513 -#, python-format -msgid "User '%(nick)s' updated" -msgstr "Benutzer '%(nick)s' aktualisiert" - -#: cps/admin.py:1517 cps/admin.py:1649 cps/web.py:1504 cps/web.py:1564 -msgid "An unknown error occurred. Please try again later." -msgstr "Es ist ein unbekannter Fehler aufgetreten. Bitte später erneut versuchen." - -#: cps/admin.py:1552 cps/templates/admin.html:98 -msgid "Edit E-mail Server Settings" -msgstr "SMTP-Einstellungen ändern" - -#: cps/admin.py:1571 -msgid "Gmail Account Verification Successful" -msgstr "Gmail Account Verifikation erfolgreich" - -#: cps/admin.py:1597 -#, python-format -msgid "Test e-mail queued for sending to %(email)s, please check Tasks for result" -msgstr "Test E-Mail an %(email)s wurde zum Senden in die Warteschlange eingereiht, für das Ergebnis bitte Aufgaben überprüfen" - -#: cps/admin.py:1600 -#, python-format -msgid "There was an error sending the Test e-mail: %(res)s" -msgstr "Es trat ein Fehler beim Versenden der Test-E-Mail auf: %(res)s" - -#: cps/admin.py:1602 -msgid "Please configure your e-mail address first..." -msgstr "Bitte zuerst E-Mail Adresse konfigurieren..." - -#: cps/admin.py:1604 -msgid "E-mail server settings updated" -msgstr "Einstellungen des E-Mail-Servers aktualisiert" - -#: cps/admin.py:1646 -#, python-format -msgid "Password for user %(user)s reset" -msgstr "Passwort für Benutzer %(user)s wurde zurückgesetzt" - -#: cps/admin.py:1652 cps/web.py:1444 -msgid "Please configure the SMTP mail settings first..." -msgstr "Bitte zuerst die SMTP-Einstellung konfigurieren ..." - -#: cps/admin.py:1663 -msgid "Logfile viewer" -msgstr "Logdatei Anzeige" - -#: cps/admin.py:1729 -msgid "Requesting update package" -msgstr "Frage Update an" - -#: cps/admin.py:1730 -msgid "Downloading update package" -msgstr "Lade Update herunter" - -#: cps/admin.py:1731 -msgid "Unzipping update package" -msgstr "Entpacke Update" - -#: cps/admin.py:1732 -msgid "Replacing files" -msgstr "Ersetze Dateien" - -#: cps/admin.py:1733 -msgid "Database connections are closed" -msgstr "Schließe Datenbankverbindungen" - -#: cps/admin.py:1734 -msgid "Stopping server" -msgstr "Stoppe Server" - -#: cps/admin.py:1735 -msgid "Update finished, please press okay and reload page" -msgstr "Update abgeschlossen, bitte okay drücken und Seite neu laden" - -#: cps/admin.py:1736 cps/admin.py:1737 cps/admin.py:1738 cps/admin.py:1739 -#: cps/admin.py:1740 cps/admin.py:1741 -msgid "Update failed:" -msgstr "Update fehlgeschlagen:" - -#: cps/admin.py:1736 cps/updater.py:385 cps/updater.py:595 cps/updater.py:597 -msgid "HTTP Error" -msgstr "HTTP Fehler" - -#: cps/admin.py:1737 cps/updater.py:387 cps/updater.py:599 -msgid "Connection error" -msgstr "Verbindungsfehler" - -#: cps/admin.py:1738 cps/updater.py:389 cps/updater.py:601 -msgid "Timeout while establishing connection" -msgstr "Timeout beim Verbindungsaufbau" - -#: cps/admin.py:1739 cps/updater.py:391 cps/updater.py:603 -msgid "General error" -msgstr "Allgemeiner Fehler" - -#: cps/admin.py:1740 -msgid "Update file could not be saved in temp dir" -msgstr "Updatedatei konnte nicht in Temporärem Ordner gespeichert werden" - -#: cps/admin.py:1741 -msgid "Files could not be replaced during update" -msgstr "Dateien konnten während des Updates nicht ausgetauscht werden" - -#: cps/admin.py:1765 -msgid "Failed to extract at least One LDAP User" -msgstr "Mindestens ein LDAP Benutzer konnte nicht extrahiert werden" - -#: cps/admin.py:1810 -msgid "Failed to Create at Least One LDAP User" -msgstr "Mindestens ein LDAP Benutzer konnte nicht erzeugt werden" - -#: cps/admin.py:1823 -#, python-format -msgid "Error: %(ldaperror)s" -msgstr "Fehler: %(ldaperror)s" - -#: cps/admin.py:1827 -msgid "Error: No user returned in response of LDAP server" -msgstr "Fehler: Keine Benutzerinformationen von LDAP Server empfangen" - -#: cps/admin.py:1860 -msgid "At Least One LDAP User Not Found in Database" -msgstr "Mindestens ein LDAP Benutzer wurde nicht in der Datenbank gefudnen" - -#: cps/admin.py:1862 -msgid "{} User Successfully Imported" -msgstr "{} Benutzer erfolgreich importiert" - -#: cps/converter.py:30 -msgid "not configured" -msgstr "Nicht konfiguriert" - -#: cps/converter.py:32 -msgid "Execution permissions missing" -msgstr "Ausführeberechtigung fehlt" - -#: cps/db.py:651 cps/web.py:667 cps/web.py:1155 -#, python-format -msgid "Custom Column No.%(column)d is not existing in calibre database" -msgstr "Benutzerdefinierte Spalte Nr. %(column)d ist nicht in Calibre Datenbank vorhanden" - -#: cps/editbooks.py:300 cps/editbooks.py:302 -msgid "Book Format Successfully Deleted" -msgstr "Buch Format erfolgreich gelöscht" - -#: cps/editbooks.py:309 cps/editbooks.py:311 -msgid "Book Successfully Deleted" -msgstr "Buch erfolgreich gelöscht" - -#: cps/editbooks.py:361 -msgid "You are missing permissions to delete books" -msgstr "Keine Erlaubnis zum Bücher löschen" - -#: cps/editbooks.py:376 cps/editbooks.py:763 cps/web.py:523 cps/web.py:1703 -#: cps/web.py:1744 cps/web.py:1811 -msgid "Oops! Selected book title is unavailable. File does not exist or is not accessible" -msgstr "Öffnen des Buchs fehlgeschlagen. Datei existiert nicht oder ist nicht zugänglich" - -#: cps/editbooks.py:410 -msgid "edit metadata" -msgstr "Metadaten editieren" - -#: cps/editbooks.py:458 -#, python-format -msgid "%(seriesindex)s is not a valid number, skipping" -msgstr "%(seriesindex)s ist keine gültige Zahl, Eintrag wird ignoriert" - -#: cps/editbooks.py:494 cps/editbooks.py:958 -#, python-format -msgid "'%(langname)s' is not a valid language" -msgstr "'%(langname)s' ist keine gültige Sprache" - -#: cps/editbooks.py:634 cps/editbooks.py:985 -#, python-format -msgid "File extension '%(ext)s' is not allowed to be uploaded to this server" -msgstr "Dateiendung '%(ext)s' kann nicht auf diesen Server hochgeladen werden" - -#: cps/editbooks.py:638 cps/editbooks.py:989 -msgid "File to be uploaded must have an extension" -msgstr "Dateien müssen eine Erweiterung haben, um hochgeladen zu werden" - -#: cps/editbooks.py:650 -#, python-format -msgid "Failed to create path %(path)s (Permission denied)." -msgstr "Fehler beim Erzeugen des Pfads %(path)s (Zugriff verweigert)" - -#: cps/editbooks.py:655 -#, python-format -msgid "Failed to store file %(file)s." -msgstr "Fehler beim Speichern der Datei %(file)s." - -#: cps/editbooks.py:673 cps/editbooks.py:1076 cps/web.py:1664 +#: cps/admin.py:1223 cps/admin.py:1339 cps/admin.py:1437 cps/admin.py:1554 +#: cps/admin.py:1623 cps/editbooks.py:678 cps/editbooks.py:882 +#: cps/editbooks.py:1130 cps/shelf.py:100 cps/shelf.py:160 cps/shelf.py:203 +#: cps/shelf.py:278 cps/shelf.py:343 cps/shelf.py:380 cps/shelf.py:456 +#: cps/web.py:1742 #, python-format msgid "Database error: %(error)s." msgstr "Datenbankfehler: %(error)s." -#: cps/editbooks.py:678 +#: cps/admin.py:1235 +msgid "DB Location is not Valid, Please Enter Correct Path" +msgstr "DB Pfad ist nicht gültig, bitte einen gültigen Pfad angeben" + +#: cps/admin.py:1253 +msgid "DB is not Writeable" +msgstr "Datenbank ist nicht schreibbar" + +#: cps/admin.py:1266 +msgid "Keyfile Location is not Valid, Please Enter Correct Path" +msgstr "Schlüsseldatei ist ungültig, bitte einen gültigen Pfad angeben" + +#: cps/admin.py:1270 +msgid "Certfile Location is not Valid, Please Enter Correct Path" +msgstr "Zertifikatsdatei ist ungültig, bitte einen gültigen Pfad angeben" + +#: cps/admin.py:1378 +msgid "Database Settings updated" +msgstr "Datenbankeinstellung aktualisiert" + +#: cps/admin.py:1386 +msgid "Database Configuration" +msgstr "Datenbank-Konfiguration" + +#: cps/admin.py:1402 cps/web.py:1557 +msgid "Please fill out all fields!" +msgstr "Bitte alle Felder ausfüllen!" + +#: cps/admin.py:1410 +msgid "E-mail is not from valid domain" +msgstr "E-Mail bezieht sich nicht auf eine gültige Domain" + +#: cps/admin.py:1416 cps/admin.py:1576 +msgid "Add new user" +msgstr "Neuen Benutzer hinzufügen" + +#: cps/admin.py:1427 +#, python-format +msgid "User '%(user)s' created" +msgstr "Benutzer '%(user)s' angelegt" + +#: cps/admin.py:1433 +msgid "Found an existing account for this e-mail address or name." +msgstr "Es existiert bereits ein Account für diese E-Mailadresse oder diesen Benutzernamen." + +#: cps/admin.py:1463 +#, python-format +msgid "User '%(nick)s' deleted" +msgstr "Benutzer '%(nick)s' gelöscht" + +#: cps/admin.py:1465 cps/admin.py:1466 +msgid "Can't delete Guest User" +msgstr "Guest Benutzer kann nicht gelöscht werden" + +#: cps/admin.py:1469 +msgid "No admin user remaining, can't delete user" +msgstr "Benutzer kann nicht gelöscht werden, es wäre kein Admin Benutzer übrig" + +#: cps/admin.py:1542 cps/admin.py:1667 +#, python-format +msgid "Edit User %(nick)s" +msgstr "Benutzer %(nick)s bearbeiten" + +#: cps/admin.py:1546 +#, python-format +msgid "User '%(nick)s' updated" +msgstr "Benutzer '%(nick)s' aktualisiert" + +#: cps/admin.py:1550 cps/admin.py:1682 cps/web.py:1582 cps/web.py:1642 +msgid "An unknown error occurred. Please try again later." +msgstr "Es ist ein unbekannter Fehler aufgetreten. Bitte später erneut versuchen." + +#: cps/admin.py:1585 cps/templates/admin.html:100 +msgid "Edit E-mail Server Settings" +msgstr "SMTP-Einstellungen ändern" + +#: cps/admin.py:1604 +msgid "Gmail Account Verification Successful" +msgstr "Gmail Account Verifikation erfolgreich" + +#: cps/admin.py:1630 +#, python-format +msgid "Test e-mail queued for sending to %(email)s, please check Tasks for result" +msgstr "Test E-Mail an %(email)s wurde zum Senden in die Warteschlange eingereiht, für das Ergebnis bitte Aufgaben überprüfen" + +#: cps/admin.py:1633 +#, python-format +msgid "There was an error sending the Test e-mail: %(res)s" +msgstr "Es trat ein Fehler beim Versenden der Test-E-Mail auf: %(res)s" + +#: cps/admin.py:1635 +msgid "Please configure your e-mail address first..." +msgstr "Bitte zuerst E-Mail Adresse konfigurieren..." + +#: cps/admin.py:1637 +msgid "E-mail server settings updated" +msgstr "Einstellungen des E-Mail-Servers aktualisiert" + +#: cps/admin.py:1679 +#, python-format +msgid "Password for user %(user)s reset" +msgstr "Passwort für Benutzer %(user)s wurde zurückgesetzt" + +#: cps/admin.py:1685 cps/web.py:1522 +msgid "Please configure the SMTP mail settings first..." +msgstr "Bitte zuerst die SMTP-Einstellung konfigurieren ..." + +#: cps/admin.py:1696 +msgid "Logfile viewer" +msgstr "Logdatei Anzeige" + +#: cps/admin.py:1762 +msgid "Requesting update package" +msgstr "Frage Update an" + +#: cps/admin.py:1763 +msgid "Downloading update package" +msgstr "Lade Update herunter" + +#: cps/admin.py:1764 +msgid "Unzipping update package" +msgstr "Entpacke Update" + +#: cps/admin.py:1765 +msgid "Replacing files" +msgstr "Ersetze Dateien" + +#: cps/admin.py:1766 +msgid "Database connections are closed" +msgstr "Schließe Datenbankverbindungen" + +#: cps/admin.py:1767 +msgid "Stopping server" +msgstr "Stoppe Server" + +#: cps/admin.py:1768 +msgid "Update finished, please press okay and reload page" +msgstr "Update abgeschlossen, bitte okay drücken und Seite neu laden" + +#: cps/admin.py:1769 cps/admin.py:1770 cps/admin.py:1771 cps/admin.py:1772 +#: cps/admin.py:1773 cps/admin.py:1774 +msgid "Update failed:" +msgstr "Update fehlgeschlagen:" + +#: cps/admin.py:1769 cps/updater.py:384 cps/updater.py:619 cps/updater.py:621 +msgid "HTTP Error" +msgstr "HTTP Fehler" + +#: cps/admin.py:1770 cps/updater.py:386 cps/updater.py:623 +msgid "Connection error" +msgstr "Verbindungsfehler" + +#: cps/admin.py:1771 cps/updater.py:388 cps/updater.py:625 +msgid "Timeout while establishing connection" +msgstr "Timeout beim Verbindungsaufbau" + +#: cps/admin.py:1772 cps/updater.py:390 cps/updater.py:627 +msgid "General error" +msgstr "Allgemeiner Fehler" + +#: cps/admin.py:1773 +msgid "Update file could not be saved in temp dir" +msgstr "Updatedatei konnte nicht in Temporärem Ordner gespeichert werden" + +#: cps/admin.py:1774 +msgid "Files could not be replaced during update" +msgstr "Dateien konnten während des Updates nicht ausgetauscht werden" + +#: cps/admin.py:1798 +msgid "Failed to extract at least One LDAP User" +msgstr "Mindestens ein LDAP Benutzer konnte nicht extrahiert werden" + +#: cps/admin.py:1843 +msgid "Failed to Create at Least One LDAP User" +msgstr "Mindestens ein LDAP Benutzer konnte nicht erzeugt werden" + +#: cps/admin.py:1856 +#, python-format +msgid "Error: %(ldaperror)s" +msgstr "Fehler: %(ldaperror)s" + +#: cps/admin.py:1860 +msgid "Error: No user returned in response of LDAP server" +msgstr "Fehler: Keine Benutzerinformationen von LDAP Server empfangen" + +#: cps/admin.py:1893 +msgid "At Least One LDAP User Not Found in Database" +msgstr "Mindestens ein LDAP Benutzer wurde nicht in der Datenbank gefudnen" + +#: cps/admin.py:1895 +msgid "{} User Successfully Imported" +msgstr "{} Benutzer erfolgreich importiert" + +#: cps/converter.py:30 +msgid "not installed" +msgstr "Nicht installiert" + +#: cps/converter.py:31 +msgid "Execution permissions missing" +msgstr "Ausführeberechtigung fehlt" + +#: cps/db.py:674 cps/web.py:710 cps/web.py:1222 +#, python-format +msgid "Custom Column No.%(column)d is not existing in calibre database" +msgstr "Benutzerdefinierte Spalte Nr. %(column)d ist nicht in Calibre Datenbank vorhanden" + +#: cps/db.py:917 cps/templates/config_edit.html:204 +#: cps/templates/config_view_edit.html:62 cps/templates/email_edit.html:41 +#: cps/web.py:551 cps/web.py:585 cps/web.py:646 cps/web.py:671 cps/web.py:1003 +#: cps/web.py:1032 cps/web.py:1066 cps/web.py:1093 cps/web.py:1132 +msgid "None" +msgstr "Keine" + +#: cps/editbooks.py:295 cps/editbooks.py:297 +msgid "Book Format Successfully Deleted" +msgstr "Buch Format erfolgreich gelöscht" + +#: cps/editbooks.py:304 cps/editbooks.py:306 +msgid "Book Successfully Deleted" +msgstr "Buch erfolgreich gelöscht" + +#: cps/editbooks.py:358 +msgid "You are missing permissions to delete books" +msgstr "Keine Erlaubnis zum Bücher löschen" + +#: cps/editbooks.py:373 cps/editbooks.py:765 cps/web.py:518 cps/web.py:1783 +#: cps/web.py:1825 cps/web.py:1870 +msgid "Oops! Selected book title is unavailable. File does not exist or is not accessible" +msgstr "Öffnen des Buchs fehlgeschlagen. Datei existiert nicht oder ist nicht zugänglich" + +#: cps/editbooks.py:408 +msgid "edit metadata" +msgstr "Metadaten editieren" + +#: cps/editbooks.py:457 +#, python-format +msgid "%(seriesindex)s is not a valid number, skipping" +msgstr "%(seriesindex)s ist keine gültige Zahl, Eintrag wird ignoriert" + +#: cps/editbooks.py:493 cps/editbooks.py:1001 +#, python-format +msgid "'%(langname)s' is not a valid language" +msgstr "'%(langname)s' ist keine gültige Sprache" + +#: cps/editbooks.py:634 +msgid "User has no rights to upload additional file formats" +msgstr "" + +#: cps/editbooks.py:639 cps/editbooks.py:1029 +#, python-format +msgid "File extension '%(ext)s' is not allowed to be uploaded to this server" +msgstr "Dateiendung '%(ext)s' kann nicht auf diesen Server hochgeladen werden" + +#: cps/editbooks.py:643 cps/editbooks.py:1033 +msgid "File to be uploaded must have an extension" +msgstr "Dateien müssen eine Erweiterung haben, um hochgeladen zu werden" + +#: cps/editbooks.py:655 +#, python-format +msgid "Failed to create path %(path)s (Permission denied)." +msgstr "Fehler beim Erzeugen des Pfads %(path)s (Zugriff verweigert)" + +#: cps/editbooks.py:660 +#, python-format +msgid "Failed to store file %(file)s." +msgstr "Fehler beim Speichern der Datei %(file)s." + +#: cps/editbooks.py:683 #, python-format msgid "File format %(ext)s added to %(book)s" msgstr "Dateiformat %(ext)s zu %(book)s hinzugefügt" -#: cps/editbooks.py:814 +#: cps/editbooks.py:697 cps/editbooks.py:809 +msgid "User has no rights to upload cover" +msgstr "" + +#: cps/editbooks.py:828 msgid "Identifiers are not Case Sensitive, Overwriting Old Identifier" msgstr "IDs unterscheiden nicht Groß-Kleinschreibung, alte ID wird überschrieben" -#: cps/editbooks.py:848 +#: cps/editbooks.py:869 msgid "Metadata successfully updated" msgstr "Metadaten wurden erfolgreich aktualisiert" -#: cps/editbooks.py:861 -msgid "Error editing book, please check logfile for details" -msgstr "Fehler beim Editieren des Buchs, Details im Logfile" +#: cps/editbooks.py:887 +msgid "Error editing book: {}" +msgstr "" -#: cps/editbooks.py:899 +#: cps/editbooks.py:951 msgid "Uploaded book probably exists in the library, consider to change before upload new: " msgstr "Das hochgeladene Buch existiert evtl. schon in der Bibliothek: " -#: cps/editbooks.py:997 +#: cps/editbooks.py:1041 #, python-format msgid "File %(filename)s could not saved to temp dir" msgstr "Die Datei %(filename)s konnte nicht im temporären Ordner gespeichert werden" -#: cps/editbooks.py:1016 +#: cps/editbooks.py:1061 #, python-format msgid "Failed to Move Cover File %(file)s: %(error)s" msgstr "Fehler beim Verschieben der Cover Datei %(file)s: %(error)s" -#: cps/editbooks.py:1063 +#: cps/editbooks.py:1117 #, python-format msgid "File %(file)s uploaded" msgstr "Datei %(file)s hochgeladen" -#: cps/editbooks.py:1088 +#: cps/editbooks.py:1143 msgid "Source or destination format for conversion missing" msgstr "Quell- oder Zielformat für Konvertierung fehlt" -#: cps/editbooks.py:1096 +#: cps/editbooks.py:1151 #, python-format msgid "Book successfully queued for converting to %(book_format)s" msgstr "Buch wurde erfolgreich für die Konvertierung nach %(book_format)s eingereiht" -#: cps/editbooks.py:1100 +#: cps/editbooks.py:1155 #, python-format msgid "There was an error converting this book: %(res)s" msgstr "Es trat ein Fehler beim Konvertieren des Buches auf: %(res)s" @@ -600,174 +603,191 @@ msgstr "Google Drive Setup is nicht komplett, bitte versuche Google Drive zu dea msgid "Callback domain is not verified, please follow steps to verify domain in google developer console" msgstr "Callback Domain ist nicht verifiziert, bitte Domain in der Google Developer Console verifizieren" -#: cps/helper.py:77 +#: cps/helper.py:81 #, python-format msgid "%(format)s format not found for book id: %(book)d" msgstr "%(format)s Format für Buch-ID %(book)d nicht gefunden" -#: cps/helper.py:83 cps/tasks/convert.py:73 +#: cps/helper.py:87 cps/tasks/convert.py:75 #, python-format msgid "%(format)s not found on Google Drive: %(fn)s" msgstr "%(format)s von Buch %(fn)s nicht auf Google Drive gefunden" -#: cps/helper.py:88 +#: cps/helper.py:92 #, python-format msgid "%(format)s not found: %(fn)s" msgstr "%(format)s nicht gefunden: %(fn)s" -#: cps/helper.py:93 cps/helper.py:217 cps/templates/detail.html:41 +#: cps/helper.py:97 cps/helper.py:221 cps/templates/detail.html:41 #: cps/templates/detail.html:45 msgid "Send to Kindle" msgstr "An Kindle senden" -#: cps/helper.py:94 cps/helper.py:111 cps/helper.py:219 +#: cps/helper.py:98 cps/helper.py:115 cps/helper.py:223 msgid "This e-mail has been sent via Calibre-Web." msgstr "Diese E-Mail wurde durch Calibre-Web versendet." -#: cps/helper.py:109 +#: cps/helper.py:113 msgid "Calibre-Web test e-mail" msgstr "Calibre-Web Test-E-Mail" -#: cps/helper.py:110 +#: cps/helper.py:114 msgid "Test e-mail" msgstr "Test-E-Mail" -#: cps/helper.py:127 +#: cps/helper.py:131 msgid "Get Started with Calibre-Web" msgstr "Loslegen mit Calibre-Web" -#: cps/helper.py:132 +#: cps/helper.py:136 #, python-format msgid "Registration e-mail for user: %(name)s" msgstr "Registrierungs-E-Mail für Benutzer %(name)s" -#: cps/helper.py:143 cps/helper.py:149 +#: cps/helper.py:147 cps/helper.py:153 #, python-format msgid "Convert %(orig)s to %(format)s and send to Kindle" msgstr "Konvertiere %(orig)s nach %(format)s und sende an Kindle" -#: cps/helper.py:168 cps/helper.py:172 cps/helper.py:176 +#: cps/helper.py:172 cps/helper.py:176 cps/helper.py:180 #, python-format msgid "Send %(format)s to Kindle" msgstr "Sende %(format)s an Kindle" -#: cps/helper.py:216 cps/tasks/convert.py:90 +#: cps/helper.py:220 cps/tasks/convert.py:92 #, python-format msgid "%(book)s send to Kindle" msgstr "%(book)s an Kindle senden" -#: cps/helper.py:221 +#: cps/helper.py:225 msgid "The requested file could not be read. Maybe wrong permissions?" msgstr "Die angeforderte Datei konnte nicht gelesen werden. Evtl. falsche Zugriffsrechte?" -#: cps/helper.py:313 +#: cps/helper.py:353 +msgid "Read status could not set: {}" +msgstr "" + +#: cps/helper.py:376 #, python-format msgid "Deleting bookfolder for book %(id)s failed, path has subfolders: %(path)s" msgstr "Löschen des Ordners für Buch %(id)s ist fehlgeschlagen, der Pfad hat Unterordner: %(path)s" -#: cps/helper.py:319 +#: cps/helper.py:382 #, python-format msgid "Deleting book %(id)s failed: %(message)s" msgstr "Löschen von Buch %(id)s fehlgeschlagen: %(message)s" -#: cps/helper.py:330 +#: cps/helper.py:393 #, python-format msgid "Deleting book %(id)s from database only, book path in database not valid: %(path)s" msgstr "Lösche Buch %(id)s nur aus Datenbank, Pfad zum Buch in Datenbank ist nicht gültig: %(path)s" -#: cps/helper.py:385 -#, python-format -msgid "Rename title from: '%(src)s' to '%(dest)s' failed with error: %(error)s" +#: cps/helper.py:458 +#, fuzzy, python-format +msgid "Rename author from: '%(src)s' to '%(dest)s' failed with error: %(error)s" msgstr "Umbenennen des Titels '%(src)s' zu '%(dest)s' schlug fehl: %(error)s" -#: cps/helper.py:400 -#, python-format -msgid "Rename file in path '%(src)s' to '%(dest)s' failed with error: %(error)s" -msgstr "Umbenennen der Datei im Pfad '%(src)s' nach '%(dest)s' ist fehlgeschlagen: %(error)s" - -#: cps/helper.py:425 cps/helper.py:435 cps/helper.py:443 +#: cps/helper.py:529 cps/helper.py:538 #, python-format msgid "File %(file)s not found on Google Drive" msgstr "Datei %(file)s wurde nicht auf Google Drive gefunden" -#: cps/helper.py:464 +#: cps/helper.py:572 +#, python-format +msgid "Rename title from: '%(src)s' to '%(dest)s' failed with error: %(error)s" +msgstr "Umbenennen des Titels '%(src)s' zu '%(dest)s' schlug fehl: %(error)s" + +#: cps/helper.py:592 +msgid "Error in rename file in path: {}" +msgstr "" + +#: cps/helper.py:610 #, python-format msgid "Book path %(path)s not found on Google Drive" msgstr "Buchpfad %(path)s wurde nicht auf Google Drive gefunden" -#: cps/helper.py:504 cps/web.py:1659 +#: cps/helper.py:651 cps/web.py:1737 msgid "Found an existing account for this e-mail address" msgstr "Es existiert bereits ein Benutzer für diese E-Mailadresse" -#: cps/helper.py:512 +#: cps/helper.py:659 msgid "This username is already taken" msgstr "Benutzername ist schon vorhanden" -#: cps/helper.py:522 +#: cps/helper.py:669 msgid "Invalid e-mail address format" msgstr "Ungültiges E-Mail Adressformat" -#: cps/helper.py:595 +#: cps/helper.py:754 +msgid "Python modul 'advocate' is not installed but is needed for cover downloads" +msgstr "" + +#: cps/helper.py:767 msgid "Error Downloading Cover" msgstr "Fehler beim Herunterladen des Covers" -#: cps/helper.py:598 +#: cps/helper.py:770 msgid "Cover Format Error" msgstr "Coverdatei fehlerhaft" -#: cps/helper.py:608 +#: cps/helper.py:773 +msgid "You are not allowed to access localhost or the local network for cover uploads" +msgstr "" + +#: cps/helper.py:783 msgid "Failed to create path for cover" msgstr "Fehler beim Erzeugen des Ordners für die Coverdatei" -#: cps/helper.py:624 +#: cps/helper.py:799 msgid "Cover-file is not a valid image file, or could not be stored" msgstr "Cover Datei ist keine gültige Bilddatei, kann nicht gespeichert werden" -#: cps/helper.py:635 +#: cps/helper.py:810 msgid "Only jpg/jpeg/png/webp/bmp files are supported as coverfile" msgstr "Nur jpg/jpeg/png/webp/bmp Dateien werden als Coverdatei unterstützt" -#: cps/helper.py:648 +#: cps/helper.py:822 msgid "Invalid cover file content" msgstr "Ungültiger Cover Dateiinhalt" -#: cps/helper.py:652 +#: cps/helper.py:826 msgid "Only jpg/jpeg files are supported as coverfile" msgstr "Es werden nur jpg/jpeg Dateien als Cover untertützt" -#: cps/helper.py:704 +#: cps/helper.py:878 msgid "Unrar binary file not found" msgstr "UnRar Programm nicht gefunden" -#: cps/helper.py:715 +#: cps/helper.py:889 msgid "Error excecuting UnRar" msgstr "Fehler beim ausführen von UnRar" -#: cps/helper.py:763 +#: cps/helper.py:937 msgid "Waiting" msgstr "Wartend" -#: cps/helper.py:765 +#: cps/helper.py:939 msgid "Failed" msgstr "Fehlgeschlagen" -#: cps/helper.py:767 +#: cps/helper.py:941 msgid "Started" msgstr "Gestartet" -#: cps/helper.py:769 +#: cps/helper.py:943 msgid "Finished" msgstr "Beendet" -#: cps/helper.py:771 +#: cps/helper.py:945 msgid "Unknown Status" msgstr "Unbekannter Status" -#: cps/kobo_auth.py:127 -msgid "PLease access calibre-web from non localhost to get valid api_endpoint for kobo device" +#: cps/kobo_auth.py:128 +#, fuzzy +msgid "Please access Calibre-Web from non localhost to get valid api_endpoint for kobo device" msgstr "Bitte nicht von \"localhost\" auf Calibre-Web zugreifen, um einen gültigen api_endpoint für Kobo Geräte zu erhalten" -#: cps/kobo_auth.py:130 cps/kobo_auth.py:158 +#: cps/kobo_auth.py:154 msgid "Kobo Setup" msgstr "Kobo Setup" @@ -776,7 +796,7 @@ msgstr "Kobo Setup" msgid "Register with %(provider)s" msgstr "Anmelden mit %(provider)s" -#: cps/oauth_bb.py:138 cps/remotelogin.py:133 cps/web.py:1535 +#: cps/oauth_bb.py:138 cps/remotelogin.py:130 cps/web.py:1613 #, python-format msgid "you are now logged in as: '%(nickname)s'" msgstr "Du bist nun eingeloggt als '%(nickname)s'" @@ -837,163 +857,163 @@ msgstr "Google Oauth Fehler, bitte später erneut versuchen." msgid "Google Oauth error: {}" msgstr "Google Oauth Fehler: {}" -#: cps/opds.py:384 +#: cps/opds.py:298 msgid "{} Stars" msgstr "{} Sterne" -#: cps/remotelogin.py:65 cps/templates/layout.html:84 -#: cps/templates/login.html:4 cps/templates/login.html:21 cps/web.py:1584 +#: cps/remotelogin.py:62 cps/templates/layout.html:84 +#: cps/templates/login.html:4 cps/templates/login.html:21 cps/web.py:1662 msgid "Login" msgstr "Login" -#: cps/remotelogin.py:77 cps/remotelogin.py:111 +#: cps/remotelogin.py:74 cps/remotelogin.py:108 msgid "Token not found" msgstr "Token wurde nicht gefunden" -#: cps/remotelogin.py:86 cps/remotelogin.py:119 +#: cps/remotelogin.py:83 cps/remotelogin.py:116 msgid "Token has expired" msgstr "Token ist abgelaufen" -#: cps/remotelogin.py:95 +#: cps/remotelogin.py:92 msgid "Success! Please return to your device" msgstr "Erfolg! Bitte zum Gerät zurückkehren" -#: cps/render_template.py:39 cps/web.py:416 +#: cps/render_template.py:41 cps/web.py:407 msgid "Books" msgstr "Bücher" -#: cps/render_template.py:41 +#: cps/render_template.py:43 msgid "Show recent books" msgstr "Zeige kürzlich hinzugefügte Bücher" -#: cps/render_template.py:42 cps/templates/index.xml:25 +#: cps/render_template.py:44 cps/templates/index.xml:25 msgid "Hot Books" msgstr "Beliebte Bücher" -#: cps/render_template.py:44 +#: cps/render_template.py:46 msgid "Show Hot Books" msgstr "Zeige beliebte Bücher" -#: cps/render_template.py:46 cps/render_template.py:51 +#: cps/render_template.py:48 cps/render_template.py:53 msgid "Downloaded Books" msgstr "Heruntergeladene Bücher" -#: cps/render_template.py:48 cps/render_template.py:53 +#: cps/render_template.py:50 cps/render_template.py:55 #: cps/templates/user_table.html:167 msgid "Show Downloaded Books" msgstr "Zeige heruntergeladene Bücher" -#: cps/render_template.py:56 cps/templates/index.xml:32 cps/web.py:430 +#: cps/render_template.py:58 cps/templates/index.xml:32 cps/web.py:422 msgid "Top Rated Books" msgstr "Best bewertete Bücher" -#: cps/render_template.py:58 cps/templates/user_table.html:161 +#: cps/render_template.py:60 cps/templates/user_table.html:161 msgid "Show Top Rated Books" msgstr "Bestbewertete Bücher anzeigen" -#: cps/render_template.py:59 cps/templates/index.xml:54 -#: cps/templates/index.xml:58 cps/web.py:676 +#: cps/render_template.py:61 cps/templates/index.xml:54 +#: cps/templates/index.xml:58 cps/web.py:729 msgid "Read Books" msgstr "Gelesene Bücher" -#: cps/render_template.py:61 +#: cps/render_template.py:63 msgid "Show read and unread" msgstr "Zeige gelesene/ungelesene Bücher" -#: cps/render_template.py:63 cps/templates/index.xml:61 -#: cps/templates/index.xml:65 cps/web.py:679 +#: cps/render_template.py:65 cps/templates/index.xml:61 +#: cps/templates/index.xml:65 cps/web.py:732 msgid "Unread Books" msgstr "Ungelesene Bücher" -#: cps/render_template.py:65 +#: cps/render_template.py:67 msgid "Show unread" msgstr "Zeige Ungelesene" -#: cps/render_template.py:66 +#: cps/render_template.py:68 msgid "Discover" msgstr "Entdecke" -#: cps/render_template.py:68 cps/templates/index.xml:50 +#: cps/render_template.py:70 cps/templates/index.xml:50 #: cps/templates/user_table.html:162 msgid "Show Random Books" msgstr "Zeige zufällige Bücher" -#: cps/render_template.py:69 cps/templates/book_table.html:67 -#: cps/templates/index.xml:83 cps/web.py:1041 +#: cps/render_template.py:71 cps/templates/book_table.html:67 +#: cps/templates/index.xml:83 cps/web.py:1135 msgid "Categories" msgstr "Kategorien" -#: cps/render_template.py:71 cps/templates/user_table.html:158 +#: cps/render_template.py:73 cps/templates/user_table.html:158 msgid "Show category selection" msgstr "Zeige Kategorienauswahl" -#: cps/render_template.py:72 cps/templates/book_edit.html:90 +#: cps/render_template.py:74 cps/templates/book_edit.html:90 #: cps/templates/book_table.html:68 cps/templates/index.xml:90 -#: cps/templates/search_form.html:69 cps/web.py:948 cps/web.py:959 +#: cps/templates/search_form.html:69 cps/web.py:1034 cps/web.py:1041 msgid "Series" msgstr "Serien" -#: cps/render_template.py:74 cps/templates/user_table.html:157 +#: cps/render_template.py:76 cps/templates/user_table.html:157 msgid "Show series selection" msgstr "Zeige Serienauswahl" -#: cps/render_template.py:75 cps/templates/book_table.html:66 +#: cps/render_template.py:77 cps/templates/book_table.html:66 #: cps/templates/index.xml:69 msgid "Authors" msgstr "Autoren" -#: cps/render_template.py:77 cps/templates/user_table.html:160 +#: cps/render_template.py:79 cps/templates/user_table.html:160 msgid "Show author selection" msgstr "Zeige Autorenauswahl" -#: cps/render_template.py:79 cps/templates/book_table.html:72 -#: cps/templates/index.xml:76 cps/web.py:925 +#: cps/render_template.py:81 cps/templates/book_table.html:72 +#: cps/templates/index.xml:76 cps/web.py:1006 msgid "Publishers" msgstr "Verleger" -#: cps/render_template.py:81 cps/templates/user_table.html:163 +#: cps/render_template.py:83 cps/templates/user_table.html:163 msgid "Show publisher selection" msgstr "Zeige Verlegerauswahl" -#: cps/render_template.py:82 cps/templates/book_table.html:70 +#: cps/render_template.py:84 cps/templates/book_table.html:70 #: cps/templates/index.xml:97 cps/templates/search_form.html:107 -#: cps/web.py:1018 +#: cps/web.py:1108 msgid "Languages" msgstr "Sprachen" -#: cps/render_template.py:85 cps/templates/user_table.html:155 +#: cps/render_template.py:87 cps/templates/user_table.html:155 msgid "Show language selection" msgstr "Zeige Sprachauswahl" -#: cps/render_template.py:86 cps/templates/index.xml:104 +#: cps/render_template.py:88 cps/templates/index.xml:104 msgid "Ratings" msgstr "Bewertungen" -#: cps/render_template.py:88 cps/templates/user_table.html:164 +#: cps/render_template.py:90 cps/templates/user_table.html:164 msgid "Show ratings selection" msgstr "Zeige Bewertungsauswahl" -#: cps/render_template.py:89 cps/templates/index.xml:112 +#: cps/render_template.py:91 cps/templates/index.xml:112 msgid "File formats" msgstr "Dateiformate" -#: cps/render_template.py:91 cps/templates/user_table.html:165 +#: cps/render_template.py:93 cps/templates/user_table.html:165 msgid "Show file formats selection" msgstr "Zeige Dateiformatauswahl" -#: cps/render_template.py:93 cps/web.py:703 +#: cps/render_template.py:95 cps/web.py:755 msgid "Archived Books" msgstr "Archivierte Bücher" -#: cps/render_template.py:95 cps/templates/user_table.html:166 +#: cps/render_template.py:97 cps/templates/user_table.html:166 msgid "Show archived books" msgstr "Zeige archivierte Bücher" -#: cps/render_template.py:97 cps/web.py:780 +#: cps/render_template.py:100 cps/web.py:837 msgid "Books List" msgstr "Bücherliste" -#: cps/render_template.py:99 cps/templates/user_table.html:168 +#: cps/render_template.py:102 cps/templates/user_table.html:168 msgid "Show Books List" msgstr "Zeige Bücherliste" @@ -1047,261 +1067,265 @@ msgstr "Sie haben keine Berechtigung um Bücher aus diesem Bücherregal zu lösc msgid "Create a Shelf" msgstr "Bücherregal erzeugen" -#: cps/shelf.py:237 +#: cps/shelf.py:236 msgid "Sorry you are not allowed to edit this shelf" msgstr "Dir ist es nicht erlaubt, dieses Bücherregal zu editieren" -#: cps/shelf.py:239 +#: cps/shelf.py:238 msgid "Edit a shelf" msgstr "Bücherregal editieren" -#: cps/shelf.py:249 +#: cps/shelf.py:248 msgid "Sorry you are not allowed to create a public shelf" msgstr "Sie haben keine Berechtigung um öffentliche Bücherregal zu erzeugen" -#: cps/shelf.py:266 +#: cps/shelf.py:265 #, python-format msgid "Shelf %(title)s created" msgstr "Bücherregal %(title)s erzeugt" -#: cps/shelf.py:269 +#: cps/shelf.py:268 #, python-format msgid "Shelf %(title)s changed" msgstr "Bücherregal %(title)s verändert" -#: cps/shelf.py:283 +#: cps/shelf.py:282 msgid "There was an error" msgstr "Es trat ein Fehler auf" -#: cps/shelf.py:305 +#: cps/shelf.py:304 #, python-format msgid "A public shelf with the name '%(title)s' already exists." msgstr "Es existiert bereit ein öffentliches Bücherregal mit dem Name '%(title)s'." -#: cps/shelf.py:316 +#: cps/shelf.py:315 #, python-format msgid "A private shelf with the name '%(title)s' already exists." msgstr "Es existiert bereit ein privates Bücherregal mit dem Name '%(title)s'." #: cps/shelf.py:337 +msgid "Error deleting Shelf" +msgstr "" + +#: cps/shelf.py:339 #, fuzzy msgid "Shelf successfully deleted" msgstr "Buch erfolgreich gelöscht" -#: cps/shelf.py:386 +#: cps/shelf.py:389 #, python-format msgid "Change order of Shelf: '%(name)s'" msgstr "Reihenfolge in Bücherregal '%(name)s' verändern" -#: cps/shelf.py:456 +#: cps/shelf.py:461 #, python-format msgid "Shelf: '%(name)s'" msgstr "Bücherregal: '%(name)s'" -#: cps/shelf.py:460 +#: cps/shelf.py:465 msgid "Error opening shelf. Shelf does not exist or is not accessible" msgstr "Fehler beim Öffnen des Bücherregals. Bücherregal exisitert nicht oder ist nicht zugänglich" -#: cps/updater.py:403 cps/updater.py:414 cps/updater.py:514 cps/updater.py:529 +#: cps/updater.py:426 cps/updater.py:437 cps/updater.py:538 cps/updater.py:553 msgid "Unexpected data while reading update information" msgstr "Updateinformationen enthalten unbekannte Daten" -#: cps/updater.py:410 cps/updater.py:521 +#: cps/updater.py:433 cps/updater.py:545 msgid "No update available. You already have the latest version installed" msgstr "Kein Update verfügbar. Es ist bereits die aktuellste Version installiert" -#: cps/updater.py:428 +#: cps/updater.py:451 msgid "A new update is available. Click on the button below to update to the latest version." msgstr "Es sind Updates verfügbar. Klicke auf den Button unten, um auf die aktuellste Version zu aktualisieren." -#: cps/updater.py:446 +#: cps/updater.py:469 msgid "Could not fetch update information" msgstr "Updateinformationen konnten nicht geladen werden" -#: cps/updater.py:456 +#: cps/updater.py:479 msgid "Click on the button below to update to the latest stable version." msgstr "Klicke auf den Button unten, um auf die letzte stabile Version zu aktualisieren." -#: cps/updater.py:465 cps/updater.py:479 cps/updater.py:490 +#: cps/updater.py:488 cps/updater.py:502 cps/updater.py:513 #, python-format msgid "A new update is available. Click on the button below to update to version: %(version)s" msgstr "Ein neues Update ist verfügbar. Klicke auf den Button unten, um auf Version: %(version)s zu aktualisieren" -#: cps/updater.py:507 +#: cps/updater.py:531 msgid "No release information available" msgstr "Keine Releaseinformationen verfügbar" -#: cps/templates/index.html:5 cps/web.py:440 +#: cps/templates/index.html:5 cps/web.py:434 msgid "Discover (Random Books)" msgstr "Entdecke (Zufällige Bücher)" -#: cps/web.py:471 +#: cps/web.py:470 msgid "Hot Books (Most Downloaded)" msgstr "Beliebte Bücher (am meisten Downloads)" -#: cps/web.py:507 +#: cps/web.py:501 #, python-format msgid "Downloaded books by %(user)s" msgstr "Von %(user)s heruntergeladene Bücher" -#: cps/web.py:539 +#: cps/web.py:534 #, python-format msgid "Author: %(name)s" msgstr "Author: %(name)s" -#: cps/web.py:554 +#: cps/web.py:570 #, python-format msgid "Publisher: %(name)s" msgstr "Verleger: %(name)s" -#: cps/web.py:569 +#: cps/web.py:598 #, python-format msgid "Series: %(serie)s" msgstr "Serie: %(serie)s" -#: cps/web.py:582 +#: cps/web.py:610 #, python-format msgid "Rating: %(rating)s stars" msgstr "Bewertung: %(rating)s Sterne" -#: cps/web.py:597 +#: cps/web.py:626 #, python-format msgid "File format: %(format)s" msgstr "Dateiformat: %(format)s" -#: cps/web.py:615 +#: cps/web.py:663 #, python-format msgid "Category: %(name)s" msgstr "Kategorie: %(name)s" -#: cps/web.py:631 +#: cps/web.py:690 #, python-format msgid "Language: %(name)s" msgstr "Sprache: %(name)s" -#: cps/templates/layout.html:56 cps/web.py:737 cps/web.py:1371 +#: cps/templates/layout.html:56 cps/web.py:789 cps/web.py:1444 msgid "Advanced Search" msgstr "Erweiterte Suche" #: cps/templates/book_edit.html:235 cps/templates/feed.xml:33 #: cps/templates/index.xml:11 cps/templates/layout.html:45 #: cps/templates/layout.html:48 cps/templates/search_form.html:226 -#: cps/web.py:750 cps/web.py:1077 +#: cps/web.py:807 cps/web.py:1164 msgid "Search" msgstr "Suche" -#: cps/templates/admin.html:16 cps/web.py:903 +#: cps/templates/admin.html:16 cps/web.py:979 msgid "Downloads" msgstr "Downloads" -#: cps/web.py:980 +#: cps/web.py:1068 msgid "Ratings list" msgstr "Bewertungsliste" -#: cps/web.py:1001 +#: cps/web.py:1095 msgid "File formats list" msgstr "Liste der Dateiformate" -#: cps/templates/layout.html:73 cps/templates/tasks.html:7 cps/web.py:1055 +#: cps/templates/layout.html:73 cps/templates/tasks.html:7 cps/web.py:1149 msgid "Tasks" msgstr "Aufgaben" -#: cps/web.py:1215 +#: cps/web.py:1286 msgid "Published after " msgstr "Herausgegeben nach dem " -#: cps/web.py:1222 +#: cps/web.py:1293 msgid "Published before " msgstr "Herausgegeben vor dem " -#: cps/web.py:1244 +#: cps/web.py:1315 #, python-format msgid "Rating <= %(rating)s" msgstr "Bewertung <= %(rating)s" -#: cps/web.py:1246 +#: cps/web.py:1317 #, python-format msgid "Rating >= %(rating)s" msgstr "Bewertung >= %(rating)s" -#: cps/web.py:1248 +#: cps/web.py:1319 #, python-format msgid "Read Status = %(status)s" msgstr "Lesestatus = %(status)s" -#: cps/web.py:1353 +#: cps/web.py:1425 msgid "Error on search for custom columns, please restart Calibre-Web" msgstr "Fehler bei der Suche nach eigenen Spalten, bitte Calibre-Web neustarten" -#: cps/web.py:1449 +#: cps/web.py:1527 #, python-format msgid "Book successfully queued for sending to %(kindlemail)s" msgstr "Buch erfolgreich zum Senden an %(kindlemail)s eingereiht" -#: cps/web.py:1453 +#: cps/web.py:1531 #, python-format msgid "Oops! There was an error sending this book: %(res)s" msgstr "Beim Senden des Buchs trat ein Fehler auf: %(res)s" -#: cps/web.py:1455 +#: cps/web.py:1533 msgid "Please update your profile with a valid Send to Kindle E-mail Address." msgstr "Bitte zuerst die Kindle E-Mailadresse konfigurieren..." -#: cps/web.py:1472 +#: cps/web.py:1550 msgid "E-Mail server is not configured, please contact your administrator!" msgstr "Der E-Mail Server ist nicht konfigurierte, bitte den Administrator kontaktieren!" -#: cps/templates/layout.html:85 cps/templates/register.html:17 cps/web.py:1473 -#: cps/web.py:1480 cps/web.py:1486 cps/web.py:1505 cps/web.py:1509 -#: cps/web.py:1515 +#: cps/templates/layout.html:85 cps/templates/register.html:17 cps/web.py:1551 +#: cps/web.py:1558 cps/web.py:1564 cps/web.py:1583 cps/web.py:1587 +#: cps/web.py:1593 msgid "Register" msgstr "Registrieren" -#: cps/web.py:1507 +#: cps/web.py:1585 msgid "Your e-mail is not allowed to register" msgstr "Diese E-Mail ist nicht für die Registrierung zugelassen" -#: cps/web.py:1510 +#: cps/web.py:1588 msgid "Confirmation e-mail was send to your e-mail account." msgstr "Eine Bestätigungs-E-Mail wurde an deinen E-Mail Account versendet." -#: cps/web.py:1524 +#: cps/web.py:1602 msgid "Cannot activate LDAP authentication" msgstr "LDAP-Authentifizierung kann nicht aktiviert werden" -#: cps/web.py:1543 +#: cps/web.py:1621 #, python-format msgid "Fallback Login as: '%(nickname)s', LDAP Server not reachable, or user not known" msgstr "Rückfall Login als: '%(nickname)s', LDAP Server ist nicht erreichbar, oder der Nutzer ist unbekannt" -#: cps/web.py:1549 +#: cps/web.py:1627 #, python-format msgid "Could not login: %(message)s" msgstr "Login nicht erfolgreich: %(message)s" -#: cps/web.py:1553 cps/web.py:1578 +#: cps/web.py:1631 cps/web.py:1656 msgid "Wrong Username or Password" msgstr "Falscher Benutzername oder Passwort" -#: cps/web.py:1560 +#: cps/web.py:1638 msgid "New Password was send to your email address" msgstr "Das neue Passwort wurde an die E-Mail Adresse verschickt" -#: cps/web.py:1566 +#: cps/web.py:1644 msgid "Please enter valid username to reset password" msgstr "Bitte einen gültigen Benutzernamen zum Zurücksetzen des Passworts angeben" -#: cps/web.py:1573 +#: cps/web.py:1651 #, python-format msgid "You are now logged in as: '%(nickname)s'" msgstr "Eingeloggt als: '%(nickname)s'" -#: cps/web.py:1639 cps/web.py:1688 +#: cps/web.py:1717 cps/web.py:1766 #, python-format msgid "%(name)s's profile" msgstr "%(name)s's Profil" -#: cps/web.py:1655 +#: cps/web.py:1733 msgid "Profile updated" msgstr "Profil aktualisiert" @@ -1309,36 +1333,36 @@ msgstr "Profil aktualisiert" msgid "Found no valid gmail.json file with OAuth information" msgstr "Keine gültige gmail.json Datei mit Oauth informationen gefunden" -#: cps/tasks/convert.py:137 +#: cps/tasks/convert.py:154 #, python-format msgid "Calibre ebook-convert %(tool)s not found" msgstr "Calibre E-Book Konverter %(tool)s nicht gefunden" -#: cps/tasks/convert.py:163 +#: cps/tasks/convert.py:187 #, python-format msgid "%(format)s format not found on disk" msgstr "%(format)s Format nicht gefunden" -#: cps/tasks/convert.py:167 +#: cps/tasks/convert.py:191 msgid "Ebook converter failed with unknown error" msgstr "EBook Converter mit unbekanntem Fehler fehlgeschlagen" -#: cps/tasks/convert.py:177 +#: cps/tasks/convert.py:201 #, python-format msgid "Kepubify-converter failed: %(error)s" msgstr "Kepubify Konverter Aufruf fehlgeschlagen: %(error)s" -#: cps/tasks/convert.py:199 +#: cps/tasks/convert.py:223 #, python-format msgid "Converted file not found or more than one file in folder %(folder)s" msgstr "Konvertierte Datei nicht gefunden, oder mehr als eine Datei im Pfad %(folder)s" -#: cps/tasks/convert.py:222 +#: cps/tasks/convert.py:246 #, python-format msgid "Ebook-converter failed: %(error)s" msgstr "Fehler des EBook-Converters: %(error)s" -#: cps/tasks/convert.py:245 +#: cps/tasks/convert.py:269 #, python-format msgid "Calibre failed with error: %(error)s" msgstr "Calibre fehlgeschlagen mit Fehler: %(error)s" @@ -1393,7 +1417,7 @@ msgid "Edit" msgstr "Editieren" #: cps/templates/admin.html:25 cps/templates/book_edit.html:16 -#: cps/templates/book_table.html:97 cps/templates/modal_dialogs.html:63 +#: cps/templates/book_table.html:100 cps/templates/modal_dialogs.html:63 #: cps/templates/modal_dialogs.html:116 cps/templates/user_edit.html:67 #: cps/templates/user_table.html:149 msgid "Delete" @@ -1403,179 +1427,179 @@ msgstr "Löschen" msgid "Public Shelf" msgstr "Öffentliches Bücherregal" -#: cps/templates/admin.html:51 +#: cps/templates/admin.html:53 msgid "Add New User" msgstr "Neuen Benutzer hinzufügen" -#: cps/templates/admin.html:53 +#: cps/templates/admin.html:55 msgid "Import LDAP Users" msgstr "LDAP Benutzer importieren" -#: cps/templates/admin.html:60 +#: cps/templates/admin.html:62 msgid "E-mail Server Settings" msgstr "Einstellungen des SMTP-Servers" -#: cps/templates/admin.html:65 cps/templates/email_edit.html:31 +#: cps/templates/admin.html:67 cps/templates/email_edit.html:31 msgid "SMTP Hostname" msgstr "SMTP-Hostname" -#: cps/templates/admin.html:69 cps/templates/email_edit.html:35 +#: cps/templates/admin.html:71 cps/templates/email_edit.html:35 msgid "SMTP Port" msgstr "SMTP Port" -#: cps/templates/admin.html:73 cps/templates/email_edit.html:39 +#: cps/templates/admin.html:75 cps/templates/email_edit.html:39 msgid "Encryption" msgstr "Verschlüsselung" -#: cps/templates/admin.html:77 cps/templates/email_edit.html:47 +#: cps/templates/admin.html:79 cps/templates/email_edit.html:47 msgid "SMTP Login" msgstr "SMTP-Login" -#: cps/templates/admin.html:81 cps/templates/admin.html:92 +#: cps/templates/admin.html:83 cps/templates/admin.html:94 #: cps/templates/email_edit.html:55 msgid "From E-mail" msgstr "Absenderadresse" -#: cps/templates/admin.html:88 +#: cps/templates/admin.html:90 msgid "E-Mail Service" msgstr "E-Mail Service" -#: cps/templates/admin.html:89 +#: cps/templates/admin.html:91 msgid "Gmail via Oauth2" msgstr "Gmail via Oauth2" -#: cps/templates/admin.html:104 +#: cps/templates/admin.html:106 msgid "Configuration" msgstr "Konfiguration" -#: cps/templates/admin.html:107 +#: cps/templates/admin.html:109 msgid "Calibre Database Directory" msgstr "Ordner der Calibre-DB" -#: cps/templates/admin.html:111 cps/templates/config_edit.html:68 +#: cps/templates/admin.html:113 cps/templates/config_edit.html:68 msgid "Log Level" msgstr "Loglevel" -#: cps/templates/admin.html:115 +#: cps/templates/admin.html:117 msgid "Port" msgstr "Port" -#: cps/templates/admin.html:120 +#: cps/templates/admin.html:122 msgid "External Port" msgstr "Externer Port" -#: cps/templates/admin.html:127 cps/templates/config_view_edit.html:28 +#: cps/templates/admin.html:129 cps/templates/config_view_edit.html:28 msgid "Books per Page" msgstr "Bücher pro Seite" -#: cps/templates/admin.html:131 +#: cps/templates/admin.html:133 msgid "Uploads" msgstr "Hochladen" -#: cps/templates/admin.html:135 +#: cps/templates/admin.html:137 msgid "Anonymous Browsing" msgstr "Anonymes Durchsuchen" -#: cps/templates/admin.html:139 +#: cps/templates/admin.html:141 msgid "Public Registration" msgstr "Öffentliche Registrierung" -#: cps/templates/admin.html:143 +#: cps/templates/admin.html:145 msgid "Magic Link Remote Login" msgstr "Remotelogin ('Magischer Link')" -#: cps/templates/admin.html:147 +#: cps/templates/admin.html:149 msgid "Reverse Proxy Login" msgstr "Reverse Proxy Login" -#: cps/templates/admin.html:152 cps/templates/config_edit.html:173 +#: cps/templates/admin.html:154 cps/templates/config_edit.html:173 msgid "Reverse Proxy Header Name" msgstr "Reverse Proxy Header Name" -#: cps/templates/admin.html:157 +#: cps/templates/admin.html:159 msgid "Edit Calibre Database Configuration" msgstr "Calibre Datenbank Konfiguration editieren" -#: cps/templates/admin.html:158 +#: cps/templates/admin.html:160 msgid "Edit Basic Configuration" msgstr "Basiskonfiguration" -#: cps/templates/admin.html:159 +#: cps/templates/admin.html:161 msgid "Edit UI Configuration" msgstr "Benutzeroberflächenkonfiguration" -#: cps/templates/admin.html:164 +#: cps/templates/admin.html:166 msgid "Administration" msgstr "Administration" -#: cps/templates/admin.html:165 +#: cps/templates/admin.html:167 msgid "Download Debug Package" msgstr "Debug Daten herunterladen" -#: cps/templates/admin.html:166 +#: cps/templates/admin.html:168 msgid "View Logs" msgstr "Logdateien ansehen" -#: cps/templates/admin.html:169 +#: cps/templates/admin.html:171 msgid "Reconnect Calibre Database" msgstr "Calibre-DB neu verbinden" -#: cps/templates/admin.html:170 +#: cps/templates/admin.html:172 msgid "Restart" msgstr "Neustart" -#: cps/templates/admin.html:171 +#: cps/templates/admin.html:173 msgid "Shutdown" msgstr "Calibre-Web beenden" -#: cps/templates/admin.html:176 +#: cps/templates/admin.html:178 msgid "Update" msgstr "Update" -#: cps/templates/admin.html:180 +#: cps/templates/admin.html:182 msgid "Version" msgstr "Version" -#: cps/templates/admin.html:181 +#: cps/templates/admin.html:183 msgid "Details" msgstr "Details" -#: cps/templates/admin.html:187 +#: cps/templates/admin.html:189 msgid "Current version" msgstr "Aktuelle Version" -#: cps/templates/admin.html:194 +#: cps/templates/admin.html:196 msgid "Check for Update" msgstr "Nach Update suchen" -#: cps/templates/admin.html:195 +#: cps/templates/admin.html:197 msgid "Perform Update" msgstr "Update durchführen" -#: cps/templates/admin.html:208 +#: cps/templates/admin.html:210 msgid "Are you sure you want to restart?" msgstr "Calibre-Web wirklich neustarten?" -#: cps/templates/admin.html:213 cps/templates/admin.html:227 -#: cps/templates/admin.html:247 cps/templates/config_db.html:70 +#: cps/templates/admin.html:215 cps/templates/admin.html:229 +#: cps/templates/admin.html:249 cps/templates/config_db.html:70 msgid "OK" msgstr "OK" -#: cps/templates/admin.html:214 cps/templates/admin.html:228 -#: cps/templates/book_edit.html:213 cps/templates/book_table.html:124 +#: cps/templates/admin.html:216 cps/templates/admin.html:230 +#: cps/templates/book_edit.html:213 cps/templates/book_table.html:127 #: cps/templates/config_db.html:54 cps/templates/config_edit.html:359 -#: cps/templates/config_view_edit.html:173 cps/templates/modal_dialogs.html:64 +#: cps/templates/config_view_edit.html:175 cps/templates/modal_dialogs.html:64 #: cps/templates/modal_dialogs.html:99 cps/templates/modal_dialogs.html:117 #: cps/templates/modal_dialogs.html:135 cps/templates/shelf_edit.html:27 #: cps/templates/user_edit.html:144 msgid "Cancel" msgstr "Abbruch" -#: cps/templates/admin.html:226 +#: cps/templates/admin.html:228 msgid "Are you sure you want to shutdown?" msgstr "Calibre-Web wirklich anhalten?" -#: cps/templates/admin.html:238 +#: cps/templates/admin.html:240 msgid "Updating, please do not reload this page" msgstr "Updatevorgang, Seite bitte nicht neu laden" @@ -1587,44 +1611,43 @@ msgstr "via" msgid "In Library" msgstr "In Bibliothek" -#: cps/templates/author.html:26 cps/templates/index.html:72 -#: cps/templates/search.html:29 cps/templates/shelf.html:19 +#: cps/templates/author.html:26 cps/templates/index.html:73 +#: cps/templates/search.html:30 cps/templates/shelf.html:19 msgid "Sort according to book date, newest first" msgstr "Sortiere nach Buchdatum, Neuestes zuerst" -#: cps/templates/author.html:27 cps/templates/index.html:73 -#: cps/templates/search.html:30 cps/templates/shelf.html:20 +#: cps/templates/author.html:27 cps/templates/index.html:74 +#: cps/templates/search.html:31 cps/templates/shelf.html:20 msgid "Sort according to book date, oldest first" msgstr "Sortiere nach Buchdatum, Aältestes zuerst" -#: cps/templates/author.html:28 cps/templates/index.html:74 -#: cps/templates/search.html:31 cps/templates/shelf.html:21 +#: cps/templates/author.html:28 cps/templates/index.html:75 +#: cps/templates/search.html:32 cps/templates/shelf.html:21 msgid "Sort title in alphabetical order" msgstr "Sortiere Titel in alphabetischer Reihenfolge" -#: cps/templates/author.html:29 cps/templates/index.html:75 -#: cps/templates/search.html:32 cps/templates/shelf.html:22 +#: cps/templates/author.html:29 cps/templates/index.html:76 +#: cps/templates/search.html:33 cps/templates/shelf.html:22 msgid "Sort title in reverse alphabetical order" msgstr "Sortiere Titel in umgekehrt alphabetischer Reihenfolge" -#: cps/templates/author.html:30 cps/templates/index.html:78 -#: cps/templates/search.html:35 cps/templates/shelf.html:25 +#: cps/templates/author.html:30 cps/templates/index.html:79 +#: cps/templates/search.html:36 cps/templates/shelf.html:25 msgid "Sort according to publishing date, newest first" msgstr "Sortiere nach Herausgabedatum, Neueste zuerst" -#: cps/templates/author.html:31 cps/templates/index.html:79 -#: cps/templates/search.html:36 cps/templates/shelf.html:26 +#: cps/templates/author.html:31 cps/templates/index.html:80 +#: cps/templates/search.html:37 cps/templates/shelf.html:26 msgid "Sort according to publishing date, oldest first" msgstr "Sortiere nach Herausgabedatum, Älteste zuerst" -#: cps/templates/author.html:57 cps/templates/author.html:117 -#: cps/templates/discover.html:30 cps/templates/index.html:29 -#: cps/templates/index.html:111 cps/templates/search.html:65 -#: cps/templates/shelf.html:54 +#: cps/templates/author.html:56 cps/templates/author.html:115 +#: cps/templates/index.html:29 cps/templates/index.html:112 +#: cps/templates/search.html:66 cps/templates/shelf.html:54 msgid "reduce" msgstr "Reduzieren" -#: cps/templates/author.html:101 +#: cps/templates/author.html:99 msgid "More by" msgstr "Mehr von" @@ -1749,7 +1772,7 @@ msgid "Fetch Metadata" msgstr "Metadaten laden" #: cps/templates/book_edit.html:212 cps/templates/config_db.html:53 -#: cps/templates/config_edit.html:358 cps/templates/config_view_edit.html:172 +#: cps/templates/config_edit.html:358 cps/templates/config_view_edit.html:174 #: cps/templates/email_edit.html:65 cps/templates/shelf_edit.html:25 #: cps/templates/shelf_order.html:41 cps/templates/user_edit.html:142 msgid "Save" @@ -1876,26 +1899,34 @@ msgstr "Kommentare eingeben" msgid "Comments" msgstr "Kommentare" -#: cps/templates/book_table.html:77 cps/templates/book_table.html:79 -#: cps/templates/book_table.html:81 cps/templates/book_table.html:83 -#: cps/templates/book_table.html:87 cps/templates/book_table.html:89 -#: cps/templates/book_table.html:91 cps/templates/book_table.html:93 +#: cps/templates/book_table.html:75 +msgid "Archiv Status" +msgstr "" + +#: cps/templates/book_table.html:77 cps/templates/search_form.html:42 +msgid "Read Status" +msgstr "Lesestatus" + +#: cps/templates/book_table.html:80 cps/templates/book_table.html:82 +#: cps/templates/book_table.html:84 cps/templates/book_table.html:86 +#: cps/templates/book_table.html:90 cps/templates/book_table.html:92 +#: cps/templates/book_table.html:96 msgid "Enter " msgstr "Eingeben " -#: cps/templates/book_table.html:110 cps/templates/modal_dialogs.html:46 +#: cps/templates/book_table.html:113 cps/templates/modal_dialogs.html:46 msgid "Are you really sure?" msgstr "Sicher?" -#: cps/templates/book_table.html:114 +#: cps/templates/book_table.html:117 msgid "Books with Title will be merged from:" msgstr "Bücher werden zusammengeführt. Von Titel:" -#: cps/templates/book_table.html:118 +#: cps/templates/book_table.html:121 msgid "Into Book with Title:" msgstr "In Buch mit Titel:" -#: cps/templates/book_table.html:123 +#: cps/templates/book_table.html:126 msgid "Merge" msgstr "Zusammenführen" @@ -2071,11 +2102,6 @@ msgstr "LDAP Server Port" msgid "LDAP Encryption" msgstr "LDAP Verschlüsselung" -#: cps/templates/config_edit.html:204 cps/templates/config_view_edit.html:62 -#: cps/templates/email_edit.html:41 -msgid "None" -msgstr "Keine" - #: cps/templates/config_edit.html:205 msgid "TLS" msgstr "TLS" @@ -2292,11 +2318,11 @@ msgstr "Standard-Sichtbarkeiten für neue Benutzer" msgid "Show Random Books in Detail View" msgstr "Zeige zufällige Bücher in der Detailansicht" -#: cps/templates/config_view_edit.html:165 cps/templates/user_edit.html:87 +#: cps/templates/config_view_edit.html:166 cps/templates/user_edit.html:87 msgid "Add Allowed/Denied Tags" msgstr "Erlaubte/Verbotene Tags hinzufügen" -#: cps/templates/config_view_edit.html:166 +#: cps/templates/config_view_edit.html:167 msgid "Add Allowed/Denied custom column values" msgstr "Erlaubte/Verbotene Calibre Spalten hinzufügen" @@ -2345,13 +2371,13 @@ msgstr "Archiviert" msgid "Description:" msgstr "Beschreibung:" -#: cps/templates/detail.html:256 cps/templates/search.html:14 +#: cps/templates/detail.html:256 cps/templates/search.html:15 msgid "Add to shelf" msgstr "Zu Bücherregal hinzufügen" #: cps/templates/detail.html:267 cps/templates/detail.html:284 #: cps/templates/feed.xml:79 cps/templates/layout.html:137 -#: cps/templates/search.html:20 +#: cps/templates/search.html:21 msgid "(Public)" msgstr "(Öffentlich)" @@ -2429,10 +2455,15 @@ msgstr "Verbotene Domains für eine Registrierung" msgid "Next" msgstr "Nächste" -#: cps/templates/generate_kobo_auth_url.html:5 +#: cps/templates/generate_kobo_auth_url.html:6 msgid "Open the .kobo/Kobo eReader.conf file in a text editor and add (or edit):" msgstr "Öffne die .kobo/Kobo eReader.conf Datei in einem Texteditor und füge hinzu (oder ersetze):" +#: cps/templates/generate_kobo_auth_url.html:11 +#, fuzzy +msgid "Kobo Token:" +msgstr "Kobo Sync Token" + #: cps/templates/http_error.html:31 msgid "Calibre-Web Instance is unconfigured, please contact your administrator" msgstr "Calibre-Web Instanz ist nicht konfiguriert, bitte den Administrator kontaktieren" @@ -2449,29 +2480,29 @@ msgstr "Zurück zur Hauptseite" msgid "Logout User" msgstr "Benutzer ausloggem" -#: cps/templates/index.html:69 +#: cps/templates/index.html:70 msgid "Sort ascending according to download count" msgstr "Aufsteigend nach Downloadzahlen sortieren" -#: cps/templates/index.html:70 +#: cps/templates/index.html:71 msgid "Sort descending according to download count" msgstr "Absteigend nach Downloadzahlen sortieren" -#: cps/templates/index.html:76 cps/templates/search.html:33 +#: cps/templates/index.html:77 cps/templates/search.html:34 #: cps/templates/shelf.html:23 msgid "Sort authors in alphabetical order" msgstr "Sortiere Autoren in alphabetischer Reihenfolge" -#: cps/templates/index.html:77 cps/templates/search.html:34 +#: cps/templates/index.html:78 cps/templates/search.html:35 #: cps/templates/shelf.html:24 msgid "Sort authors in reverse alphabetical order" msgstr "Sortiere Autoren in umgekehrt alphabetischer Reihenfolge" -#: cps/templates/index.html:81 +#: cps/templates/index.html:82 msgid "Sort ascending according to series index" msgstr "Sortiere Serienindex aufsteigend" -#: cps/templates/index.html:82 +#: cps/templates/index.html:83 msgid "Sort descending according to series index" msgstr "Sortiere Serienindex absteigend" @@ -2901,10 +2932,6 @@ msgstr "Herausgabedatum von" msgid "Published Date To" msgstr "Herausgabedatum bis" -#: cps/templates/search_form.html:42 -msgid "Read Status" -msgstr "Lesestatus" - #: cps/templates/search_form.html:59 msgid "Exclude Tags" msgstr "Tags ausschließen" diff --git a/cps/translations/el/LC_MESSAGES/messages.mo b/cps/translations/el/LC_MESSAGES/messages.mo index f9eedd9b..d61f1964 100644 Binary files a/cps/translations/el/LC_MESSAGES/messages.mo and b/cps/translations/el/LC_MESSAGES/messages.mo differ diff --git a/cps/translations/el/LC_MESSAGES/messages.po b/cps/translations/el/LC_MESSAGES/messages.po index 77034e28..0a4b6419 100644 --- a/cps/translations/el/LC_MESSAGES/messages.po +++ b/cps/translations/el/LC_MESSAGES/messages.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: Calibre-Web\n" "Report-Msgid-Bugs-To: https://github.com/janeczku/Calibre-Web\n" -"POT-Creation-Date: 2022-01-15 09:19+0100\n" +"POT-Creation-Date: 2022-04-18 20:01+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Depountis Georgios\n" "Language: el\n" @@ -15,589 +15,592 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.9.0\n" +"Generated-By: Babel 2.9.1\n" -#: cps/about.py:34 cps/about.py:49 cps/about.py:65 cps/converter.py:31 -msgid "not installed" -msgstr "δεν εγκαταστάθηκε" - -#: cps/about.py:47 cps/about.py:63 -msgid "installed" -msgstr "εγκαταστάθηκε" - -#: cps/about.py:145 +#: cps/about.py:86 msgid "Statistics" msgstr "Στατιστικά" -#: cps/admin.py:144 +#: cps/admin.py:141 msgid "Server restarted, please reload page" msgstr "Ο διακομιστής επανεκκίνησε, παρακαλούμε φόρτωσε ξανά τη σελίδα" -#: cps/admin.py:146 +#: cps/admin.py:143 msgid "Performing shutdown of server, please close window" msgstr "Πραγματοποιείται κλείσιμο του διακομιστή, παρακαλούμε κλείσε το παράθυρο" -#: cps/admin.py:154 +#: cps/admin.py:151 msgid "Reconnect successful" msgstr "Επιτυχής επανασύνδεση" -#: cps/admin.py:157 +#: cps/admin.py:154 msgid "Unknown command" msgstr "Άγνωστη εντολή" -#: cps/admin.py:167 cps/editbooks.py:707 cps/editbooks.py:721 -#: cps/editbooks.py:866 cps/editbooks.py:868 cps/editbooks.py:895 -#: cps/editbooks.py:911 cps/updater.py:584 cps/uploader.py:93 -#: cps/uploader.py:103 +#: cps/admin.py:176 cps/editbooks.py:713 cps/editbooks.py:892 +#: cps/editbooks.py:894 cps/editbooks.py:930 cps/editbooks.py:947 +#: cps/updater.py:608 cps/uploader.py:93 cps/uploader.py:103 msgid "Unknown" msgstr "ʼΑγνωστο" -#: cps/admin.py:188 +#: cps/admin.py:197 msgid "Admin page" msgstr "Σελίδα διαχειριστή" -#: cps/admin.py:207 +#: cps/admin.py:217 msgid "Basic Configuration" msgstr "Βασική Διαμόρφωση" -#: cps/admin.py:244 +#: cps/admin.py:255 msgid "UI Configuration" msgstr "UI Διαμόρφωση" -#: cps/admin.py:277 cps/templates/admin.html:50 +#: cps/admin.py:289 cps/templates/admin.html:51 #, fuzzy msgid "Edit Users" msgstr "Χρήστης Διαχειριστής" -#: cps/admin.py:318 cps/opds.py:109 cps/opds.py:198 cps/opds.py:275 -#: cps/opds.py:327 cps/templates/grid.html:13 cps/templates/languages.html:9 +#: cps/admin.py:333 cps/opds.py:529 cps/templates/grid.html:13 #: cps/templates/list.html:13 msgid "All" msgstr "Όλα" -#: cps/admin.py:343 cps/admin.py:1615 +#: cps/admin.py:360 cps/admin.py:1648 msgid "User not found" msgstr "Δεν βρέθηκε χρήστης" -#: cps/admin.py:357 +#: cps/admin.py:374 msgid "{} users deleted successfully" msgstr "" -#: cps/admin.py:379 cps/templates/config_view_edit.html:133 +#: cps/admin.py:397 cps/templates/config_view_edit.html:133 #: cps/templates/user_edit.html:45 cps/templates/user_table.html:81 msgid "Show All" msgstr "Προβολή Όλων" -#: cps/admin.py:400 cps/admin.py:406 +#: cps/admin.py:418 cps/admin.py:424 msgid "Malformed request" msgstr "" -#: cps/admin.py:418 cps/admin.py:1493 +#: cps/admin.py:436 cps/admin.py:1526 msgid "Guest Name can't be changed" msgstr "" -#: cps/admin.py:430 +#: cps/admin.py:448 msgid "Guest can't have this role" msgstr "" -#: cps/admin.py:442 cps/admin.py:1451 +#: cps/admin.py:460 cps/admin.py:1484 msgid "No admin user remaining, can't remove admin role" msgstr "Δεν έχει απομείνει χρήστης διαχειριστής, δεν μπορεί να αφαιρεθεί ο ρόλος διαχειριστή" -#: cps/admin.py:446 cps/admin.py:460 +#: cps/admin.py:464 cps/admin.py:478 msgid "Value has to be true or false" msgstr "" -#: cps/admin.py:448 +#: cps/admin.py:466 msgid "Invalid role" msgstr "" -#: cps/admin.py:452 +#: cps/admin.py:470 msgid "Guest can't have this view" msgstr "" -#: cps/admin.py:462 +#: cps/admin.py:480 msgid "Invalid view" msgstr "" -#: cps/admin.py:465 +#: cps/admin.py:483 msgid "Guest's Locale is determined automatically and can't be set" msgstr "" -#: cps/admin.py:469 +#: cps/admin.py:487 msgid "No Valid Locale Given" msgstr "" -#: cps/admin.py:480 +#: cps/admin.py:498 msgid "No Valid Book Language Given" msgstr "" -#: cps/admin.py:482 +#: cps/admin.py:500 cps/editbooks.py:1267 msgid "Parameter not found" msgstr "" -#: cps/admin.py:533 +#: cps/admin.py:553 msgid "Invalid Read Column" msgstr "" -#: cps/admin.py:539 +#: cps/admin.py:559 msgid "Invalid Restricted Column" msgstr "" -#: cps/admin.py:560 cps/admin.py:1323 +#: cps/admin.py:579 cps/admin.py:1355 msgid "Calibre-Web configuration updated" msgstr "Ενημερώθηκε η διαμόρφωση Calibre-Web" -#: cps/admin.py:572 +#: cps/admin.py:591 msgid "Do you really want to delete the Kobo Token?" msgstr "Θέλεις πραγματικά να διαγράψεις τη Μονάδα Kobo;" -#: cps/admin.py:574 +#: cps/admin.py:593 msgid "Do you really want to delete this domain?" msgstr "" -#: cps/admin.py:576 +#: cps/admin.py:595 msgid "Do you really want to delete this user?" msgstr "" -#: cps/admin.py:578 +#: cps/admin.py:597 msgid "Are you sure you want to delete this shelf?" msgstr "Είσαι σίγουρος/η πως θέλεις να διαγράψεις αυτό το ράφι;" -#: cps/admin.py:580 +#: cps/admin.py:599 #, fuzzy msgid "Are you sure you want to change locales of selected user(s)?" msgstr "Είσαι σίγουρος/η πως θέλεις να διαγράψεις αυτό το ράφι;" -#: cps/admin.py:582 +#: cps/admin.py:601 msgid "Are you sure you want to change visible book languages for selected user(s)?" msgstr "" -#: cps/admin.py:584 +#: cps/admin.py:603 msgid "Are you sure you want to change the selected role for the selected user(s)?" msgstr "" -#: cps/admin.py:586 +#: cps/admin.py:605 #, fuzzy msgid "Are you sure you want to change the selected restrictions for the selected user(s)?" msgstr "Είσαι σίγουρος/η πως θέλεις να διαγράψεις αυτό το ράφι;" -#: cps/admin.py:588 +#: cps/admin.py:607 msgid "Are you sure you want to change the selected visibility restrictions for the selected user(s)?" msgstr "" -#: cps/admin.py:590 +#: cps/admin.py:610 #, fuzzy msgid "Are you sure you want to change shelf sync behavior for the selected user(s)?" msgstr "Είσαι σίγουρος/η πως θέλεις να διαγράψεις αυτό το ράφι;" -#: cps/admin.py:592 +#: cps/admin.py:612 #, fuzzy msgid "Are you sure you want to change Calibre library location?" msgstr "Είσαι σίγουρος/η πως θέλεις να κάνεις κλείσιμο;" -#: cps/admin.py:594 +#: cps/admin.py:614 msgid "Are you sure you want delete Calibre-Web's sync database to force a full sync with your Kobo Reader?" msgstr "" -#: cps/admin.py:743 +#: cps/admin.py:764 msgid "Tag not found" msgstr "" -#: cps/admin.py:755 +#: cps/admin.py:776 msgid "Invalid Action" msgstr "" -#: cps/admin.py:871 cps/admin.py:877 cps/admin.py:887 cps/admin.py:897 +#: cps/admin.py:893 cps/admin.py:899 cps/admin.py:909 cps/admin.py:919 #: cps/templates/modal_dialogs.html:29 cps/templates/user_table.html:41 #: cps/templates/user_table.html:58 msgid "Deny" msgstr "Απόρριψη" -#: cps/admin.py:873 cps/admin.py:879 cps/admin.py:889 cps/admin.py:899 +#: cps/admin.py:895 cps/admin.py:901 cps/admin.py:911 cps/admin.py:921 #: cps/templates/modal_dialogs.html:28 cps/templates/user_table.html:44 #: cps/templates/user_table.html:61 msgid "Allow" msgstr "Επιτρέπεται" -#: cps/admin.py:913 +#: cps/admin.py:936 msgid "{} sync entries deleted" msgstr "" -#: cps/admin.py:1036 +#: cps/admin.py:1059 msgid "client_secrets.json Is Not Configured For Web Application" msgstr "client_secrets.json Δεν Έχει Διαμορφωθεί Για Διαδικτυακή Εφαρμογή" -#: cps/admin.py:1081 +#: cps/admin.py:1104 msgid "Logfile Location is not Valid, Please Enter Correct Path" msgstr "Το Φύλλο Καταγραφής Τοποθεσίας δεν είναι Έγκυρο, Παρακαλούμε Συμπλήρωσε Τη Σωστή Πορεία" -#: cps/admin.py:1087 +#: cps/admin.py:1110 msgid "Access Logfile Location is not Valid, Please Enter Correct Path" msgstr "Η Πρόσβαση Φύλλου Καταγραφης Τοποθεσίας δεν είναι έγκυρη, Παρακαλούμε Συμπλήρωσε Τη Σωστή Πορεία" -#: cps/admin.py:1117 +#: cps/admin.py:1140 msgid "Please Enter a LDAP Provider, Port, DN and User Object Identifier" msgstr "Παρακαλούμε Συμπλήρωσε ένα Πάροχο LDAP, Θύρα, DN και Αντικείμενο Αναγνώρισης Χρήστη" -#: cps/admin.py:1123 +#: cps/admin.py:1146 #, fuzzy msgid "Please Enter a LDAP Service Account and Password" msgstr "Παρακαλούμε συμπλήρωσε ένα έγκυρο όνομα χρήστη για επαναφορά του κωδικού" -#: cps/admin.py:1126 +#: cps/admin.py:1149 msgid "Please Enter a LDAP Service Account" msgstr "" -#: cps/admin.py:1131 +#: cps/admin.py:1154 #, python-format msgid "LDAP Group Object Filter Needs to Have One \"%s\" Format Identifier" msgstr "Το Αντικείμενο Φίλτρου Ομάδας LDAP Πρέπει να Έχει Μια \"%s\" Αναγνώριση Μορφής" -#: cps/admin.py:1133 +#: cps/admin.py:1156 msgid "LDAP Group Object Filter Has Unmatched Parenthesis" msgstr "Το Αντικείμενο Φίλτρου Ομάδας LDAP Έχει Παρενθέσεις Που Δεν Ταιριάζουν" -#: cps/admin.py:1137 +#: cps/admin.py:1160 #, python-format msgid "LDAP User Object Filter needs to Have One \"%s\" Format Identifier" msgstr "Το Αντικείμενο Φίλτρου Χρήστη LDAP πρέπει να Έχει Μια \"%s\" Αναγνώριση Μορφής" -#: cps/admin.py:1139 +#: cps/admin.py:1162 msgid "LDAP User Object Filter Has Unmatched Parenthesis" msgstr "Το Αντικείμενο Φίλτρου Χρήστη LDAP Έχει Παρενθέσεις Που Δεν Ταιριάζουν" -#: cps/admin.py:1146 +#: cps/admin.py:1169 #, python-format msgid "LDAP Member User Filter needs to Have One \"%s\" Format Identifier" msgstr "" -#: cps/admin.py:1148 +#: cps/admin.py:1171 msgid "LDAP Member User Filter Has Unmatched Parenthesis" msgstr "" -#: cps/admin.py:1155 +#: cps/admin.py:1178 msgid "LDAP CACertificate, Certificate or Key Location is not Valid, Please Enter Correct Path" msgstr "" -#: cps/admin.py:1197 cps/admin.py:1308 cps/admin.py:1405 cps/admin.py:1521 -#: cps/admin.py:1590 cps/shelf.py:100 cps/shelf.py:160 cps/shelf.py:203 -#: cps/shelf.py:279 cps/shelf.py:341 cps/shelf.py:376 cps/shelf.py:451 -msgid "Settings DB is not Writeable" -msgstr "Οι ρυθμίσεις DB δεν μπορούν να Γραφτούν" - -#: cps/admin.py:1208 -msgid "DB Location is not Valid, Please Enter Correct Path" -msgstr "Η Τοποθεσία DB δεν είναι Έγκυρη, Παρακαλούμε Συμπληρώστε Τη Σωστή Πορεία" - -#: cps/admin.py:1223 -msgid "DB is not Writeable" -msgstr "Η DB δεν μπορεί να Γραφτεί" - -#: cps/admin.py:1235 -msgid "Keyfile Location is not Valid, Please Enter Correct Path" -msgstr "Το Αρχειο Κλειδί Τοποθεσίας δεν είναι Έγκυρο, Παρακαλούμε Συμπληρώστε Τη Σωστή Πορεία" - -#: cps/admin.py:1239 -msgid "Certfile Location is not Valid, Please Enter Correct Path" -msgstr "Η Τοποθεσία Certfile δεν είναι Έγκυρη, Παρακαλούμε Συμπληρώστε Τη Σωστή Πορεία" - -#: cps/admin.py:1346 -#, fuzzy -msgid "Database Settings updated" -msgstr "Ενημερώθηκαν οι ρυθμίσεις E-mail διακομιστή" - -#: cps/admin.py:1354 -#, fuzzy -msgid "Database Configuration" -msgstr "Διαμόρφωση Λειτουργίας" - -#: cps/admin.py:1370 cps/web.py:1479 -msgid "Please fill out all fields!" -msgstr "Παρακαλούμε συμπλήρωσε όλα τα πεδία!" - -#: cps/admin.py:1378 -msgid "E-mail is not from valid domain" -msgstr "Το E-mail δεν είναι από έγκυρο domain" - -#: cps/admin.py:1384 cps/admin.py:1543 -msgid "Add new user" -msgstr "Προσθήκη νέου χρήστη" - -#: cps/admin.py:1395 -#, python-format -msgid "User '%(user)s' created" -msgstr "Χρήστης/ες '%(user)s' δημιουργήθηκαν" - -#: cps/admin.py:1401 -#, fuzzy -msgid "Found an existing account for this e-mail address or name." -msgstr "Βρέθηκε ένας ήδη υπάρχον λογαριασμός για αυτή τη διεύθυνση e-mail ή όνομα χρήστη." - -#: cps/admin.py:1430 -#, python-format -msgid "User '%(nick)s' deleted" -msgstr "Χρήστης/ες '%(nick)s' διαγράφηκαν" - -#: cps/admin.py:1432 cps/admin.py:1433 -msgid "Can't delete Guest User" -msgstr "" - -#: cps/admin.py:1436 -msgid "No admin user remaining, can't delete user" -msgstr "Δεν έχει απομείνει χρήστης διαχειριστής, δεν μπορεί να διαγραφεί ο χρήστης" - -#: cps/admin.py:1509 cps/admin.py:1634 -#, python-format -msgid "Edit User %(nick)s" -msgstr "Επεξεργασία χρήστη %(nick)s" - -#: cps/admin.py:1513 -#, python-format -msgid "User '%(nick)s' updated" -msgstr "Χρήστης/ες '%(nick)s' ενημερώθηκαν" - -#: cps/admin.py:1517 cps/admin.py:1649 cps/web.py:1504 cps/web.py:1564 -msgid "An unknown error occurred. Please try again later." -msgstr "Προέκυψε ένα άγνωστο σφάλμα. Παρακαλούμε δοκίμασε ξανά αργότερα." - -#: cps/admin.py:1552 cps/templates/admin.html:98 -msgid "Edit E-mail Server Settings" -msgstr "Επεξεργασία Ρυθμίσεων E-mail Διακομιστή" - -#: cps/admin.py:1571 -msgid "Gmail Account Verification Successful" -msgstr "" - -#: cps/admin.py:1597 -#, python-format -msgid "Test e-mail queued for sending to %(email)s, please check Tasks for result" -msgstr "" - -#: cps/admin.py:1600 -#, python-format -msgid "There was an error sending the Test e-mail: %(res)s" -msgstr "Παρουσιάστηκε σφάλμα κατά την αποστολή του δοκιμαστικού e-mail:% (res)s" - -#: cps/admin.py:1602 -msgid "Please configure your e-mail address first..." -msgstr "Παρακαλούμε ρύθμισε πρώτα τη διεύθυνση e-mail σου..." - -#: cps/admin.py:1604 -msgid "E-mail server settings updated" -msgstr "Ενημερώθηκαν οι ρυθμίσεις E-mail διακομιστή" - -#: cps/admin.py:1646 -#, python-format -msgid "Password for user %(user)s reset" -msgstr "Κωδικός για επαναφορά %(user) χρήστη/ών" - -#: cps/admin.py:1652 cps/web.py:1444 -msgid "Please configure the SMTP mail settings first..." -msgstr "Παρακαλούμε διαμόρφωσε πρώτα τις ρυθμίσεις ταχυδρομείου SMTP..." - -#: cps/admin.py:1663 -msgid "Logfile viewer" -msgstr "Προβολέας αρχείου φύλλου καταγραφής" - -#: cps/admin.py:1729 -msgid "Requesting update package" -msgstr "Αίτημα πακέτου ενημέρωσης" - -#: cps/admin.py:1730 -msgid "Downloading update package" -msgstr "Κατεβάζει πακέτο ενημέρωσης" - -#: cps/admin.py:1731 -msgid "Unzipping update package" -msgstr "Ανοίγει πακέτο ενημέρωσης" - -#: cps/admin.py:1732 -msgid "Replacing files" -msgstr "Αντικατάσταση αρχείων" - -#: cps/admin.py:1733 -msgid "Database connections are closed" -msgstr "Οι συνδέσεις βάσης δεδομένων είναι κλειστές" - -#: cps/admin.py:1734 -msgid "Stopping server" -msgstr "Σταματάει το διακομιστή" - -#: cps/admin.py:1735 -msgid "Update finished, please press okay and reload page" -msgstr "Η ενημέρωση τελειώσε, παρακαλούμε πιέστε το εντάξει και φορτώστε ξανά τη σελίδα" - -#: cps/admin.py:1736 cps/admin.py:1737 cps/admin.py:1738 cps/admin.py:1739 -#: cps/admin.py:1740 cps/admin.py:1741 -msgid "Update failed:" -msgstr "Η ενημέρωση απέτυχε:" - -#: cps/admin.py:1736 cps/updater.py:385 cps/updater.py:595 cps/updater.py:597 -msgid "HTTP Error" -msgstr "HTTP Σφάλμα" - -#: cps/admin.py:1737 cps/updater.py:387 cps/updater.py:599 -msgid "Connection error" -msgstr "Σφάλμα σύνδεσης" - -#: cps/admin.py:1738 cps/updater.py:389 cps/updater.py:601 -msgid "Timeout while establishing connection" -msgstr "Τελείωσε ο χρόνος κατά την προσπάθεια δημιουργίας σύνδεσης" - -#: cps/admin.py:1739 cps/updater.py:391 cps/updater.py:603 -msgid "General error" -msgstr "Γενικό σφάλμα" - -#: cps/admin.py:1740 -#, fuzzy -msgid "Update file could not be saved in temp dir" -msgstr "Το Αρχείο Ενημέρωσης Δεν Μπόρεσε Να Αποθηκευτεί σε" - -#: cps/admin.py:1741 -msgid "Files could not be replaced during update" -msgstr "" - -#: cps/admin.py:1765 -#, fuzzy -msgid "Failed to extract at least One LDAP User" -msgstr "Αποτυχία Δημιουργίας Τουλάχιστον Ενός Χρήστη LDAP" - -#: cps/admin.py:1810 -msgid "Failed to Create at Least One LDAP User" -msgstr "Αποτυχία Δημιουργίας Τουλάχιστον Ενός Χρήστη LDAP" - -#: cps/admin.py:1823 -#, python-format -msgid "Error: %(ldaperror)s" -msgstr "Σφάλμα: %(ldaperror)s" - -#: cps/admin.py:1827 -msgid "Error: No user returned in response of LDAP server" -msgstr "Σφάλμα: Δεν επιστράφηκε χρήστης σε απάντηση του διακομιστή LDAP" - -#: cps/admin.py:1860 -msgid "At Least One LDAP User Not Found in Database" -msgstr "Τουλάχιστον Ένας Χρήστης LDAP Δεν Βρέθηκε Στη Βάση Δεδομένων" - -#: cps/admin.py:1862 -msgid "{} User Successfully Imported" -msgstr "" - -#: cps/converter.py:30 -msgid "not configured" -msgstr "δεν διαμορφώθηκε" - -#: cps/converter.py:32 -msgid "Execution permissions missing" -msgstr "Λείπουν άδειες εκτέλεσης" - -#: cps/db.py:651 cps/web.py:667 cps/web.py:1155 -#, python-format -msgid "Custom Column No.%(column)d is not existing in calibre database" -msgstr "Η ειδικά προσαρμοσμένη στήλη No.%(column)d δεν υπάρχει στο επίπεδο βάσης δεδομένων" - -#: cps/editbooks.py:300 cps/editbooks.py:302 -msgid "Book Format Successfully Deleted" -msgstr "Η μορφή βιβλίου Διαγράφηκε Επιτυχώς" - -#: cps/editbooks.py:309 cps/editbooks.py:311 -msgid "Book Successfully Deleted" -msgstr "Το Βιβλίο Διαγράφηκε Επιτυχώς" - -#: cps/editbooks.py:361 -msgid "You are missing permissions to delete books" -msgstr "" - -#: cps/editbooks.py:376 cps/editbooks.py:763 cps/web.py:523 cps/web.py:1703 -#: cps/web.py:1744 cps/web.py:1811 -msgid "Oops! Selected book title is unavailable. File does not exist or is not accessible" -msgstr "Oυπς! Ο επιλεγμένος τίτλος βιβλίου δεν είναι διαθέσιμος. Το αρχείο δεν υπάρχει ή δεν είναι προσβάσιμο" - -#: cps/editbooks.py:410 -msgid "edit metadata" -msgstr "επεξεργασία μεταδεδομένων" - -#: cps/editbooks.py:458 -#, python-format -msgid "%(seriesindex)s is not a valid number, skipping" -msgstr "" - -#: cps/editbooks.py:494 cps/editbooks.py:958 -#, fuzzy, python-format -msgid "'%(langname)s' is not a valid language" -msgstr "%(langname)s δεν είναι μια έγκυρη γλώσσα" - -#: cps/editbooks.py:634 cps/editbooks.py:985 -#, python-format -msgid "File extension '%(ext)s' is not allowed to be uploaded to this server" -msgstr "Η επέκταση αρχείου '%(ext)s' δεν επιτρέπεται να ανέβει σε αυτό το διακομιστή" - -#: cps/editbooks.py:638 cps/editbooks.py:989 -msgid "File to be uploaded must have an extension" -msgstr "Το αρχείο προς ανέβασμα πρέπει να έχει μια επέκταση" - -#: cps/editbooks.py:650 -#, python-format -msgid "Failed to create path %(path)s (Permission denied)." -msgstr "Αποτυχεία δημιουργίας πορείας %(path)s (Η άδεια απορρήφθηκε)." - -#: cps/editbooks.py:655 -#, python-format -msgid "Failed to store file %(file)s." -msgstr "Αποτυχία αποθήκευσης αρχείου %(file)s." - -#: cps/editbooks.py:673 cps/editbooks.py:1076 cps/web.py:1664 +#: cps/admin.py:1223 cps/admin.py:1339 cps/admin.py:1437 cps/admin.py:1554 +#: cps/admin.py:1623 cps/editbooks.py:678 cps/editbooks.py:882 +#: cps/editbooks.py:1130 cps/shelf.py:100 cps/shelf.py:160 cps/shelf.py:203 +#: cps/shelf.py:278 cps/shelf.py:343 cps/shelf.py:380 cps/shelf.py:456 +#: cps/web.py:1742 #, python-format msgid "Database error: %(error)s." msgstr "Σφάλμα βάσης δεδομένων: %(error)s." -#: cps/editbooks.py:678 +#: cps/admin.py:1235 +msgid "DB Location is not Valid, Please Enter Correct Path" +msgstr "Η Τοποθεσία DB δεν είναι Έγκυρη, Παρακαλούμε Συμπληρώστε Τη Σωστή Πορεία" + +#: cps/admin.py:1253 +msgid "DB is not Writeable" +msgstr "Η DB δεν μπορεί να Γραφτεί" + +#: cps/admin.py:1266 +msgid "Keyfile Location is not Valid, Please Enter Correct Path" +msgstr "Το Αρχειο Κλειδί Τοποθεσίας δεν είναι Έγκυρο, Παρακαλούμε Συμπληρώστε Τη Σωστή Πορεία" + +#: cps/admin.py:1270 +msgid "Certfile Location is not Valid, Please Enter Correct Path" +msgstr "Η Τοποθεσία Certfile δεν είναι Έγκυρη, Παρακαλούμε Συμπληρώστε Τη Σωστή Πορεία" + +#: cps/admin.py:1378 +#, fuzzy +msgid "Database Settings updated" +msgstr "Ενημερώθηκαν οι ρυθμίσεις E-mail διακομιστή" + +#: cps/admin.py:1386 +#, fuzzy +msgid "Database Configuration" +msgstr "Διαμόρφωση Λειτουργίας" + +#: cps/admin.py:1402 cps/web.py:1557 +msgid "Please fill out all fields!" +msgstr "Παρακαλούμε συμπλήρωσε όλα τα πεδία!" + +#: cps/admin.py:1410 +msgid "E-mail is not from valid domain" +msgstr "Το E-mail δεν είναι από έγκυρο domain" + +#: cps/admin.py:1416 cps/admin.py:1576 +msgid "Add new user" +msgstr "Προσθήκη νέου χρήστη" + +#: cps/admin.py:1427 +#, python-format +msgid "User '%(user)s' created" +msgstr "Χρήστης/ες '%(user)s' δημιουργήθηκαν" + +#: cps/admin.py:1433 +#, fuzzy +msgid "Found an existing account for this e-mail address or name." +msgstr "Βρέθηκε ένας ήδη υπάρχον λογαριασμός για αυτή τη διεύθυνση e-mail ή όνομα χρήστη." + +#: cps/admin.py:1463 +#, python-format +msgid "User '%(nick)s' deleted" +msgstr "Χρήστης/ες '%(nick)s' διαγράφηκαν" + +#: cps/admin.py:1465 cps/admin.py:1466 +msgid "Can't delete Guest User" +msgstr "" + +#: cps/admin.py:1469 +msgid "No admin user remaining, can't delete user" +msgstr "Δεν έχει απομείνει χρήστης διαχειριστής, δεν μπορεί να διαγραφεί ο χρήστης" + +#: cps/admin.py:1542 cps/admin.py:1667 +#, python-format +msgid "Edit User %(nick)s" +msgstr "Επεξεργασία χρήστη %(nick)s" + +#: cps/admin.py:1546 +#, python-format +msgid "User '%(nick)s' updated" +msgstr "Χρήστης/ες '%(nick)s' ενημερώθηκαν" + +#: cps/admin.py:1550 cps/admin.py:1682 cps/web.py:1582 cps/web.py:1642 +msgid "An unknown error occurred. Please try again later." +msgstr "Προέκυψε ένα άγνωστο σφάλμα. Παρακαλούμε δοκίμασε ξανά αργότερα." + +#: cps/admin.py:1585 cps/templates/admin.html:100 +msgid "Edit E-mail Server Settings" +msgstr "Επεξεργασία Ρυθμίσεων E-mail Διακομιστή" + +#: cps/admin.py:1604 +msgid "Gmail Account Verification Successful" +msgstr "" + +#: cps/admin.py:1630 +#, python-format +msgid "Test e-mail queued for sending to %(email)s, please check Tasks for result" +msgstr "" + +#: cps/admin.py:1633 +#, python-format +msgid "There was an error sending the Test e-mail: %(res)s" +msgstr "Παρουσιάστηκε σφάλμα κατά την αποστολή του δοκιμαστικού e-mail:% (res)s" + +#: cps/admin.py:1635 +msgid "Please configure your e-mail address first..." +msgstr "Παρακαλούμε ρύθμισε πρώτα τη διεύθυνση e-mail σου..." + +#: cps/admin.py:1637 +msgid "E-mail server settings updated" +msgstr "Ενημερώθηκαν οι ρυθμίσεις E-mail διακομιστή" + +#: cps/admin.py:1679 +#, python-format +msgid "Password for user %(user)s reset" +msgstr "Κωδικός για επαναφορά %(user) χρήστη/ών" + +#: cps/admin.py:1685 cps/web.py:1522 +msgid "Please configure the SMTP mail settings first..." +msgstr "Παρακαλούμε διαμόρφωσε πρώτα τις ρυθμίσεις ταχυδρομείου SMTP..." + +#: cps/admin.py:1696 +msgid "Logfile viewer" +msgstr "Προβολέας αρχείου φύλλου καταγραφής" + +#: cps/admin.py:1762 +msgid "Requesting update package" +msgstr "Αίτημα πακέτου ενημέρωσης" + +#: cps/admin.py:1763 +msgid "Downloading update package" +msgstr "Κατεβάζει πακέτο ενημέρωσης" + +#: cps/admin.py:1764 +msgid "Unzipping update package" +msgstr "Ανοίγει πακέτο ενημέρωσης" + +#: cps/admin.py:1765 +msgid "Replacing files" +msgstr "Αντικατάσταση αρχείων" + +#: cps/admin.py:1766 +msgid "Database connections are closed" +msgstr "Οι συνδέσεις βάσης δεδομένων είναι κλειστές" + +#: cps/admin.py:1767 +msgid "Stopping server" +msgstr "Σταματάει το διακομιστή" + +#: cps/admin.py:1768 +msgid "Update finished, please press okay and reload page" +msgstr "Η ενημέρωση τελειώσε, παρακαλούμε πιέστε το εντάξει και φορτώστε ξανά τη σελίδα" + +#: cps/admin.py:1769 cps/admin.py:1770 cps/admin.py:1771 cps/admin.py:1772 +#: cps/admin.py:1773 cps/admin.py:1774 +msgid "Update failed:" +msgstr "Η ενημέρωση απέτυχε:" + +#: cps/admin.py:1769 cps/updater.py:384 cps/updater.py:619 cps/updater.py:621 +msgid "HTTP Error" +msgstr "HTTP Σφάλμα" + +#: cps/admin.py:1770 cps/updater.py:386 cps/updater.py:623 +msgid "Connection error" +msgstr "Σφάλμα σύνδεσης" + +#: cps/admin.py:1771 cps/updater.py:388 cps/updater.py:625 +msgid "Timeout while establishing connection" +msgstr "Τελείωσε ο χρόνος κατά την προσπάθεια δημιουργίας σύνδεσης" + +#: cps/admin.py:1772 cps/updater.py:390 cps/updater.py:627 +msgid "General error" +msgstr "Γενικό σφάλμα" + +#: cps/admin.py:1773 +#, fuzzy +msgid "Update file could not be saved in temp dir" +msgstr "Το Αρχείο Ενημέρωσης Δεν Μπόρεσε Να Αποθηκευτεί σε" + +#: cps/admin.py:1774 +msgid "Files could not be replaced during update" +msgstr "" + +#: cps/admin.py:1798 +#, fuzzy +msgid "Failed to extract at least One LDAP User" +msgstr "Αποτυχία Δημιουργίας Τουλάχιστον Ενός Χρήστη LDAP" + +#: cps/admin.py:1843 +msgid "Failed to Create at Least One LDAP User" +msgstr "Αποτυχία Δημιουργίας Τουλάχιστον Ενός Χρήστη LDAP" + +#: cps/admin.py:1856 +#, python-format +msgid "Error: %(ldaperror)s" +msgstr "Σφάλμα: %(ldaperror)s" + +#: cps/admin.py:1860 +msgid "Error: No user returned in response of LDAP server" +msgstr "Σφάλμα: Δεν επιστράφηκε χρήστης σε απάντηση του διακομιστή LDAP" + +#: cps/admin.py:1893 +msgid "At Least One LDAP User Not Found in Database" +msgstr "Τουλάχιστον Ένας Χρήστης LDAP Δεν Βρέθηκε Στη Βάση Δεδομένων" + +#: cps/admin.py:1895 +msgid "{} User Successfully Imported" +msgstr "" + +#: cps/converter.py:30 +msgid "not installed" +msgstr "δεν εγκαταστάθηκε" + +#: cps/converter.py:31 +msgid "Execution permissions missing" +msgstr "Λείπουν άδειες εκτέλεσης" + +#: cps/db.py:674 cps/web.py:710 cps/web.py:1222 +#, python-format +msgid "Custom Column No.%(column)d is not existing in calibre database" +msgstr "Η ειδικά προσαρμοσμένη στήλη No.%(column)d δεν υπάρχει στο επίπεδο βάσης δεδομένων" + +#: cps/db.py:917 cps/templates/config_edit.html:204 +#: cps/templates/config_view_edit.html:62 cps/templates/email_edit.html:41 +#: cps/web.py:551 cps/web.py:585 cps/web.py:646 cps/web.py:671 cps/web.py:1003 +#: cps/web.py:1032 cps/web.py:1066 cps/web.py:1093 cps/web.py:1132 +msgid "None" +msgstr "Κανένα" + +#: cps/editbooks.py:295 cps/editbooks.py:297 +msgid "Book Format Successfully Deleted" +msgstr "Η μορφή βιβλίου Διαγράφηκε Επιτυχώς" + +#: cps/editbooks.py:304 cps/editbooks.py:306 +msgid "Book Successfully Deleted" +msgstr "Το Βιβλίο Διαγράφηκε Επιτυχώς" + +#: cps/editbooks.py:358 +msgid "You are missing permissions to delete books" +msgstr "" + +#: cps/editbooks.py:373 cps/editbooks.py:765 cps/web.py:518 cps/web.py:1783 +#: cps/web.py:1825 cps/web.py:1870 +msgid "Oops! Selected book title is unavailable. File does not exist or is not accessible" +msgstr "Oυπς! Ο επιλεγμένος τίτλος βιβλίου δεν είναι διαθέσιμος. Το αρχείο δεν υπάρχει ή δεν είναι προσβάσιμο" + +#: cps/editbooks.py:408 +msgid "edit metadata" +msgstr "επεξεργασία μεταδεδομένων" + +#: cps/editbooks.py:457 +#, python-format +msgid "%(seriesindex)s is not a valid number, skipping" +msgstr "" + +#: cps/editbooks.py:493 cps/editbooks.py:1001 +#, fuzzy, python-format +msgid "'%(langname)s' is not a valid language" +msgstr "%(langname)s δεν είναι μια έγκυρη γλώσσα" + +#: cps/editbooks.py:634 +msgid "User has no rights to upload additional file formats" +msgstr "" + +#: cps/editbooks.py:639 cps/editbooks.py:1029 +#, python-format +msgid "File extension '%(ext)s' is not allowed to be uploaded to this server" +msgstr "Η επέκταση αρχείου '%(ext)s' δεν επιτρέπεται να ανέβει σε αυτό το διακομιστή" + +#: cps/editbooks.py:643 cps/editbooks.py:1033 +msgid "File to be uploaded must have an extension" +msgstr "Το αρχείο προς ανέβασμα πρέπει να έχει μια επέκταση" + +#: cps/editbooks.py:655 +#, python-format +msgid "Failed to create path %(path)s (Permission denied)." +msgstr "Αποτυχεία δημιουργίας πορείας %(path)s (Η άδεια απορρήφθηκε)." + +#: cps/editbooks.py:660 +#, python-format +msgid "Failed to store file %(file)s." +msgstr "Αποτυχία αποθήκευσης αρχείου %(file)s." + +#: cps/editbooks.py:683 #, python-format msgid "File format %(ext)s added to %(book)s" msgstr "Μορφή αρχείου %(ext)s προστέθηκε σε %(book)s" -#: cps/editbooks.py:814 +#: cps/editbooks.py:697 cps/editbooks.py:809 +msgid "User has no rights to upload cover" +msgstr "" + +#: cps/editbooks.py:828 msgid "Identifiers are not Case Sensitive, Overwriting Old Identifier" msgstr "Τα αναγνωριστικά δεν έχουν Διάκριση Πεζών-Κεφαλαίων Γραμμάτων, Αντικατάσταση Παλιού Αναγνωριστικού" -#: cps/editbooks.py:848 +#: cps/editbooks.py:869 msgid "Metadata successfully updated" msgstr "Τα μεταδεδομένα ενημερώθηκαν επιτυχώς" -#: cps/editbooks.py:861 -msgid "Error editing book, please check logfile for details" -msgstr "Σφάλμα επεξεργασίας βιβλίου, παρακαλούμε έλεγξε το φύλλο καταγραφής για λεπτομέρειες" +#: cps/editbooks.py:887 +msgid "Error editing book: {}" +msgstr "" -#: cps/editbooks.py:899 +#: cps/editbooks.py:951 msgid "Uploaded book probably exists in the library, consider to change before upload new: " msgstr "Το βιβλίο που ανέβηκε πιθανόν να υπάρχει στη βιβλιοθήκη, σκέψου να το αλλάξεις πριν ανεβάσεις νέο: " -#: cps/editbooks.py:997 +#: cps/editbooks.py:1041 #, python-format msgid "File %(filename)s could not saved to temp dir" msgstr "Το αρχείο %(filename)s δεν μπόρεσε να αποθηκευτεί σε temp dir" -#: cps/editbooks.py:1016 +#: cps/editbooks.py:1061 #, python-format msgid "Failed to Move Cover File %(file)s: %(error)s" msgstr "Αποτυχία Μετακίνησης Αρχείου Φόντου %(file)s: %(error)s" -#: cps/editbooks.py:1063 +#: cps/editbooks.py:1117 #, python-format msgid "File %(file)s uploaded" msgstr "Το αρχείο %(file)s ανέβηκε" -#: cps/editbooks.py:1088 +#: cps/editbooks.py:1143 msgid "Source or destination format for conversion missing" msgstr "Η δομή πηγής ή προορισμού για μετατροπή λείπει" -#: cps/editbooks.py:1096 +#: cps/editbooks.py:1151 #, python-format msgid "Book successfully queued for converting to %(book_format)s" msgstr "Το βιβλίο είναι σε σειρά επιτυχώς για μετατροπή σε %(book_format)s" -#: cps/editbooks.py:1100 +#: cps/editbooks.py:1155 #, python-format msgid "There was an error converting this book: %(res)s" msgstr "Υπήρξε ένα σφάλμα στη μετατροπή αυτού του βιβλίου: %(res)s" @@ -610,175 +613,192 @@ msgstr "Η ρύθμιση του Google Drive δεν ολοκληρώθηκε, msgid "Callback domain is not verified, please follow steps to verify domain in google developer console" msgstr "Η ανάκληση ονόματος δεν έχει επαληθευτεί, παρακαλούμε ακολούθησε τα βήματα για την επαλήθευση ονόματος στην κονσόλα προγραμματιστή google" -#: cps/helper.py:77 +#: cps/helper.py:81 #, python-format msgid "%(format)s format not found for book id: %(book)d" msgstr "%(format)s η δομή δεν βρέθηκε για την ταυτότητα βιβλίου: %(book)d" -#: cps/helper.py:83 cps/tasks/convert.py:73 +#: cps/helper.py:87 cps/tasks/convert.py:75 #, python-format msgid "%(format)s not found on Google Drive: %(fn)s" msgstr "%(format)s δεν βρέθηκε στο Google Drive: %(fn)s" -#: cps/helper.py:88 +#: cps/helper.py:92 #, python-format msgid "%(format)s not found: %(fn)s" msgstr "%(format)s δεν βρέθηκε: %(fn)s" -#: cps/helper.py:93 cps/helper.py:217 cps/templates/detail.html:41 +#: cps/helper.py:97 cps/helper.py:221 cps/templates/detail.html:41 #: cps/templates/detail.html:45 msgid "Send to Kindle" msgstr "Αποστολή στο Kindle" -#: cps/helper.py:94 cps/helper.py:111 cps/helper.py:219 +#: cps/helper.py:98 cps/helper.py:115 cps/helper.py:223 msgid "This e-mail has been sent via Calibre-Web." msgstr "Αυτό το e-mail έχει σταλεί μέσω Calibre-Web." -#: cps/helper.py:109 +#: cps/helper.py:113 msgid "Calibre-Web test e-mail" msgstr "Calibre-Web δοκιμαστικό e-mail" -#: cps/helper.py:110 +#: cps/helper.py:114 msgid "Test e-mail" msgstr "Δοκιμαστικό e-mail" -#: cps/helper.py:127 +#: cps/helper.py:131 msgid "Get Started with Calibre-Web" msgstr "Ξεκινήστε με το Calibre-Web" -#: cps/helper.py:132 +#: cps/helper.py:136 #, python-format msgid "Registration e-mail for user: %(name)s" msgstr "e-mail εγγραφής για χρήστη: %(name)s" -#: cps/helper.py:143 cps/helper.py:149 +#: cps/helper.py:147 cps/helper.py:153 #, python-format msgid "Convert %(orig)s to %(format)s and send to Kindle" msgstr "Μετατροπή %(orig)s σε %(format)s και αποστολή στο Kindle" -#: cps/helper.py:168 cps/helper.py:172 cps/helper.py:176 +#: cps/helper.py:172 cps/helper.py:176 cps/helper.py:180 #, python-format msgid "Send %(format)s to Kindle" msgstr "Αποστολή %(format)s στο Kindle" -#: cps/helper.py:216 cps/tasks/convert.py:90 +#: cps/helper.py:220 cps/tasks/convert.py:92 #, fuzzy, python-format msgid "%(book)s send to Kindle" msgstr "Αποστολή στο Kindle" -#: cps/helper.py:221 +#: cps/helper.py:225 msgid "The requested file could not be read. Maybe wrong permissions?" msgstr "Το αρχείου που χητήθηκε δεν μπορεί να διαβαστεί. Μπορεί να υπάρχουν λαθασμένες άδειες;" -#: cps/helper.py:313 +#: cps/helper.py:353 +msgid "Read status could not set: {}" +msgstr "" + +#: cps/helper.py:376 #, python-format msgid "Deleting bookfolder for book %(id)s failed, path has subfolders: %(path)s" msgstr "Η διαγραφή φακέλου βιβλίου για το βιβλίο %(id)s απέτυχε, η πορεία έχει υπό-φακέλους: %(path)s" -#: cps/helper.py:319 +#: cps/helper.py:382 #, python-format msgid "Deleting book %(id)s failed: %(message)s" msgstr "Η διαγραφή βιβλίου %(id)s απέτυχε: %(message)s" -#: cps/helper.py:330 +#: cps/helper.py:393 #, fuzzy, python-format msgid "Deleting book %(id)s from database only, book path in database not valid: %(path)s" msgstr "Διαγραφή βιβλίου %(id)s, η πορεία βιβλίου δεν είναι έγκυρη: %(path)s" -#: cps/helper.py:385 -#, python-format -msgid "Rename title from: '%(src)s' to '%(dest)s' failed with error: %(error)s" +#: cps/helper.py:458 +#, fuzzy, python-format +msgid "Rename author from: '%(src)s' to '%(dest)s' failed with error: %(error)s" msgstr "Η μετονομασία τίτλου από: '%(src)s' σε '%(dest)s' απέτυχε με σφάλμα: %(error)s" -#: cps/helper.py:400 -#, python-format -msgid "Rename file in path '%(src)s' to '%(dest)s' failed with error: %(error)s" -msgstr "Η μετονομασία αρχείου σε πορεία '%(src)s' σε '%(dest)s' απέτυχε με σφάλμα: %(error)s" - -#: cps/helper.py:425 cps/helper.py:435 cps/helper.py:443 +#: cps/helper.py:529 cps/helper.py:538 #, python-format msgid "File %(file)s not found on Google Drive" msgstr "Το αρχείο %(file)s δεν βρέθηκε στο Google Drive" -#: cps/helper.py:464 +#: cps/helper.py:572 +#, python-format +msgid "Rename title from: '%(src)s' to '%(dest)s' failed with error: %(error)s" +msgstr "Η μετονομασία τίτλου από: '%(src)s' σε '%(dest)s' απέτυχε με σφάλμα: %(error)s" + +#: cps/helper.py:592 +msgid "Error in rename file in path: {}" +msgstr "" + +#: cps/helper.py:610 #, python-format msgid "Book path %(path)s not found on Google Drive" msgstr "Η πορεία βιβλίου %(path)s δεν βρέθηκε στο Google Drive" -#: cps/helper.py:504 cps/web.py:1659 +#: cps/helper.py:651 cps/web.py:1737 #, fuzzy msgid "Found an existing account for this e-mail address" msgstr "Βρέθηκε ένας ήδη υπάρχον λογαριασμός για αυτή τη διεύθυνση e-mail." -#: cps/helper.py:512 +#: cps/helper.py:659 msgid "This username is already taken" msgstr "Αυτό το όνομα χρήστη έχει ήδη παρθεί" -#: cps/helper.py:522 +#: cps/helper.py:669 msgid "Invalid e-mail address format" msgstr "" -#: cps/helper.py:595 +#: cps/helper.py:754 +msgid "Python modul 'advocate' is not installed but is needed for cover downloads" +msgstr "" + +#: cps/helper.py:767 msgid "Error Downloading Cover" msgstr "Σφάλμα Κατεβάσματος Φόντου" -#: cps/helper.py:598 +#: cps/helper.py:770 msgid "Cover Format Error" msgstr "Σφάλμα Μορφής Φόντου" -#: cps/helper.py:608 +#: cps/helper.py:773 +msgid "You are not allowed to access localhost or the local network for cover uploads" +msgstr "" + +#: cps/helper.py:783 msgid "Failed to create path for cover" msgstr "Αποτυχία δημιουργίας πορείας για φόντο" -#: cps/helper.py:624 +#: cps/helper.py:799 msgid "Cover-file is not a valid image file, or could not be stored" msgstr "Το αρχείο φόντου δεν είναι ένα έγκυρο αρχείο εικόνας, ή δεν μπόρεσε να αποθηκευτεί" -#: cps/helper.py:635 +#: cps/helper.py:810 msgid "Only jpg/jpeg/png/webp/bmp files are supported as coverfile" msgstr "" -#: cps/helper.py:648 +#: cps/helper.py:822 msgid "Invalid cover file content" msgstr "" -#: cps/helper.py:652 +#: cps/helper.py:826 msgid "Only jpg/jpeg files are supported as coverfile" msgstr "Μόνο jpg/jpeg αρχεία υποστηρίζονται ως αρχεία φόντου" -#: cps/helper.py:704 +#: cps/helper.py:878 msgid "Unrar binary file not found" msgstr "Δεν βρέθηκε δυαδικό αρχείο Unrar" -#: cps/helper.py:715 +#: cps/helper.py:889 msgid "Error excecuting UnRar" msgstr "Σφάλμα εκτέλεσης UnRar" -#: cps/helper.py:763 +#: cps/helper.py:937 msgid "Waiting" msgstr "Αναμονή" -#: cps/helper.py:765 +#: cps/helper.py:939 msgid "Failed" msgstr "Απέτυχε" -#: cps/helper.py:767 +#: cps/helper.py:941 msgid "Started" msgstr "Ξεκίνησε" -#: cps/helper.py:769 +#: cps/helper.py:943 msgid "Finished" msgstr "Τελείωσε" -#: cps/helper.py:771 +#: cps/helper.py:945 msgid "Unknown Status" msgstr "ʼΑγνωστη κατάσταση" -#: cps/kobo_auth.py:127 -msgid "PLease access calibre-web from non localhost to get valid api_endpoint for kobo device" +#: cps/kobo_auth.py:128 +#, fuzzy +msgid "Please access Calibre-Web from non localhost to get valid api_endpoint for kobo device" msgstr "Παρακαλούμε λάβε πρόσβαση στο calibre-web από ένα μη τοπικό εξηπηρετητή για να λάβεις μια έγκυρη api_endpoint για συσκευή kobo" -#: cps/kobo_auth.py:130 cps/kobo_auth.py:158 +#: cps/kobo_auth.py:154 msgid "Kobo Setup" msgstr "Καθορισμός Kobo" @@ -787,7 +807,7 @@ msgstr "Καθορισμός Kobo" msgid "Register with %(provider)s" msgstr "Εγγραφή με %(provider)s" -#: cps/oauth_bb.py:138 cps/remotelogin.py:133 cps/web.py:1535 +#: cps/oauth_bb.py:138 cps/remotelogin.py:130 cps/web.py:1613 #, python-format msgid "you are now logged in as: '%(nickname)s'" msgstr "τώρα έχεις συνδεθεί ως: '%(nickname)s'" @@ -848,163 +868,163 @@ msgstr "Google Oauth σφάλμα, παρακαλούμε δοκίμασε ξα msgid "Google Oauth error: {}" msgstr "" -#: cps/opds.py:384 +#: cps/opds.py:298 msgid "{} Stars" msgstr "" -#: cps/remotelogin.py:65 cps/templates/layout.html:84 -#: cps/templates/login.html:4 cps/templates/login.html:21 cps/web.py:1584 +#: cps/remotelogin.py:62 cps/templates/layout.html:84 +#: cps/templates/login.html:4 cps/templates/login.html:21 cps/web.py:1662 msgid "Login" msgstr "Σύνδεση" -#: cps/remotelogin.py:77 cps/remotelogin.py:111 +#: cps/remotelogin.py:74 cps/remotelogin.py:108 msgid "Token not found" msgstr "Η μάρκα δεν βρέθηκε" -#: cps/remotelogin.py:86 cps/remotelogin.py:119 +#: cps/remotelogin.py:83 cps/remotelogin.py:116 msgid "Token has expired" msgstr "Η μάρκα έχει λήξει" -#: cps/remotelogin.py:95 +#: cps/remotelogin.py:92 msgid "Success! Please return to your device" msgstr "Επιτυχία! Παρακαλούμε επέστρεψε στη συσκευή σου" -#: cps/render_template.py:39 cps/web.py:416 +#: cps/render_template.py:41 cps/web.py:407 msgid "Books" msgstr "Βιβλία" -#: cps/render_template.py:41 +#: cps/render_template.py:43 msgid "Show recent books" msgstr "Προβολή πρόσφατων βιβλίων" -#: cps/render_template.py:42 cps/templates/index.xml:25 +#: cps/render_template.py:44 cps/templates/index.xml:25 msgid "Hot Books" msgstr "Βιβλία στη Μόδα" -#: cps/render_template.py:44 +#: cps/render_template.py:46 msgid "Show Hot Books" msgstr "Προβολή Βιβλίων στη Μόδα" -#: cps/render_template.py:46 cps/render_template.py:51 +#: cps/render_template.py:48 cps/render_template.py:53 msgid "Downloaded Books" msgstr "Κατεβασμένα Βιβλία" -#: cps/render_template.py:48 cps/render_template.py:53 +#: cps/render_template.py:50 cps/render_template.py:55 #: cps/templates/user_table.html:167 msgid "Show Downloaded Books" msgstr "Προβολή Κατεβασμένων Βιβλίων" -#: cps/render_template.py:56 cps/templates/index.xml:32 cps/web.py:430 +#: cps/render_template.py:58 cps/templates/index.xml:32 cps/web.py:422 msgid "Top Rated Books" msgstr "Βιβλία με Κορυφαία Αξιολόγηση" -#: cps/render_template.py:58 cps/templates/user_table.html:161 +#: cps/render_template.py:60 cps/templates/user_table.html:161 msgid "Show Top Rated Books" msgstr "Προβολή Βιβλίων με Κορυφαία Αξιολόγηση" -#: cps/render_template.py:59 cps/templates/index.xml:54 -#: cps/templates/index.xml:58 cps/web.py:676 +#: cps/render_template.py:61 cps/templates/index.xml:54 +#: cps/templates/index.xml:58 cps/web.py:729 msgid "Read Books" msgstr "Βιβλία που Διαβάστηκαν" -#: cps/render_template.py:61 +#: cps/render_template.py:63 msgid "Show read and unread" msgstr "Προβολή διαβασμένων και αδιάβαστων" -#: cps/render_template.py:63 cps/templates/index.xml:61 -#: cps/templates/index.xml:65 cps/web.py:679 +#: cps/render_template.py:65 cps/templates/index.xml:61 +#: cps/templates/index.xml:65 cps/web.py:732 msgid "Unread Books" msgstr "Βιβλία που δεν Διαβάστηκαν" -#: cps/render_template.py:65 +#: cps/render_template.py:67 msgid "Show unread" msgstr "Προβολή αδιάβαστων" -#: cps/render_template.py:66 +#: cps/render_template.py:68 msgid "Discover" msgstr "Ανακάλυψε" -#: cps/render_template.py:68 cps/templates/index.xml:50 +#: cps/render_template.py:70 cps/templates/index.xml:50 #: cps/templates/user_table.html:162 msgid "Show Random Books" msgstr "Προβολή Τυχαίων Βιβλίων" -#: cps/render_template.py:69 cps/templates/book_table.html:67 -#: cps/templates/index.xml:83 cps/web.py:1041 +#: cps/render_template.py:71 cps/templates/book_table.html:67 +#: cps/templates/index.xml:83 cps/web.py:1135 msgid "Categories" msgstr "Κατηγορίες" -#: cps/render_template.py:71 cps/templates/user_table.html:158 +#: cps/render_template.py:73 cps/templates/user_table.html:158 msgid "Show category selection" msgstr "Προβολή επιλογών κατηγορίας" -#: cps/render_template.py:72 cps/templates/book_edit.html:90 +#: cps/render_template.py:74 cps/templates/book_edit.html:90 #: cps/templates/book_table.html:68 cps/templates/index.xml:90 -#: cps/templates/search_form.html:69 cps/web.py:948 cps/web.py:959 +#: cps/templates/search_form.html:69 cps/web.py:1034 cps/web.py:1041 msgid "Series" msgstr "Σειρές" -#: cps/render_template.py:74 cps/templates/user_table.html:157 +#: cps/render_template.py:76 cps/templates/user_table.html:157 msgid "Show series selection" msgstr "Προβολή επιλογών σειράς" -#: cps/render_template.py:75 cps/templates/book_table.html:66 +#: cps/render_template.py:77 cps/templates/book_table.html:66 #: cps/templates/index.xml:69 msgid "Authors" msgstr "Συγγραφείς" -#: cps/render_template.py:77 cps/templates/user_table.html:160 +#: cps/render_template.py:79 cps/templates/user_table.html:160 msgid "Show author selection" msgstr "Προβολή επιλογών συγγραφέα" -#: cps/render_template.py:79 cps/templates/book_table.html:72 -#: cps/templates/index.xml:76 cps/web.py:925 +#: cps/render_template.py:81 cps/templates/book_table.html:72 +#: cps/templates/index.xml:76 cps/web.py:1006 msgid "Publishers" msgstr "Εκδότες" -#: cps/render_template.py:81 cps/templates/user_table.html:163 +#: cps/render_template.py:83 cps/templates/user_table.html:163 msgid "Show publisher selection" msgstr "Προβολή επιλογών εκδότη" -#: cps/render_template.py:82 cps/templates/book_table.html:70 +#: cps/render_template.py:84 cps/templates/book_table.html:70 #: cps/templates/index.xml:97 cps/templates/search_form.html:107 -#: cps/web.py:1018 +#: cps/web.py:1108 msgid "Languages" msgstr "Γλώσσες" -#: cps/render_template.py:85 cps/templates/user_table.html:155 +#: cps/render_template.py:87 cps/templates/user_table.html:155 msgid "Show language selection" msgstr "Προβολή επιλογών γλώσσας" -#: cps/render_template.py:86 cps/templates/index.xml:104 +#: cps/render_template.py:88 cps/templates/index.xml:104 msgid "Ratings" msgstr "Αξιολογήσεις" -#: cps/render_template.py:88 cps/templates/user_table.html:164 +#: cps/render_template.py:90 cps/templates/user_table.html:164 msgid "Show ratings selection" msgstr "Προβολή επιλογών αξιολόγησης" -#: cps/render_template.py:89 cps/templates/index.xml:112 +#: cps/render_template.py:91 cps/templates/index.xml:112 msgid "File formats" msgstr "Μορφές αρχείου" -#: cps/render_template.py:91 cps/templates/user_table.html:165 +#: cps/render_template.py:93 cps/templates/user_table.html:165 msgid "Show file formats selection" msgstr "Προβολή επιλογών μορφής αρχείου" -#: cps/render_template.py:93 cps/web.py:703 +#: cps/render_template.py:95 cps/web.py:755 msgid "Archived Books" msgstr "Αρχειοθετημένα Βιβλία" -#: cps/render_template.py:95 cps/templates/user_table.html:166 +#: cps/render_template.py:97 cps/templates/user_table.html:166 msgid "Show archived books" msgstr "Προβολή αρχειοθετημένων βιβλίων" -#: cps/render_template.py:97 cps/web.py:780 +#: cps/render_template.py:100 cps/web.py:837 msgid "Books List" msgstr "Λίστα Βιβλίων" -#: cps/render_template.py:99 cps/templates/user_table.html:168 +#: cps/render_template.py:102 cps/templates/user_table.html:168 msgid "Show Books List" msgstr "Προβολή Λίστας Βιβλίων" @@ -1059,262 +1079,266 @@ msgstr "" msgid "Create a Shelf" msgstr "Δημιούργησε ένα Ράφι" -#: cps/shelf.py:237 +#: cps/shelf.py:236 #, fuzzy msgid "Sorry you are not allowed to edit this shelf" msgstr "Συγγνώμη αλλά δεν σου επιτρέπεται η αφαίρεση ενός βιβλίου από αυτό το ράφι: %(sname)s" -#: cps/shelf.py:239 +#: cps/shelf.py:238 msgid "Edit a shelf" msgstr "Επεξεργασία ενός ραφιού" -#: cps/shelf.py:249 +#: cps/shelf.py:248 msgid "Sorry you are not allowed to create a public shelf" msgstr "" -#: cps/shelf.py:266 +#: cps/shelf.py:265 #, python-format msgid "Shelf %(title)s created" msgstr "Το ράφι %(title)s δημιουργήθηκε" -#: cps/shelf.py:269 +#: cps/shelf.py:268 #, python-format msgid "Shelf %(title)s changed" msgstr "Το ράφι %(title)s άλλαξε" -#: cps/shelf.py:283 +#: cps/shelf.py:282 msgid "There was an error" msgstr "Υπήρξε ένα σφάλμα" -#: cps/shelf.py:305 +#: cps/shelf.py:304 #, python-format msgid "A public shelf with the name '%(title)s' already exists." msgstr "Ένα δημόσιο ράφι με το όνομα '%(title)s' υπάρχει ήδη." -#: cps/shelf.py:316 +#: cps/shelf.py:315 #, python-format msgid "A private shelf with the name '%(title)s' already exists." msgstr "Ένα ιδιωτικό ράφι με το όνομα '%(title)s' υπάρχει ήδη." #: cps/shelf.py:337 +msgid "Error deleting Shelf" +msgstr "" + +#: cps/shelf.py:339 #, fuzzy msgid "Shelf successfully deleted" msgstr "Το Βιβλίο Διαγράφηκε Επιτυχώς" -#: cps/shelf.py:386 +#: cps/shelf.py:389 #, python-format msgid "Change order of Shelf: '%(name)s'" msgstr "Αλλαγή σειράς του Ραφιού: '%(name)s'" -#: cps/shelf.py:456 +#: cps/shelf.py:461 #, python-format msgid "Shelf: '%(name)s'" msgstr "Ράφι: '%(name)s" -#: cps/shelf.py:460 +#: cps/shelf.py:465 msgid "Error opening shelf. Shelf does not exist or is not accessible" msgstr "Σφάλμα κατά το άνοιγμα του ραφιού. Το ράφι δεν υπάρχει ή δεν είναι προσβάσιμο" -#: cps/updater.py:403 cps/updater.py:414 cps/updater.py:514 cps/updater.py:529 +#: cps/updater.py:426 cps/updater.py:437 cps/updater.py:538 cps/updater.py:553 msgid "Unexpected data while reading update information" msgstr "Απρόβλεπτα δεδομένα κατά την ανάγνωση των πληροφοριών ενημέρωσης" -#: cps/updater.py:410 cps/updater.py:521 +#: cps/updater.py:433 cps/updater.py:545 msgid "No update available. You already have the latest version installed" msgstr "Δεν υπάρχει διαθέσιμη ενημέρωση. Έχεις ήδη την τελευταία έκδοση εγκατεστημένη" -#: cps/updater.py:428 +#: cps/updater.py:451 msgid "A new update is available. Click on the button below to update to the latest version." msgstr "Μια νέα ενημέρωση είναι διαθέσιμη. Κάνε κλικ στο κουμπί πιο κάτω για να ενημερώσεις με την τελευταία έκδοση." -#: cps/updater.py:446 +#: cps/updater.py:469 msgid "Could not fetch update information" msgstr "Δεν μπόρεσε να συγκεντρώσει τις πληροφορίες ενημέρωσης" -#: cps/updater.py:456 +#: cps/updater.py:479 msgid "Click on the button below to update to the latest stable version." msgstr "Κάνε κλικ στο κουμπί πιο κάτω για να ενημερώσεις με την τελευταία σταθερή έκδοση." -#: cps/updater.py:465 cps/updater.py:479 cps/updater.py:490 +#: cps/updater.py:488 cps/updater.py:502 cps/updater.py:513 #, python-format msgid "A new update is available. Click on the button below to update to version: %(version)s" msgstr "Μια νέα ενημέρωση είναι διαθέσιμη. Κάνε κλικ στο κουμπί πιο κάτω για ενημέρωση με την έκδοση: %(version)s" -#: cps/updater.py:507 +#: cps/updater.py:531 msgid "No release information available" msgstr "Δεν υπάρχουν διαθέσιμες πληροφορίες αποδέσμευσης" -#: cps/templates/index.html:5 cps/web.py:440 +#: cps/templates/index.html:5 cps/web.py:434 msgid "Discover (Random Books)" msgstr "Ανακάλυψε (Τυχαία Βιβλία)" -#: cps/web.py:471 +#: cps/web.py:470 msgid "Hot Books (Most Downloaded)" msgstr "Βιβλία στη Μόδα (Με τα περισσότερα κατεβάσματα)" -#: cps/web.py:507 +#: cps/web.py:501 #, python-format msgid "Downloaded books by %(user)s" msgstr "Κατεβασμένα βιβλία από %(user)s" -#: cps/web.py:539 +#: cps/web.py:534 #, python-format msgid "Author: %(name)s" msgstr "Συγγραφέας: %(name)s" -#: cps/web.py:554 +#: cps/web.py:570 #, python-format msgid "Publisher: %(name)s" msgstr "Εκδότης: %(name)s" -#: cps/web.py:569 +#: cps/web.py:598 #, python-format msgid "Series: %(serie)s" msgstr "Σειρές: %(serie)s" -#: cps/web.py:582 +#: cps/web.py:610 #, python-format msgid "Rating: %(rating)s stars" msgstr "Αξιολόγηση: %(rating)s stars" -#: cps/web.py:597 +#: cps/web.py:626 #, python-format msgid "File format: %(format)s" msgstr "Μορφή αρχείου: %(format)s" -#: cps/web.py:615 +#: cps/web.py:663 #, python-format msgid "Category: %(name)s" msgstr "Κατηγορία: %(name)s" -#: cps/web.py:631 +#: cps/web.py:690 #, python-format msgid "Language: %(name)s" msgstr "Γλώσσα: %(name)s" -#: cps/templates/layout.html:56 cps/web.py:737 cps/web.py:1371 +#: cps/templates/layout.html:56 cps/web.py:789 cps/web.py:1444 msgid "Advanced Search" msgstr "Προχωρημένη Αναζήτηση" #: cps/templates/book_edit.html:235 cps/templates/feed.xml:33 #: cps/templates/index.xml:11 cps/templates/layout.html:45 #: cps/templates/layout.html:48 cps/templates/search_form.html:226 -#: cps/web.py:750 cps/web.py:1077 +#: cps/web.py:807 cps/web.py:1164 msgid "Search" msgstr "Αναζήτηση" -#: cps/templates/admin.html:16 cps/web.py:903 +#: cps/templates/admin.html:16 cps/web.py:979 msgid "Downloads" msgstr "Κατεβασμένα" -#: cps/web.py:980 +#: cps/web.py:1068 msgid "Ratings list" msgstr "Λίστα αξιολογήσεων" -#: cps/web.py:1001 +#: cps/web.py:1095 msgid "File formats list" msgstr "Λίστα μορφών αρχείου" -#: cps/templates/layout.html:73 cps/templates/tasks.html:7 cps/web.py:1055 +#: cps/templates/layout.html:73 cps/templates/tasks.html:7 cps/web.py:1149 msgid "Tasks" msgstr "Εργασίες" -#: cps/web.py:1215 +#: cps/web.py:1286 msgid "Published after " msgstr "Εκδόθηκε μετά" -#: cps/web.py:1222 +#: cps/web.py:1293 msgid "Published before " msgstr "Εκδόθηκε πριν" -#: cps/web.py:1244 +#: cps/web.py:1315 #, python-format msgid "Rating <= %(rating)s" msgstr "Αξιολόγηση <= %(rating)s" -#: cps/web.py:1246 +#: cps/web.py:1317 #, python-format msgid "Rating >= %(rating)s" msgstr "Αξιολόγηση >= %(rating)s" -#: cps/web.py:1248 +#: cps/web.py:1319 #, python-format msgid "Read Status = %(status)s" msgstr "" -#: cps/web.py:1353 +#: cps/web.py:1425 msgid "Error on search for custom columns, please restart Calibre-Web" msgstr "" -#: cps/web.py:1449 +#: cps/web.py:1527 #, python-format msgid "Book successfully queued for sending to %(kindlemail)s" msgstr "Το βιβλίο έχει επιτυχώς μπει σε σειρά για αποστολή στο %(kindlemail)s" -#: cps/web.py:1453 +#: cps/web.py:1531 #, python-format msgid "Oops! There was an error sending this book: %(res)s" msgstr "Oυπς! Υπήρξε ένα σφάλμα κατά την αποστολή αυτού του βιβλίου: %(res)s" -#: cps/web.py:1455 +#: cps/web.py:1533 msgid "Please update your profile with a valid Send to Kindle E-mail Address." msgstr "Παρακαλούμε ενημέρωσε το προφίλ σου με μια έγκυρη Διεύθυνση E-mail Αποστολής στο Kindle." -#: cps/web.py:1472 +#: cps/web.py:1550 msgid "E-Mail server is not configured, please contact your administrator!" msgstr "Ο διακομιστής E-Mail δεν έχει διαμορφωθεί, παρακαλούμε επικοινώνησε με το διαχειριστή σου!" -#: cps/templates/layout.html:85 cps/templates/register.html:17 cps/web.py:1473 -#: cps/web.py:1480 cps/web.py:1486 cps/web.py:1505 cps/web.py:1509 -#: cps/web.py:1515 +#: cps/templates/layout.html:85 cps/templates/register.html:17 cps/web.py:1551 +#: cps/web.py:1558 cps/web.py:1564 cps/web.py:1583 cps/web.py:1587 +#: cps/web.py:1593 msgid "Register" msgstr "Εγγραφή" -#: cps/web.py:1507 +#: cps/web.py:1585 msgid "Your e-mail is not allowed to register" msgstr "Η διεύθυνση e-mail σου δεν επιτρέπεται να εγγραφεί" -#: cps/web.py:1510 +#: cps/web.py:1588 msgid "Confirmation e-mail was send to your e-mail account." msgstr "Το e-mail επιβεβαίωσης έχει σταλεί στον e-mail λογαριασμό σου." -#: cps/web.py:1524 +#: cps/web.py:1602 msgid "Cannot activate LDAP authentication" msgstr "Δεν μπόρεσε να ενεργοποιηθεί η επαλήθευση LDAP" -#: cps/web.py:1543 +#: cps/web.py:1621 #, python-format msgid "Fallback Login as: '%(nickname)s', LDAP Server not reachable, or user not known" msgstr "Εναλλακτική Σύνδεση ως: '%(nickname)s', Ο Διακομιστής LDAP δεν είναι προσβάσιμος, ή ο χρήστης δεν είναι γνωστός" -#: cps/web.py:1549 +#: cps/web.py:1627 #, python-format msgid "Could not login: %(message)s" msgstr "Δεν μπόρεσε να συνδεθεί: %(message)s" -#: cps/web.py:1553 cps/web.py:1578 +#: cps/web.py:1631 cps/web.py:1656 msgid "Wrong Username or Password" msgstr "Λανθασμένο Όνομα Χρήστη ή Κωδικός" -#: cps/web.py:1560 +#: cps/web.py:1638 msgid "New Password was send to your email address" msgstr "Ο Νέος Κωδικός έχει σταλεί στη διεύθυνση email σου" -#: cps/web.py:1566 +#: cps/web.py:1644 msgid "Please enter valid username to reset password" msgstr "Παρακαλούμε συμπλήρωσε ένα έγκυρο όνομα χρήστη για επαναφορά του κωδικού" -#: cps/web.py:1573 +#: cps/web.py:1651 #, python-format msgid "You are now logged in as: '%(nickname)s'" msgstr "Έχεις συνδεθεί ως: '%(nickname)s'" -#: cps/web.py:1639 cps/web.py:1688 +#: cps/web.py:1717 cps/web.py:1766 #, python-format msgid "%(name)s's profile" msgstr "%(name)s's προφίλ" -#: cps/web.py:1655 +#: cps/web.py:1733 msgid "Profile updated" msgstr "Το προφίλ ενημερώθηκε" @@ -1322,36 +1346,36 @@ msgstr "Το προφίλ ενημερώθηκε" msgid "Found no valid gmail.json file with OAuth information" msgstr "" -#: cps/tasks/convert.py:137 +#: cps/tasks/convert.py:154 #, python-format msgid "Calibre ebook-convert %(tool)s not found" msgstr "Το εργαλείο μετατροπής Calibre ebook %(tool)s δεν βρέθηκε" -#: cps/tasks/convert.py:163 +#: cps/tasks/convert.py:187 #, python-format msgid "%(format)s format not found on disk" msgstr "%(format)s μορφή δεν βρέθηκε σε δίσκο" -#: cps/tasks/convert.py:167 +#: cps/tasks/convert.py:191 msgid "Ebook converter failed with unknown error" msgstr "Ο μετατροπέας Ebook απέτυχε με άγνωστο σφάλμα" -#: cps/tasks/convert.py:177 +#: cps/tasks/convert.py:201 #, python-format msgid "Kepubify-converter failed: %(error)s" msgstr "Ο μετατροπέας Kepubify απέτυχε: %(error)s" -#: cps/tasks/convert.py:199 +#: cps/tasks/convert.py:223 #, python-format msgid "Converted file not found or more than one file in folder %(folder)s" msgstr "Το τροποποιημένο αρχείο δεν βρέθηκε ή υπάρχουν περισσότερα από ένα αρχεία στο φάκελο %(folder)s" -#: cps/tasks/convert.py:222 +#: cps/tasks/convert.py:246 #, python-format msgid "Ebook-converter failed: %(error)s" msgstr "Ο μετατροπέας Ebook απέτυχε: %(error)s" -#: cps/tasks/convert.py:245 +#: cps/tasks/convert.py:269 #, python-format msgid "Calibre failed with error: %(error)s" msgstr "Το Calibre απέτυχε με σφάλμα: %(error)s" @@ -1406,7 +1430,7 @@ msgid "Edit" msgstr "Επεξεργασία" #: cps/templates/admin.html:25 cps/templates/book_edit.html:16 -#: cps/templates/book_table.html:97 cps/templates/modal_dialogs.html:63 +#: cps/templates/book_table.html:100 cps/templates/modal_dialogs.html:63 #: cps/templates/modal_dialogs.html:116 cps/templates/user_edit.html:67 #: cps/templates/user_table.html:149 msgid "Delete" @@ -1416,180 +1440,180 @@ msgstr "Διαγραφή" msgid "Public Shelf" msgstr "Δημόσιο Ράφι" -#: cps/templates/admin.html:51 +#: cps/templates/admin.html:53 msgid "Add New User" msgstr "Προσθήκη Νέου Χρήστη" -#: cps/templates/admin.html:53 +#: cps/templates/admin.html:55 msgid "Import LDAP Users" msgstr "Εισαγωγή Χρηστών LDAP" -#: cps/templates/admin.html:60 +#: cps/templates/admin.html:62 msgid "E-mail Server Settings" msgstr "Ρυθμίσεις E-mail Διακομιστή" -#: cps/templates/admin.html:65 cps/templates/email_edit.html:31 +#: cps/templates/admin.html:67 cps/templates/email_edit.html:31 msgid "SMTP Hostname" msgstr "Όνομα Εξυπηρετητή SMTP" -#: cps/templates/admin.html:69 cps/templates/email_edit.html:35 +#: cps/templates/admin.html:71 cps/templates/email_edit.html:35 msgid "SMTP Port" msgstr "SMTP Θύρα" -#: cps/templates/admin.html:73 cps/templates/email_edit.html:39 +#: cps/templates/admin.html:75 cps/templates/email_edit.html:39 msgid "Encryption" msgstr "Κρυπτογράφηση" -#: cps/templates/admin.html:77 cps/templates/email_edit.html:47 +#: cps/templates/admin.html:79 cps/templates/email_edit.html:47 msgid "SMTP Login" msgstr "Σύνδεση SMTP" -#: cps/templates/admin.html:81 cps/templates/admin.html:92 +#: cps/templates/admin.html:83 cps/templates/admin.html:94 #: cps/templates/email_edit.html:55 msgid "From E-mail" msgstr "Από E-mail" -#: cps/templates/admin.html:88 +#: cps/templates/admin.html:90 msgid "E-Mail Service" msgstr "" -#: cps/templates/admin.html:89 +#: cps/templates/admin.html:91 msgid "Gmail via Oauth2" msgstr "" -#: cps/templates/admin.html:104 +#: cps/templates/admin.html:106 msgid "Configuration" msgstr "Διαμόρφωση" -#: cps/templates/admin.html:107 +#: cps/templates/admin.html:109 msgid "Calibre Database Directory" msgstr "Ευρετήριο Βάσης Δεδομένων Calibre" -#: cps/templates/admin.html:111 cps/templates/config_edit.html:68 +#: cps/templates/admin.html:113 cps/templates/config_edit.html:68 msgid "Log Level" msgstr "Επίπεδο Φύλλου Καταγραφής" -#: cps/templates/admin.html:115 +#: cps/templates/admin.html:117 msgid "Port" msgstr "Θύρα" -#: cps/templates/admin.html:120 +#: cps/templates/admin.html:122 msgid "External Port" msgstr "Εξωτερική Θύρα" -#: cps/templates/admin.html:127 cps/templates/config_view_edit.html:28 +#: cps/templates/admin.html:129 cps/templates/config_view_edit.html:28 msgid "Books per Page" msgstr "Βιβλία ανά Σελίδα" -#: cps/templates/admin.html:131 +#: cps/templates/admin.html:133 msgid "Uploads" msgstr "Ανεβάσμένα" -#: cps/templates/admin.html:135 +#: cps/templates/admin.html:137 msgid "Anonymous Browsing" msgstr "Ανώνυμη Περιήγηση" -#: cps/templates/admin.html:139 +#: cps/templates/admin.html:141 msgid "Public Registration" msgstr "Δημόσια Εγγραφή" -#: cps/templates/admin.html:143 +#: cps/templates/admin.html:145 msgid "Magic Link Remote Login" msgstr "Μαγικός Σύνδεσμος Απομακρυσμένης Σύνδεσης" -#: cps/templates/admin.html:147 +#: cps/templates/admin.html:149 msgid "Reverse Proxy Login" msgstr "Αναστροφή Σύνδεσης Διακομιστή Μεσολάβησης" -#: cps/templates/admin.html:152 cps/templates/config_edit.html:173 +#: cps/templates/admin.html:154 cps/templates/config_edit.html:173 msgid "Reverse Proxy Header Name" msgstr "Αναστροφή Proxy Όνομα Επικεφαλίδας" -#: cps/templates/admin.html:157 +#: cps/templates/admin.html:159 #, fuzzy msgid "Edit Calibre Database Configuration" msgstr "Επεξεργασία Βασικής Διαμόρφωσης" -#: cps/templates/admin.html:158 +#: cps/templates/admin.html:160 msgid "Edit Basic Configuration" msgstr "Επεξεργασία Βασικής Διαμόρφωσης" -#: cps/templates/admin.html:159 +#: cps/templates/admin.html:161 msgid "Edit UI Configuration" msgstr "Επεξεργασία Διαμόρφωσης UI" -#: cps/templates/admin.html:164 +#: cps/templates/admin.html:166 msgid "Administration" msgstr "Διοίκηση" -#: cps/templates/admin.html:165 +#: cps/templates/admin.html:167 msgid "Download Debug Package" msgstr "" -#: cps/templates/admin.html:166 +#: cps/templates/admin.html:168 msgid "View Logs" msgstr "Προβολή Φύλλων Καταγραφής" -#: cps/templates/admin.html:169 +#: cps/templates/admin.html:171 msgid "Reconnect Calibre Database" msgstr "Επανασύνδεση Βάσης Δεδομένων Calibre" -#: cps/templates/admin.html:170 +#: cps/templates/admin.html:172 msgid "Restart" msgstr "Επανεκκίνηση" -#: cps/templates/admin.html:171 +#: cps/templates/admin.html:173 msgid "Shutdown" msgstr "Κλείσιμο" -#: cps/templates/admin.html:176 +#: cps/templates/admin.html:178 msgid "Update" msgstr "Ενημέρωση" -#: cps/templates/admin.html:180 +#: cps/templates/admin.html:182 msgid "Version" msgstr "Έκδοση" -#: cps/templates/admin.html:181 +#: cps/templates/admin.html:183 msgid "Details" msgstr "Λεπτομέρειες" -#: cps/templates/admin.html:187 +#: cps/templates/admin.html:189 msgid "Current version" msgstr "Τρέχουσα έκδοση" -#: cps/templates/admin.html:194 +#: cps/templates/admin.html:196 msgid "Check for Update" msgstr "Έλεγχος για Ενημέρωση" -#: cps/templates/admin.html:195 +#: cps/templates/admin.html:197 msgid "Perform Update" msgstr "Πραγματοποίηση Ενημέρωσης" -#: cps/templates/admin.html:208 +#: cps/templates/admin.html:210 msgid "Are you sure you want to restart?" msgstr "Είσαι σίγουρος/η πως θέλεις να κάνεις επανεκκίνηση" -#: cps/templates/admin.html:213 cps/templates/admin.html:227 -#: cps/templates/admin.html:247 cps/templates/config_db.html:70 +#: cps/templates/admin.html:215 cps/templates/admin.html:229 +#: cps/templates/admin.html:249 cps/templates/config_db.html:70 msgid "OK" msgstr "OK" -#: cps/templates/admin.html:214 cps/templates/admin.html:228 -#: cps/templates/book_edit.html:213 cps/templates/book_table.html:124 +#: cps/templates/admin.html:216 cps/templates/admin.html:230 +#: cps/templates/book_edit.html:213 cps/templates/book_table.html:127 #: cps/templates/config_db.html:54 cps/templates/config_edit.html:359 -#: cps/templates/config_view_edit.html:173 cps/templates/modal_dialogs.html:64 +#: cps/templates/config_view_edit.html:175 cps/templates/modal_dialogs.html:64 #: cps/templates/modal_dialogs.html:99 cps/templates/modal_dialogs.html:117 #: cps/templates/modal_dialogs.html:135 cps/templates/shelf_edit.html:27 #: cps/templates/user_edit.html:144 msgid "Cancel" msgstr "Ακύρωση" -#: cps/templates/admin.html:226 +#: cps/templates/admin.html:228 msgid "Are you sure you want to shutdown?" msgstr "Είσαι σίγουρος/η πως θέλεις να κάνεις κλείσιμο;" -#: cps/templates/admin.html:238 +#: cps/templates/admin.html:240 msgid "Updating, please do not reload this page" msgstr "Γίνεται ενημέρωση, παρακαλούμε μη φορτώσεις ξανά αυτή τη σελίδα" @@ -1601,44 +1625,43 @@ msgstr "μέσω" msgid "In Library" msgstr "Στη Βιβλιοθήκη" -#: cps/templates/author.html:26 cps/templates/index.html:72 -#: cps/templates/search.html:29 cps/templates/shelf.html:19 +#: cps/templates/author.html:26 cps/templates/index.html:73 +#: cps/templates/search.html:30 cps/templates/shelf.html:19 msgid "Sort according to book date, newest first" msgstr "" -#: cps/templates/author.html:27 cps/templates/index.html:73 -#: cps/templates/search.html:30 cps/templates/shelf.html:20 +#: cps/templates/author.html:27 cps/templates/index.html:74 +#: cps/templates/search.html:31 cps/templates/shelf.html:20 msgid "Sort according to book date, oldest first" msgstr "" -#: cps/templates/author.html:28 cps/templates/index.html:74 -#: cps/templates/search.html:31 cps/templates/shelf.html:21 +#: cps/templates/author.html:28 cps/templates/index.html:75 +#: cps/templates/search.html:32 cps/templates/shelf.html:21 msgid "Sort title in alphabetical order" msgstr "" -#: cps/templates/author.html:29 cps/templates/index.html:75 -#: cps/templates/search.html:32 cps/templates/shelf.html:22 +#: cps/templates/author.html:29 cps/templates/index.html:76 +#: cps/templates/search.html:33 cps/templates/shelf.html:22 msgid "Sort title in reverse alphabetical order" msgstr "" -#: cps/templates/author.html:30 cps/templates/index.html:78 -#: cps/templates/search.html:35 cps/templates/shelf.html:25 +#: cps/templates/author.html:30 cps/templates/index.html:79 +#: cps/templates/search.html:36 cps/templates/shelf.html:25 msgid "Sort according to publishing date, newest first" msgstr "" -#: cps/templates/author.html:31 cps/templates/index.html:79 -#: cps/templates/search.html:36 cps/templates/shelf.html:26 +#: cps/templates/author.html:31 cps/templates/index.html:80 +#: cps/templates/search.html:37 cps/templates/shelf.html:26 msgid "Sort according to publishing date, oldest first" msgstr "" -#: cps/templates/author.html:57 cps/templates/author.html:117 -#: cps/templates/discover.html:30 cps/templates/index.html:29 -#: cps/templates/index.html:111 cps/templates/search.html:65 -#: cps/templates/shelf.html:54 +#: cps/templates/author.html:56 cps/templates/author.html:115 +#: cps/templates/index.html:29 cps/templates/index.html:112 +#: cps/templates/search.html:66 cps/templates/shelf.html:54 msgid "reduce" msgstr "μείωση" -#: cps/templates/author.html:101 +#: cps/templates/author.html:99 msgid "More by" msgstr "Περισσότερα από" @@ -1763,7 +1786,7 @@ msgid "Fetch Metadata" msgstr "Συγκέντρωση Μεταδεδομένων" #: cps/templates/book_edit.html:212 cps/templates/config_db.html:53 -#: cps/templates/config_edit.html:358 cps/templates/config_view_edit.html:172 +#: cps/templates/config_edit.html:358 cps/templates/config_view_edit.html:174 #: cps/templates/email_edit.html:65 cps/templates/shelf_edit.html:25 #: cps/templates/shelf_order.html:41 cps/templates/user_edit.html:142 msgid "Save" @@ -1892,27 +1915,35 @@ msgstr "Όνομα domain" msgid "Comments" msgstr "" -#: cps/templates/book_table.html:77 cps/templates/book_table.html:79 -#: cps/templates/book_table.html:81 cps/templates/book_table.html:83 -#: cps/templates/book_table.html:87 cps/templates/book_table.html:89 -#: cps/templates/book_table.html:91 cps/templates/book_table.html:93 +#: cps/templates/book_table.html:75 +msgid "Archiv Status" +msgstr "" + +#: cps/templates/book_table.html:77 cps/templates/search_form.html:42 +msgid "Read Status" +msgstr "" + +#: cps/templates/book_table.html:80 cps/templates/book_table.html:82 +#: cps/templates/book_table.html:84 cps/templates/book_table.html:86 +#: cps/templates/book_table.html:90 cps/templates/book_table.html:92 +#: cps/templates/book_table.html:96 #, fuzzy msgid "Enter " msgstr "Αναγνωριστικά" -#: cps/templates/book_table.html:110 cps/templates/modal_dialogs.html:46 +#: cps/templates/book_table.html:113 cps/templates/modal_dialogs.html:46 msgid "Are you really sure?" msgstr "Είσαι πραγματικά σίγουρος/η;" -#: cps/templates/book_table.html:114 +#: cps/templates/book_table.html:117 msgid "Books with Title will be merged from:" msgstr "Βιβλία με Τίτλους θα ενωθούν από:" -#: cps/templates/book_table.html:118 +#: cps/templates/book_table.html:121 msgid "Into Book with Title:" msgstr "Μέσα σε Βιβλίο με Τίτλο:" -#: cps/templates/book_table.html:123 +#: cps/templates/book_table.html:126 msgid "Merge" msgstr "Συγχώνευση" @@ -2089,11 +2120,6 @@ msgstr "Θύρα Διακομιστή LDAP" msgid "LDAP Encryption" msgstr "LDAP Αποκρυπτογράφηση" -#: cps/templates/config_edit.html:204 cps/templates/config_view_edit.html:62 -#: cps/templates/email_edit.html:41 -msgid "None" -msgstr "Κανένα" - #: cps/templates/config_edit.html:205 msgid "TLS" msgstr "TLS" @@ -2312,11 +2338,11 @@ msgstr "Προκαθορισμένες Ορατότηες για Νέους Χρ msgid "Show Random Books in Detail View" msgstr "Προβολή Τυχαίων Βιβλίων σε Προβολή Λεπτομερειών" -#: cps/templates/config_view_edit.html:165 cps/templates/user_edit.html:87 +#: cps/templates/config_view_edit.html:166 cps/templates/user_edit.html:87 msgid "Add Allowed/Denied Tags" msgstr "Προσθήκη ετικετών Επιτρέπεται/Απορρίπτεται" -#: cps/templates/config_view_edit.html:166 +#: cps/templates/config_view_edit.html:167 msgid "Add Allowed/Denied custom column values" msgstr "Προσθήκη τιμών ειδικά κατασκευασμένων στηλών Επιτρέπεται/Απορρίπτεται" @@ -2365,13 +2391,13 @@ msgstr "Αρχειοθετήθηκε" msgid "Description:" msgstr "Περιγραφή" -#: cps/templates/detail.html:256 cps/templates/search.html:14 +#: cps/templates/detail.html:256 cps/templates/search.html:15 msgid "Add to shelf" msgstr "Προσθήκη στο ράφι" #: cps/templates/detail.html:267 cps/templates/detail.html:284 #: cps/templates/feed.xml:79 cps/templates/layout.html:137 -#: cps/templates/search.html:20 +#: cps/templates/search.html:21 msgid "(Public)" msgstr "(Δημόσιο)" @@ -2449,10 +2475,15 @@ msgstr "Domains που Απορρίφθηκαν (Μαύρη λίστα)" msgid "Next" msgstr "Επόμενο" -#: cps/templates/generate_kobo_auth_url.html:5 +#: cps/templates/generate_kobo_auth_url.html:6 msgid "Open the .kobo/Kobo eReader.conf file in a text editor and add (or edit):" msgstr "ʼΑνοιξε το .kobo/Kobo eReader.conf αρχείο σε πρόγραμμα επεξεργασίας κειμένου και πρόσθεσε (ή κάνε επεξεργασία):" +#: cps/templates/generate_kobo_auth_url.html:11 +#, fuzzy +msgid "Kobo Token:" +msgstr "Kobo Μονάδα Συγχρονισμού" + #: cps/templates/http_error.html:31 #, fuzzy msgid "Calibre-Web Instance is unconfigured, please contact your administrator" @@ -2470,29 +2501,29 @@ msgstr "Επιστροφή στην Κεντρική" msgid "Logout User" msgstr "" -#: cps/templates/index.html:69 +#: cps/templates/index.html:70 msgid "Sort ascending according to download count" msgstr "" -#: cps/templates/index.html:70 +#: cps/templates/index.html:71 msgid "Sort descending according to download count" msgstr "" -#: cps/templates/index.html:76 cps/templates/search.html:33 +#: cps/templates/index.html:77 cps/templates/search.html:34 #: cps/templates/shelf.html:23 msgid "Sort authors in alphabetical order" msgstr "" -#: cps/templates/index.html:77 cps/templates/search.html:34 +#: cps/templates/index.html:78 cps/templates/search.html:35 #: cps/templates/shelf.html:24 msgid "Sort authors in reverse alphabetical order" msgstr "" -#: cps/templates/index.html:81 +#: cps/templates/index.html:82 msgid "Sort ascending according to series index" msgstr "" -#: cps/templates/index.html:82 +#: cps/templates/index.html:83 msgid "Sort descending according to series index" msgstr "" @@ -2928,10 +2959,6 @@ msgstr "Ημερομηνία Έκδοσης Από" msgid "Published Date To" msgstr "Ημερομηνία Έκδοσης Μέχρι" -#: cps/templates/search_form.html:42 -msgid "Read Status" -msgstr "" - #: cps/templates/search_form.html:59 msgid "Exclude Tags" msgstr "Εξαίρεση Ετικετών" diff --git a/cps/translations/es/LC_MESSAGES/messages.mo b/cps/translations/es/LC_MESSAGES/messages.mo index bd6afe28..c8c6ae9e 100644 Binary files a/cps/translations/es/LC_MESSAGES/messages.mo and b/cps/translations/es/LC_MESSAGES/messages.mo differ diff --git a/cps/translations/es/LC_MESSAGES/messages.po b/cps/translations/es/LC_MESSAGES/messages.po index 2f100e3b..63bc1161 100644 --- a/cps/translations/es/LC_MESSAGES/messages.po +++ b/cps/translations/es/LC_MESSAGES/messages.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: Calibre-Web\n" "Report-Msgid-Bugs-To: https://github.com/janeczku/Calibre-Web\n" -"POT-Creation-Date: 2022-01-15 09:19+0100\n" +"POT-Creation-Date: 2022-04-18 20:01+0200\n" "PO-Revision-Date: 2020-05-25 17:22+0200\n" "Last-Translator: minakmostoles \n" "Language: es\n" @@ -18,590 +18,593 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.9.0\n" - -#: cps/about.py:34 cps/about.py:49 cps/about.py:65 cps/converter.py:31 -msgid "not installed" -msgstr "no instalado" - -#: cps/about.py:47 cps/about.py:63 -msgid "installed" -msgstr "instalado" +"Generated-By: Babel 2.9.1\n" # "Last-Translator: victorhck \n" -#: cps/about.py:145 +#: cps/about.py:86 msgid "Statistics" msgstr "Estadísticas" -#: cps/admin.py:144 +#: cps/admin.py:141 msgid "Server restarted, please reload page" msgstr "Servidor reiniciado. Por favor, recargue la página" -#: cps/admin.py:146 +#: cps/admin.py:143 msgid "Performing shutdown of server, please close window" msgstr "El servidor se está apagando. Por favor, cierre la ventana" -#: cps/admin.py:154 +#: cps/admin.py:151 msgid "Reconnect successful" msgstr "Reconexión correcta" -#: cps/admin.py:157 +#: cps/admin.py:154 msgid "Unknown command" msgstr "Comando desconocido" -#: cps/admin.py:167 cps/editbooks.py:707 cps/editbooks.py:721 -#: cps/editbooks.py:866 cps/editbooks.py:868 cps/editbooks.py:895 -#: cps/editbooks.py:911 cps/updater.py:584 cps/uploader.py:93 -#: cps/uploader.py:103 +#: cps/admin.py:176 cps/editbooks.py:713 cps/editbooks.py:892 +#: cps/editbooks.py:894 cps/editbooks.py:930 cps/editbooks.py:947 +#: cps/updater.py:608 cps/uploader.py:93 cps/uploader.py:103 msgid "Unknown" msgstr "Desconocido" -#: cps/admin.py:188 +#: cps/admin.py:197 msgid "Admin page" msgstr "Página de administración" -#: cps/admin.py:207 +#: cps/admin.py:217 msgid "Basic Configuration" msgstr "Configuración básica" -#: cps/admin.py:244 +#: cps/admin.py:255 msgid "UI Configuration" msgstr "Configuración de la interfaz de usuario" -#: cps/admin.py:277 cps/templates/admin.html:50 +#: cps/admin.py:289 cps/templates/admin.html:51 #, fuzzy msgid "Edit Users" msgstr "Editar usuarios" -#: cps/admin.py:318 cps/opds.py:109 cps/opds.py:198 cps/opds.py:275 -#: cps/opds.py:327 cps/templates/grid.html:13 cps/templates/languages.html:9 +#: cps/admin.py:333 cps/opds.py:529 cps/templates/grid.html:13 #: cps/templates/list.html:13 msgid "All" msgstr "Todo" -#: cps/admin.py:343 cps/admin.py:1615 +#: cps/admin.py:360 cps/admin.py:1648 msgid "User not found" msgstr "Usuario no encontrado" -#: cps/admin.py:357 +#: cps/admin.py:374 msgid "{} users deleted successfully" msgstr "{} usuarios eliminados con éxito" -#: cps/admin.py:379 cps/templates/config_view_edit.html:133 +#: cps/admin.py:397 cps/templates/config_view_edit.html:133 #: cps/templates/user_edit.html:45 cps/templates/user_table.html:81 msgid "Show All" msgstr "Mostrar todo" -#: cps/admin.py:400 cps/admin.py:406 +#: cps/admin.py:418 cps/admin.py:424 msgid "Malformed request" msgstr "Petición mal formulada" -#: cps/admin.py:418 cps/admin.py:1493 +#: cps/admin.py:436 cps/admin.py:1526 msgid "Guest Name can't be changed" msgstr "El nombre de invitado no se puede cambiar" -#: cps/admin.py:430 +#: cps/admin.py:448 msgid "Guest can't have this role" msgstr "El invitado no puede tener ese rol" -#: cps/admin.py:442 cps/admin.py:1451 +#: cps/admin.py:460 cps/admin.py:1484 msgid "No admin user remaining, can't remove admin role" msgstr "No queda ningún usuario administrador, no se puede eliminar al usuario" -#: cps/admin.py:446 cps/admin.py:460 +#: cps/admin.py:464 cps/admin.py:478 msgid "Value has to be true or false" msgstr "Valor tiene que ser verdadero o falso" -#: cps/admin.py:448 +#: cps/admin.py:466 msgid "Invalid role" msgstr "Rol inválido" -#: cps/admin.py:452 +#: cps/admin.py:470 msgid "Guest can't have this view" msgstr "El invitado no puede tener esta vista" -#: cps/admin.py:462 +#: cps/admin.py:480 msgid "Invalid view" msgstr "Vista no válida" -#: cps/admin.py:465 +#: cps/admin.py:483 msgid "Guest's Locale is determined automatically and can't be set" msgstr "El sitio del invitado se determina automáticamente y no puede ser cambiado" -#: cps/admin.py:469 +#: cps/admin.py:487 msgid "No Valid Locale Given" msgstr "No hay un sitio válido" -#: cps/admin.py:480 +#: cps/admin.py:498 msgid "No Valid Book Language Given" msgstr "No se ha indicado un idioma válido para el libro" -#: cps/admin.py:482 +#: cps/admin.py:500 cps/editbooks.py:1267 msgid "Parameter not found" msgstr "Parámetro no encontrado" -#: cps/admin.py:533 +#: cps/admin.py:553 msgid "Invalid Read Column" msgstr "Columna de lectura no válida" -#: cps/admin.py:539 +#: cps/admin.py:559 msgid "Invalid Restricted Column" msgstr "Columna restringida no válida" -#: cps/admin.py:560 cps/admin.py:1323 +#: cps/admin.py:579 cps/admin.py:1355 msgid "Calibre-Web configuration updated" msgstr "Configuración de Calibre-Web actualizada" -#: cps/admin.py:572 +#: cps/admin.py:591 msgid "Do you really want to delete the Kobo Token?" msgstr "¿Realmente quieres borrar el Token de Kobo?" -#: cps/admin.py:574 +#: cps/admin.py:593 msgid "Do you really want to delete this domain?" msgstr "¿Realmente deseas borrar este dominio?" -#: cps/admin.py:576 +#: cps/admin.py:595 msgid "Do you really want to delete this user?" msgstr "¿Realmente quieres borrar este usuario?" -#: cps/admin.py:578 +#: cps/admin.py:597 msgid "Are you sure you want to delete this shelf?" msgstr "¿Realmente quieres eliminar este estante?" -#: cps/admin.py:580 +#: cps/admin.py:599 #, fuzzy msgid "Are you sure you want to change locales of selected user(s)?" msgstr "¿Realmente quieres cambiar el idioma de los usuarios seleccionados?" -#: cps/admin.py:582 +#: cps/admin.py:601 msgid "Are you sure you want to change visible book languages for selected user(s)?" msgstr "¿Realmente quieres cambiar los idiomas visibles del libro de los usuarios seleccionados?" -#: cps/admin.py:584 +#: cps/admin.py:603 msgid "Are you sure you want to change the selected role for the selected user(s)?" msgstr "¿Realmente quieres cambiar el rol seleccionado de el usuario seleccionado?" -#: cps/admin.py:586 +#: cps/admin.py:605 #, fuzzy msgid "Are you sure you want to change the selected restrictions for the selected user(s)?" msgstr "¿Realmente quieres cambiar las restricciones de los usuarios seleccionados?" -#: cps/admin.py:588 +#: cps/admin.py:607 msgid "Are you sure you want to change the selected visibility restrictions for the selected user(s)?" msgstr "¿Realmente quieres cambiar las restricciones de visibilidad de los usuarios seleccionados?" -#: cps/admin.py:590 +#: cps/admin.py:610 #, fuzzy msgid "Are you sure you want to change shelf sync behavior for the selected user(s)?" msgstr "¿Realmente quieres cambiar el comportamiento de sincronización de estante del usuario seleccionado?" -#: cps/admin.py:592 +#: cps/admin.py:612 #, fuzzy msgid "Are you sure you want to change Calibre library location?" msgstr "¿Realmente quieres cambiar la ubicación de la biblioteca Calibre?" -#: cps/admin.py:594 +#: cps/admin.py:614 msgid "Are you sure you want delete Calibre-Web's sync database to force a full sync with your Kobo Reader?" msgstr "" -#: cps/admin.py:743 +#: cps/admin.py:764 msgid "Tag not found" msgstr "Etiqueta no encontrada" -#: cps/admin.py:755 +#: cps/admin.py:776 msgid "Invalid Action" msgstr "Acción no válida" -#: cps/admin.py:871 cps/admin.py:877 cps/admin.py:887 cps/admin.py:897 +#: cps/admin.py:893 cps/admin.py:899 cps/admin.py:909 cps/admin.py:919 #: cps/templates/modal_dialogs.html:29 cps/templates/user_table.html:41 #: cps/templates/user_table.html:58 msgid "Deny" msgstr "Denegar" -#: cps/admin.py:873 cps/admin.py:879 cps/admin.py:889 cps/admin.py:899 +#: cps/admin.py:895 cps/admin.py:901 cps/admin.py:911 cps/admin.py:921 #: cps/templates/modal_dialogs.html:28 cps/templates/user_table.html:44 #: cps/templates/user_table.html:61 msgid "Allow" msgstr "Permitir" -#: cps/admin.py:913 +#: cps/admin.py:936 msgid "{} sync entries deleted" msgstr "" -#: cps/admin.py:1036 +#: cps/admin.py:1059 msgid "client_secrets.json Is Not Configured For Web Application" msgstr "client_secrets.json no está configurado para la aplicación web" -#: cps/admin.py:1081 +#: cps/admin.py:1104 msgid "Logfile Location is not Valid, Please Enter Correct Path" msgstr "La ruta del Logfile no es válida. Por favor, Introduce la ruta correcta" -#: cps/admin.py:1087 +#: cps/admin.py:1110 msgid "Access Logfile Location is not Valid, Please Enter Correct Path" msgstr "La ruta del Access Logfile no es válida. Por favor, Introduce la ruta correcta" -#: cps/admin.py:1117 +#: cps/admin.py:1140 msgid "Please Enter a LDAP Provider, Port, DN and User Object Identifier" msgstr "Por favor, Introduce un proveedor LDAP, puerto, DN y el User Object Identifier" -#: cps/admin.py:1123 +#: cps/admin.py:1146 #, fuzzy msgid "Please Enter a LDAP Service Account and Password" msgstr "Por favor, introduce una cuenta de servicio LDAP y su contraseña" -#: cps/admin.py:1126 +#: cps/admin.py:1149 msgid "Please Enter a LDAP Service Account" msgstr "Por favor, introduce una cuenta de servicio LDAP" -#: cps/admin.py:1131 +#: cps/admin.py:1154 #, python-format msgid "LDAP Group Object Filter Needs to Have One \"%s\" Format Identifier" msgstr "LDAP Group Object Filter necesita tener un identificador de formato \"%s\"" -#: cps/admin.py:1133 +#: cps/admin.py:1156 msgid "LDAP Group Object Filter Has Unmatched Parenthesis" msgstr "El LDAP Group Object Filter tiene un paréntesis diferente" -#: cps/admin.py:1137 +#: cps/admin.py:1160 #, python-format msgid "LDAP User Object Filter needs to Have One \"%s\" Format Identifier" msgstr "LDAP Group Object Filter necesita tener un identificador de formato \"%s\"" -#: cps/admin.py:1139 +#: cps/admin.py:1162 msgid "LDAP User Object Filter Has Unmatched Parenthesis" msgstr "El LDAP Group Object Filter tiene un paréntesis diferente" -#: cps/admin.py:1146 +#: cps/admin.py:1169 #, python-format msgid "LDAP Member User Filter needs to Have One \"%s\" Format Identifier" msgstr "El filtro de usuarios LDAP necesita tener un identificador de formato \"%s\"" -#: cps/admin.py:1148 +#: cps/admin.py:1171 msgid "LDAP Member User Filter Has Unmatched Parenthesis" msgstr "El filtro de LDAP \"Member User\" tiene paréntesis no coincidentes" -#: cps/admin.py:1155 +#: cps/admin.py:1178 msgid "LDAP CACertificate, Certificate or Key Location is not Valid, Please Enter Correct Path" msgstr "Ubicaciones del certificado de la CA del LDAP, del certificado o de la clave no válidos. Por favor introduce la ruta correcta" -#: cps/admin.py:1197 cps/admin.py:1308 cps/admin.py:1405 cps/admin.py:1521 -#: cps/admin.py:1590 cps/shelf.py:100 cps/shelf.py:160 cps/shelf.py:203 -#: cps/shelf.py:279 cps/shelf.py:341 cps/shelf.py:376 cps/shelf.py:451 -msgid "Settings DB is not Writeable" -msgstr "La base de datos de configuración no es modificable" - -#: cps/admin.py:1208 -msgid "DB Location is not Valid, Please Enter Correct Path" -msgstr "La ruta de la base de datos no es válida. Por favor, Introduce la ruta correcta" - -#: cps/admin.py:1223 -msgid "DB is not Writeable" -msgstr "La base de datos no es modificable" - -#: cps/admin.py:1235 -msgid "Keyfile Location is not Valid, Please Enter Correct Path" -msgstr "La ruta del Keyfile no es válida, por favor, Introduce la ruta correcta" - -#: cps/admin.py:1239 -msgid "Certfile Location is not Valid, Please Enter Correct Path" -msgstr "La ruta de Certfile no es válida, por favor, Introduce la ruta correcta" - -#: cps/admin.py:1346 -#, fuzzy -msgid "Database Settings updated" -msgstr "Actualizados los ajustes del servidor de correo electrónico" - -#: cps/admin.py:1354 -#, fuzzy -msgid "Database Configuration" -msgstr "Configuración de la base de datos" - -#: cps/admin.py:1370 cps/web.py:1479 -msgid "Please fill out all fields!" -msgstr "¡Por favor, rellena todos los campos!" - -#: cps/admin.py:1378 -msgid "E-mail is not from valid domain" -msgstr "El correo electrónico no tiene un dominio válido" - -#: cps/admin.py:1384 cps/admin.py:1543 -msgid "Add new user" -msgstr "Añadir un nuevo usuario" - -#: cps/admin.py:1395 -#, python-format -msgid "User '%(user)s' created" -msgstr "Usuario '%(user)s' creado" - -#: cps/admin.py:1401 -#, fuzzy -msgid "Found an existing account for this e-mail address or name." -msgstr "Encontrada una cuenta existente para este correo electrónico o nombre de usuario." - -#: cps/admin.py:1430 -#, python-format -msgid "User '%(nick)s' deleted" -msgstr "Usuario '%(nick)s' eliminado" - -#: cps/admin.py:1432 cps/admin.py:1433 -msgid "Can't delete Guest User" -msgstr "No puedes borrar al Usuario Invitado" - -#: cps/admin.py:1436 -msgid "No admin user remaining, can't delete user" -msgstr "No queda ningún usuario administrador, no se puede borrar al usuario" - -#: cps/admin.py:1509 cps/admin.py:1634 -#, python-format -msgid "Edit User %(nick)s" -msgstr "Editar Usuario %(nick)s" - -#: cps/admin.py:1513 -#, python-format -msgid "User '%(nick)s' updated" -msgstr "Usuario '%(nick)s' actualizado" - -#: cps/admin.py:1517 cps/admin.py:1649 cps/web.py:1504 cps/web.py:1564 -msgid "An unknown error occurred. Please try again later." -msgstr "Ha ocurrido un error desconocido. Por favor vuelva a intentarlo más tarde." - -#: cps/admin.py:1552 cps/templates/admin.html:98 -msgid "Edit E-mail Server Settings" -msgstr "Cambiar parámetros de correo" - -#: cps/admin.py:1571 -msgid "Gmail Account Verification Successful" -msgstr "Verificación de cuenta de Gmail exitosa" - -#: cps/admin.py:1597 -#, python-format -msgid "Test e-mail queued for sending to %(email)s, please check Tasks for result" -msgstr "Puesto en cola un correo electrónico de prueba enviado a %(email)s, por favor, comprueba el resultado en Tareas" - -#: cps/admin.py:1600 -#, python-format -msgid "There was an error sending the Test e-mail: %(res)s" -msgstr "Ocurrió un error enviando el correo electrónico de prueba: %(res)s" - -#: cps/admin.py:1602 -msgid "Please configure your e-mail address first..." -msgstr "Por favor, configure su correo electrónico primero..." - -#: cps/admin.py:1604 -msgid "E-mail server settings updated" -msgstr "Actualizados los ajustes del servidor de correo electrónico" - -#: cps/admin.py:1646 -#, python-format -msgid "Password for user %(user)s reset" -msgstr "Contraseña para el usuario %(user)s reinicializada" - -#: cps/admin.py:1652 cps/web.py:1444 -msgid "Please configure the SMTP mail settings first..." -msgstr "Configura primero los parámetros del servidor SMTP..." - -#: cps/admin.py:1663 -msgid "Logfile viewer" -msgstr "Visor del fichero de log" - -#: cps/admin.py:1729 -msgid "Requesting update package" -msgstr "Solicitando paquete de actualización" - -#: cps/admin.py:1730 -msgid "Downloading update package" -msgstr "Descargando paquete de actualización" - -#: cps/admin.py:1731 -msgid "Unzipping update package" -msgstr "Descomprimiendo paquete de actualización" - -#: cps/admin.py:1732 -msgid "Replacing files" -msgstr "Remplazando archivos" - -#: cps/admin.py:1733 -msgid "Database connections are closed" -msgstr "Los conexiones con la base datos están cerradas" - -#: cps/admin.py:1734 -msgid "Stopping server" -msgstr "Parando el servidor" - -#: cps/admin.py:1735 -msgid "Update finished, please press okay and reload page" -msgstr "Actualización finalizada. Por favor, pulse OK y recargue la página" - -#: cps/admin.py:1736 cps/admin.py:1737 cps/admin.py:1738 cps/admin.py:1739 -#: cps/admin.py:1740 cps/admin.py:1741 -msgid "Update failed:" -msgstr "Falló la actualización:" - -#: cps/admin.py:1736 cps/updater.py:385 cps/updater.py:595 cps/updater.py:597 -msgid "HTTP Error" -msgstr "Error HTTP" - -#: cps/admin.py:1737 cps/updater.py:387 cps/updater.py:599 -msgid "Connection error" -msgstr "Error de conexión" - -#: cps/admin.py:1738 cps/updater.py:389 cps/updater.py:601 -msgid "Timeout while establishing connection" -msgstr "Tiempo agotado mientras se trataba de establecer la conexión" - -#: cps/admin.py:1739 cps/updater.py:391 cps/updater.py:603 -msgid "General error" -msgstr "Error general" - -#: cps/admin.py:1740 -#, fuzzy -msgid "Update file could not be saved in temp dir" -msgstr "La actualización del archivo no pudo guardarse en el directorio temporal (Temp Dir)" - -#: cps/admin.py:1741 -msgid "Files could not be replaced during update" -msgstr "" - -#: cps/admin.py:1765 -#, fuzzy -msgid "Failed to extract at least One LDAP User" -msgstr "Error al crear al menos un usuario LDAP" - -#: cps/admin.py:1810 -msgid "Failed to Create at Least One LDAP User" -msgstr "Error al crear al menos un usuario LDAP" - -#: cps/admin.py:1823 -#, python-format -msgid "Error: %(ldaperror)s" -msgstr "Error: %(ldaperror)s" - -#: cps/admin.py:1827 -msgid "Error: No user returned in response of LDAP server" -msgstr "Error: el servidor LDAP no ha devuelto ningún usuario" - -#: cps/admin.py:1860 -msgid "At Least One LDAP User Not Found in Database" -msgstr "Al menos, un usuario LDAP no se ha encontrado en la base de datos" - -#: cps/admin.py:1862 -msgid "{} User Successfully Imported" -msgstr "{} Usuario importado con éxito" - -#: cps/converter.py:30 -msgid "not configured" -msgstr "no configurado" - -#: cps/converter.py:32 -msgid "Execution permissions missing" -msgstr "Faltan permisos de ejecución" - -#: cps/db.py:651 cps/web.py:667 cps/web.py:1155 -#, python-format -msgid "Custom Column No.%(column)d is not existing in calibre database" -msgstr "Columna personalizada No.%(column)d no existe en la base de datos calibre" - -#: cps/editbooks.py:300 cps/editbooks.py:302 -msgid "Book Format Successfully Deleted" -msgstr "Formato de libro eliminado con éxito" - -#: cps/editbooks.py:309 cps/editbooks.py:311 -msgid "Book Successfully Deleted" -msgstr "Libro eliminado con éxito" - -#: cps/editbooks.py:361 -msgid "You are missing permissions to delete books" -msgstr "" - -#: cps/editbooks.py:376 cps/editbooks.py:763 cps/web.py:523 cps/web.py:1703 -#: cps/web.py:1744 cps/web.py:1811 -msgid "Oops! Selected book title is unavailable. File does not exist or is not accessible" -msgstr "oh, oh, el libro seleccionado no está disponible. El archivo no existe o no es accesible" - -#: cps/editbooks.py:410 -msgid "edit metadata" -msgstr "editar metadatos" - -#: cps/editbooks.py:458 -#, python-format -msgid "%(seriesindex)s is not a valid number, skipping" -msgstr "%(seriesindex) no es un número válido, saltando" - -#: cps/editbooks.py:494 cps/editbooks.py:958 -#, fuzzy, python-format -msgid "'%(langname)s' is not a valid language" -msgstr "%(langname)s no es un idioma válido" - -#: cps/editbooks.py:634 cps/editbooks.py:985 -#, python-format -msgid "File extension '%(ext)s' is not allowed to be uploaded to this server" -msgstr "No se permite subir archivos con la extensión '%(ext)s' a este servidor" - -#: cps/editbooks.py:638 cps/editbooks.py:989 -msgid "File to be uploaded must have an extension" -msgstr "El archivo a subir debe tener una extensión" - -#: cps/editbooks.py:650 -#, python-format -msgid "Failed to create path %(path)s (Permission denied)." -msgstr "Fallo al crear la ruta %(path)s (permiso denegado)" - -#: cps/editbooks.py:655 -#, python-format -msgid "Failed to store file %(file)s." -msgstr "Fallo al guardar el archivo %(file)s." - -#: cps/editbooks.py:673 cps/editbooks.py:1076 cps/web.py:1664 +#: cps/admin.py:1223 cps/admin.py:1339 cps/admin.py:1437 cps/admin.py:1554 +#: cps/admin.py:1623 cps/editbooks.py:678 cps/editbooks.py:882 +#: cps/editbooks.py:1130 cps/shelf.py:100 cps/shelf.py:160 cps/shelf.py:203 +#: cps/shelf.py:278 cps/shelf.py:343 cps/shelf.py:380 cps/shelf.py:456 +#: cps/web.py:1742 #, python-format msgid "Database error: %(error)s." msgstr "Error en la base de datos: %(error)s." -#: cps/editbooks.py:678 +#: cps/admin.py:1235 +msgid "DB Location is not Valid, Please Enter Correct Path" +msgstr "La ruta de la base de datos no es válida. Por favor, Introduce la ruta correcta" + +#: cps/admin.py:1253 +msgid "DB is not Writeable" +msgstr "La base de datos no es modificable" + +#: cps/admin.py:1266 +msgid "Keyfile Location is not Valid, Please Enter Correct Path" +msgstr "La ruta del Keyfile no es válida, por favor, Introduce la ruta correcta" + +#: cps/admin.py:1270 +msgid "Certfile Location is not Valid, Please Enter Correct Path" +msgstr "La ruta de Certfile no es válida, por favor, Introduce la ruta correcta" + +#: cps/admin.py:1378 +#, fuzzy +msgid "Database Settings updated" +msgstr "Actualizados los ajustes del servidor de correo electrónico" + +#: cps/admin.py:1386 +#, fuzzy +msgid "Database Configuration" +msgstr "Configuración de la base de datos" + +#: cps/admin.py:1402 cps/web.py:1557 +msgid "Please fill out all fields!" +msgstr "¡Por favor, rellena todos los campos!" + +#: cps/admin.py:1410 +msgid "E-mail is not from valid domain" +msgstr "El correo electrónico no tiene un dominio válido" + +#: cps/admin.py:1416 cps/admin.py:1576 +msgid "Add new user" +msgstr "Añadir un nuevo usuario" + +#: cps/admin.py:1427 +#, python-format +msgid "User '%(user)s' created" +msgstr "Usuario '%(user)s' creado" + +#: cps/admin.py:1433 +#, fuzzy +msgid "Found an existing account for this e-mail address or name." +msgstr "Encontrada una cuenta existente para este correo electrónico o nombre de usuario." + +#: cps/admin.py:1463 +#, python-format +msgid "User '%(nick)s' deleted" +msgstr "Usuario '%(nick)s' eliminado" + +#: cps/admin.py:1465 cps/admin.py:1466 +msgid "Can't delete Guest User" +msgstr "No puedes borrar al Usuario Invitado" + +#: cps/admin.py:1469 +msgid "No admin user remaining, can't delete user" +msgstr "No queda ningún usuario administrador, no se puede borrar al usuario" + +#: cps/admin.py:1542 cps/admin.py:1667 +#, python-format +msgid "Edit User %(nick)s" +msgstr "Editar Usuario %(nick)s" + +#: cps/admin.py:1546 +#, python-format +msgid "User '%(nick)s' updated" +msgstr "Usuario '%(nick)s' actualizado" + +#: cps/admin.py:1550 cps/admin.py:1682 cps/web.py:1582 cps/web.py:1642 +msgid "An unknown error occurred. Please try again later." +msgstr "Ha ocurrido un error desconocido. Por favor vuelva a intentarlo más tarde." + +#: cps/admin.py:1585 cps/templates/admin.html:100 +msgid "Edit E-mail Server Settings" +msgstr "Cambiar parámetros de correo" + +#: cps/admin.py:1604 +msgid "Gmail Account Verification Successful" +msgstr "Verificación de cuenta de Gmail exitosa" + +#: cps/admin.py:1630 +#, python-format +msgid "Test e-mail queued for sending to %(email)s, please check Tasks for result" +msgstr "Puesto en cola un correo electrónico de prueba enviado a %(email)s, por favor, comprueba el resultado en Tareas" + +#: cps/admin.py:1633 +#, python-format +msgid "There was an error sending the Test e-mail: %(res)s" +msgstr "Ocurrió un error enviando el correo electrónico de prueba: %(res)s" + +#: cps/admin.py:1635 +msgid "Please configure your e-mail address first..." +msgstr "Por favor, configure su correo electrónico primero..." + +#: cps/admin.py:1637 +msgid "E-mail server settings updated" +msgstr "Actualizados los ajustes del servidor de correo electrónico" + +#: cps/admin.py:1679 +#, python-format +msgid "Password for user %(user)s reset" +msgstr "Contraseña para el usuario %(user)s reinicializada" + +#: cps/admin.py:1685 cps/web.py:1522 +msgid "Please configure the SMTP mail settings first..." +msgstr "Configura primero los parámetros del servidor SMTP..." + +#: cps/admin.py:1696 +msgid "Logfile viewer" +msgstr "Visor del fichero de log" + +#: cps/admin.py:1762 +msgid "Requesting update package" +msgstr "Solicitando paquete de actualización" + +#: cps/admin.py:1763 +msgid "Downloading update package" +msgstr "Descargando paquete de actualización" + +#: cps/admin.py:1764 +msgid "Unzipping update package" +msgstr "Descomprimiendo paquete de actualización" + +#: cps/admin.py:1765 +msgid "Replacing files" +msgstr "Remplazando archivos" + +#: cps/admin.py:1766 +msgid "Database connections are closed" +msgstr "Los conexiones con la base datos están cerradas" + +#: cps/admin.py:1767 +msgid "Stopping server" +msgstr "Parando el servidor" + +#: cps/admin.py:1768 +msgid "Update finished, please press okay and reload page" +msgstr "Actualización finalizada. Por favor, pulse OK y recargue la página" + +#: cps/admin.py:1769 cps/admin.py:1770 cps/admin.py:1771 cps/admin.py:1772 +#: cps/admin.py:1773 cps/admin.py:1774 +msgid "Update failed:" +msgstr "Falló la actualización:" + +#: cps/admin.py:1769 cps/updater.py:384 cps/updater.py:619 cps/updater.py:621 +msgid "HTTP Error" +msgstr "Error HTTP" + +#: cps/admin.py:1770 cps/updater.py:386 cps/updater.py:623 +msgid "Connection error" +msgstr "Error de conexión" + +#: cps/admin.py:1771 cps/updater.py:388 cps/updater.py:625 +msgid "Timeout while establishing connection" +msgstr "Tiempo agotado mientras se trataba de establecer la conexión" + +#: cps/admin.py:1772 cps/updater.py:390 cps/updater.py:627 +msgid "General error" +msgstr "Error general" + +#: cps/admin.py:1773 +#, fuzzy +msgid "Update file could not be saved in temp dir" +msgstr "La actualización del archivo no pudo guardarse en el directorio temporal (Temp Dir)" + +#: cps/admin.py:1774 +msgid "Files could not be replaced during update" +msgstr "" + +#: cps/admin.py:1798 +#, fuzzy +msgid "Failed to extract at least One LDAP User" +msgstr "Error al crear al menos un usuario LDAP" + +#: cps/admin.py:1843 +msgid "Failed to Create at Least One LDAP User" +msgstr "Error al crear al menos un usuario LDAP" + +#: cps/admin.py:1856 +#, python-format +msgid "Error: %(ldaperror)s" +msgstr "Error: %(ldaperror)s" + +#: cps/admin.py:1860 +msgid "Error: No user returned in response of LDAP server" +msgstr "Error: el servidor LDAP no ha devuelto ningún usuario" + +#: cps/admin.py:1893 +msgid "At Least One LDAP User Not Found in Database" +msgstr "Al menos, un usuario LDAP no se ha encontrado en la base de datos" + +#: cps/admin.py:1895 +msgid "{} User Successfully Imported" +msgstr "{} Usuario importado con éxito" + +#: cps/converter.py:30 +msgid "not installed" +msgstr "no instalado" + +#: cps/converter.py:31 +msgid "Execution permissions missing" +msgstr "Faltan permisos de ejecución" + +#: cps/db.py:674 cps/web.py:710 cps/web.py:1222 +#, python-format +msgid "Custom Column No.%(column)d is not existing in calibre database" +msgstr "Columna personalizada No.%(column)d no existe en la base de datos calibre" + +#: cps/db.py:917 cps/templates/config_edit.html:204 +#: cps/templates/config_view_edit.html:62 cps/templates/email_edit.html:41 +#: cps/web.py:551 cps/web.py:585 cps/web.py:646 cps/web.py:671 cps/web.py:1003 +#: cps/web.py:1032 cps/web.py:1066 cps/web.py:1093 cps/web.py:1132 +msgid "None" +msgstr "Ninguno" + +#: cps/editbooks.py:295 cps/editbooks.py:297 +msgid "Book Format Successfully Deleted" +msgstr "Formato de libro eliminado con éxito" + +#: cps/editbooks.py:304 cps/editbooks.py:306 +msgid "Book Successfully Deleted" +msgstr "Libro eliminado con éxito" + +#: cps/editbooks.py:358 +msgid "You are missing permissions to delete books" +msgstr "" + +#: cps/editbooks.py:373 cps/editbooks.py:765 cps/web.py:518 cps/web.py:1783 +#: cps/web.py:1825 cps/web.py:1870 +msgid "Oops! Selected book title is unavailable. File does not exist or is not accessible" +msgstr "oh, oh, el libro seleccionado no está disponible. El archivo no existe o no es accesible" + +#: cps/editbooks.py:408 +msgid "edit metadata" +msgstr "editar metadatos" + +#: cps/editbooks.py:457 +#, python-format +msgid "%(seriesindex)s is not a valid number, skipping" +msgstr "%(seriesindex) no es un número válido, saltando" + +#: cps/editbooks.py:493 cps/editbooks.py:1001 +#, fuzzy, python-format +msgid "'%(langname)s' is not a valid language" +msgstr "%(langname)s no es un idioma válido" + +#: cps/editbooks.py:634 +msgid "User has no rights to upload additional file formats" +msgstr "" + +#: cps/editbooks.py:639 cps/editbooks.py:1029 +#, python-format +msgid "File extension '%(ext)s' is not allowed to be uploaded to this server" +msgstr "No se permite subir archivos con la extensión '%(ext)s' a este servidor" + +#: cps/editbooks.py:643 cps/editbooks.py:1033 +msgid "File to be uploaded must have an extension" +msgstr "El archivo a subir debe tener una extensión" + +#: cps/editbooks.py:655 +#, python-format +msgid "Failed to create path %(path)s (Permission denied)." +msgstr "Fallo al crear la ruta %(path)s (permiso denegado)" + +#: cps/editbooks.py:660 +#, python-format +msgid "Failed to store file %(file)s." +msgstr "Fallo al guardar el archivo %(file)s." + +#: cps/editbooks.py:683 #, python-format msgid "File format %(ext)s added to %(book)s" msgstr "Archivo con formato %(ext)s añadido a %(book)s" -#: cps/editbooks.py:814 +#: cps/editbooks.py:697 cps/editbooks.py:809 +msgid "User has no rights to upload cover" +msgstr "" + +#: cps/editbooks.py:828 msgid "Identifiers are not Case Sensitive, Overwriting Old Identifier" msgstr "Los identificadores no distinguen entre mayúsculas y minúsculas, sobrescribiendo el identificador antiguo" -#: cps/editbooks.py:848 +#: cps/editbooks.py:869 msgid "Metadata successfully updated" msgstr "Metadatos actualizados con éxito" -#: cps/editbooks.py:861 -msgid "Error editing book, please check logfile for details" -msgstr "Error al editar el libro, por favor, compruebe el archivo de registro (logfile) para tener más detalles" +#: cps/editbooks.py:887 +msgid "Error editing book: {}" +msgstr "" -#: cps/editbooks.py:899 +#: cps/editbooks.py:951 msgid "Uploaded book probably exists in the library, consider to change before upload new: " msgstr "El libro cargado probablemente existe en la biblioteca, considera cambiarlo antes de subirlo de nuevo: " -#: cps/editbooks.py:997 +#: cps/editbooks.py:1041 #, python-format msgid "File %(filename)s could not saved to temp dir" msgstr "El archivo %(filename)s no pudo salvarse en el directorio temporal (Temp Dir)" -#: cps/editbooks.py:1016 +#: cps/editbooks.py:1061 #, python-format msgid "Failed to Move Cover File %(file)s: %(error)s" msgstr "Fallo al mover el archivo de cubierta %(file)s: %(error)s" -#: cps/editbooks.py:1063 +#: cps/editbooks.py:1117 #, python-format msgid "File %(file)s uploaded" msgstr "El fichero %(file)s ha sido subido" -#: cps/editbooks.py:1088 +#: cps/editbooks.py:1143 msgid "Source or destination format for conversion missing" msgstr "Falta la fuente o el formato de destino para la conversión" -#: cps/editbooks.py:1096 +#: cps/editbooks.py:1151 #, python-format msgid "Book successfully queued for converting to %(book_format)s" msgstr "Libro puesto a la cola para su conversión a %(book_format)s" -#: cps/editbooks.py:1100 +#: cps/editbooks.py:1155 #, python-format msgid "There was an error converting this book: %(res)s" msgstr "Ocurrió un error al convertir este libro: %(res)s" @@ -614,175 +617,192 @@ msgstr "La configuración de Google Drive no se ha completado, intente desactiva msgid "Callback domain is not verified, please follow steps to verify domain in google developer console" msgstr "El dominio Callback no se ha verificado, siga los pasos para verificarlo en la consola de desarrollador de Google" -#: cps/helper.py:77 +#: cps/helper.py:81 #, python-format msgid "%(format)s format not found for book id: %(book)d" msgstr "%(format)s formato no encontrado para el id del libro: %(book)d" -#: cps/helper.py:83 cps/tasks/convert.py:73 +#: cps/helper.py:87 cps/tasks/convert.py:75 #, python-format msgid "%(format)s not found on Google Drive: %(fn)s" msgstr "%(format)s no encontrado en Google Drive: %(fn)s" -#: cps/helper.py:88 +#: cps/helper.py:92 #, python-format msgid "%(format)s not found: %(fn)s" msgstr "%(format)s no encontrado: %(fn)s" -#: cps/helper.py:93 cps/helper.py:217 cps/templates/detail.html:41 +#: cps/helper.py:97 cps/helper.py:221 cps/templates/detail.html:41 #: cps/templates/detail.html:45 msgid "Send to Kindle" msgstr "Enviar al Kindle" -#: cps/helper.py:94 cps/helper.py:111 cps/helper.py:219 +#: cps/helper.py:98 cps/helper.py:115 cps/helper.py:223 msgid "This e-mail has been sent via Calibre-Web." msgstr "Este correo electrónico ha sido enviado usando Calibre-Web." -#: cps/helper.py:109 +#: cps/helper.py:113 msgid "Calibre-Web test e-mail" msgstr "Correo de prueba de Calibre-Web" -#: cps/helper.py:110 +#: cps/helper.py:114 msgid "Test e-mail" msgstr "Comprobar correo electrónico" -#: cps/helper.py:127 +#: cps/helper.py:131 msgid "Get Started with Calibre-Web" msgstr "Primeros pasos con Calibre-Web" -#: cps/helper.py:132 +#: cps/helper.py:136 #, python-format msgid "Registration e-mail for user: %(name)s" msgstr "Correo electrónico de registro para el usuario: %(name)s" -#: cps/helper.py:143 cps/helper.py:149 +#: cps/helper.py:147 cps/helper.py:153 #, python-format msgid "Convert %(orig)s to %(format)s and send to Kindle" msgstr "Convertir %(orig)s a %(format)s y enviar al Kindle" -#: cps/helper.py:168 cps/helper.py:172 cps/helper.py:176 +#: cps/helper.py:172 cps/helper.py:176 cps/helper.py:180 #, python-format msgid "Send %(format)s to Kindle" msgstr "Enviado %(format)s al Kindle" -#: cps/helper.py:216 cps/tasks/convert.py:90 +#: cps/helper.py:220 cps/tasks/convert.py:92 #, fuzzy, python-format msgid "%(book)s send to Kindle" msgstr "Enviar al Kindle" -#: cps/helper.py:221 +#: cps/helper.py:225 msgid "The requested file could not be read. Maybe wrong permissions?" msgstr "El archivo solicitado no puede ser leído. ¿Quizás existen problemas con los permisos?" -#: cps/helper.py:313 +#: cps/helper.py:353 +msgid "Read status could not set: {}" +msgstr "" + +#: cps/helper.py:376 #, python-format msgid "Deleting bookfolder for book %(id)s failed, path has subfolders: %(path)s" msgstr "Fallo al intentar borrar la carpeta del libro %(id)s, la ruta tiene subcarpetas: %(path)s" -#: cps/helper.py:319 +#: cps/helper.py:382 #, python-format msgid "Deleting book %(id)s failed: %(message)s" msgstr "El eliminado del libro %(id)s falló: %(message)s" -#: cps/helper.py:330 +#: cps/helper.py:393 #, fuzzy, python-format msgid "Deleting book %(id)s from database only, book path in database not valid: %(path)s" msgstr "Borrando el libro %(id)s, la ruta del libro es no válida: %(path)s" -#: cps/helper.py:385 -#, python-format -msgid "Rename title from: '%(src)s' to '%(dest)s' failed with error: %(error)s" +#: cps/helper.py:458 +#, fuzzy, python-format +msgid "Rename author from: '%(src)s' to '%(dest)s' failed with error: %(error)s" msgstr "El renombrado del título de: '%(src)s' a '%(dest)s' falló con el error: %(error)s" -#: cps/helper.py:400 -#, python-format -msgid "Rename file in path '%(src)s' to '%(dest)s' failed with error: %(error)s" -msgstr "Ha fallado el cambio de nombre del archivo '%(src)s' a '%(dest)s' con el error: %(error)s" - -#: cps/helper.py:425 cps/helper.py:435 cps/helper.py:443 +#: cps/helper.py:529 cps/helper.py:538 #, python-format msgid "File %(file)s not found on Google Drive" msgstr "Fichero %(file)s no encontrado en Google Drive" -#: cps/helper.py:464 +#: cps/helper.py:572 +#, python-format +msgid "Rename title from: '%(src)s' to '%(dest)s' failed with error: %(error)s" +msgstr "El renombrado del título de: '%(src)s' a '%(dest)s' falló con el error: %(error)s" + +#: cps/helper.py:592 +msgid "Error in rename file in path: {}" +msgstr "" + +#: cps/helper.py:610 #, python-format msgid "Book path %(path)s not found on Google Drive" msgstr "La ruta %(path)s del libro no fue encontrada en Google Drive" -#: cps/helper.py:504 cps/web.py:1659 +#: cps/helper.py:651 cps/web.py:1737 #, fuzzy msgid "Found an existing account for this e-mail address" msgstr "Encontrada una cuenta existente para esa dirección de correo electrónico" -#: cps/helper.py:512 +#: cps/helper.py:659 msgid "This username is already taken" msgstr "Este nombre de usuario ya está en uso" -#: cps/helper.py:522 +#: cps/helper.py:669 msgid "Invalid e-mail address format" msgstr "Dirección de correo no válida" -#: cps/helper.py:595 +#: cps/helper.py:754 +msgid "Python modul 'advocate' is not installed but is needed for cover downloads" +msgstr "" + +#: cps/helper.py:767 msgid "Error Downloading Cover" msgstr "Error al descargar la cubierta" -#: cps/helper.py:598 +#: cps/helper.py:770 msgid "Cover Format Error" msgstr "Error en el formato de la cubierta" -#: cps/helper.py:608 +#: cps/helper.py:773 +msgid "You are not allowed to access localhost or the local network for cover uploads" +msgstr "" + +#: cps/helper.py:783 msgid "Failed to create path for cover" msgstr "Error al crear una ruta para la cubierta" -#: cps/helper.py:624 +#: cps/helper.py:799 msgid "Cover-file is not a valid image file, or could not be stored" msgstr "El archivo de cubierta no es una imágen válida" -#: cps/helper.py:635 +#: cps/helper.py:810 msgid "Only jpg/jpeg/png/webp/bmp files are supported as coverfile" msgstr "Sólo se admiten como portada los archivos jpg/jpeg/png/webp/bmp" -#: cps/helper.py:648 +#: cps/helper.py:822 msgid "Invalid cover file content" msgstr "" -#: cps/helper.py:652 +#: cps/helper.py:826 msgid "Only jpg/jpeg files are supported as coverfile" msgstr "Sólo se admiten como portada los archivos jpg/jpeg" -#: cps/helper.py:704 +#: cps/helper.py:878 msgid "Unrar binary file not found" msgstr "No se encuentra el archivo binario UnRar" -#: cps/helper.py:715 +#: cps/helper.py:889 msgid "Error excecuting UnRar" msgstr "Error ejecutando UnRar" -#: cps/helper.py:763 +#: cps/helper.py:937 msgid "Waiting" msgstr "Esperando" -#: cps/helper.py:765 +#: cps/helper.py:939 msgid "Failed" msgstr "Fallido" -#: cps/helper.py:767 +#: cps/helper.py:941 msgid "Started" msgstr "Comenzado" -#: cps/helper.py:769 +#: cps/helper.py:943 msgid "Finished" msgstr "Finalizado" -#: cps/helper.py:771 +#: cps/helper.py:945 msgid "Unknown Status" msgstr "Estado desconocido" -#: cps/kobo_auth.py:127 -msgid "PLease access calibre-web from non localhost to get valid api_endpoint for kobo device" +#: cps/kobo_auth.py:128 +#, fuzzy +msgid "Please access Calibre-Web from non localhost to get valid api_endpoint for kobo device" msgstr "Por favor, accede a calibre-web desde una ubicación que no sea localhost para obtener una api_endpoint válida para tu dispositivo Kobo" -#: cps/kobo_auth.py:130 cps/kobo_auth.py:158 +#: cps/kobo_auth.py:154 msgid "Kobo Setup" msgstr "Configuración de Kobo" @@ -791,7 +811,7 @@ msgstr "Configuración de Kobo" msgid "Register with %(provider)s" msgstr "Registrado con %(provider)s" -#: cps/oauth_bb.py:138 cps/remotelogin.py:133 cps/web.py:1535 +#: cps/oauth_bb.py:138 cps/remotelogin.py:130 cps/web.py:1613 #, python-format msgid "you are now logged in as: '%(nickname)s'" msgstr "has iniciado sesión como : '%(nickname)s'" @@ -852,163 +872,163 @@ msgstr "Error en Google Oauth, por favor vuelva a intentarlo más tarde." msgid "Google Oauth error: {}" msgstr "Error Google Oauth {}" -#: cps/opds.py:384 +#: cps/opds.py:298 msgid "{} Stars" msgstr "{} Estrellas" -#: cps/remotelogin.py:65 cps/templates/layout.html:84 -#: cps/templates/login.html:4 cps/templates/login.html:21 cps/web.py:1584 +#: cps/remotelogin.py:62 cps/templates/layout.html:84 +#: cps/templates/login.html:4 cps/templates/login.html:21 cps/web.py:1662 msgid "Login" msgstr "Inicio de sesión" -#: cps/remotelogin.py:77 cps/remotelogin.py:111 +#: cps/remotelogin.py:74 cps/remotelogin.py:108 msgid "Token not found" msgstr "Token no encontrado" -#: cps/remotelogin.py:86 cps/remotelogin.py:119 +#: cps/remotelogin.py:83 cps/remotelogin.py:116 msgid "Token has expired" msgstr "El token ha expirado" -#: cps/remotelogin.py:95 +#: cps/remotelogin.py:92 msgid "Success! Please return to your device" msgstr "¡Correcto! Por favor regrese a su dispositivo" -#: cps/render_template.py:39 cps/web.py:416 +#: cps/render_template.py:41 cps/web.py:407 msgid "Books" msgstr "Libros" -#: cps/render_template.py:41 +#: cps/render_template.py:43 msgid "Show recent books" msgstr "Mostrar libros recientes" -#: cps/render_template.py:42 cps/templates/index.xml:25 +#: cps/render_template.py:44 cps/templates/index.xml:25 msgid "Hot Books" msgstr "Libros populares" -#: cps/render_template.py:44 +#: cps/render_template.py:46 msgid "Show Hot Books" msgstr "Mostrar libros populares" -#: cps/render_template.py:46 cps/render_template.py:51 +#: cps/render_template.py:48 cps/render_template.py:53 msgid "Downloaded Books" msgstr "Libros Descargados" -#: cps/render_template.py:48 cps/render_template.py:53 +#: cps/render_template.py:50 cps/render_template.py:55 #: cps/templates/user_table.html:167 msgid "Show Downloaded Books" msgstr "Mostrar Libros Descargados" -#: cps/render_template.py:56 cps/templates/index.xml:32 cps/web.py:430 +#: cps/render_template.py:58 cps/templates/index.xml:32 cps/web.py:422 msgid "Top Rated Books" msgstr "Libros mejor valorados" -#: cps/render_template.py:58 cps/templates/user_table.html:161 +#: cps/render_template.py:60 cps/templates/user_table.html:161 msgid "Show Top Rated Books" msgstr "Mostrar libros mejor valorados" -#: cps/render_template.py:59 cps/templates/index.xml:54 -#: cps/templates/index.xml:58 cps/web.py:676 +#: cps/render_template.py:61 cps/templates/index.xml:54 +#: cps/templates/index.xml:58 cps/web.py:729 msgid "Read Books" msgstr "Libros leídos" -#: cps/render_template.py:61 +#: cps/render_template.py:63 msgid "Show read and unread" msgstr "Mostrar leídos y no leídos" -#: cps/render_template.py:63 cps/templates/index.xml:61 -#: cps/templates/index.xml:65 cps/web.py:679 +#: cps/render_template.py:65 cps/templates/index.xml:61 +#: cps/templates/index.xml:65 cps/web.py:732 msgid "Unread Books" msgstr "Libros no leídos" -#: cps/render_template.py:65 +#: cps/render_template.py:67 msgid "Show unread" msgstr "Mostrar no leído" -#: cps/render_template.py:66 +#: cps/render_template.py:68 msgid "Discover" msgstr "Descubrir" -#: cps/render_template.py:68 cps/templates/index.xml:50 +#: cps/render_template.py:70 cps/templates/index.xml:50 #: cps/templates/user_table.html:162 msgid "Show Random Books" msgstr "Mostrar libros al azar" -#: cps/render_template.py:69 cps/templates/book_table.html:67 -#: cps/templates/index.xml:83 cps/web.py:1041 +#: cps/render_template.py:71 cps/templates/book_table.html:67 +#: cps/templates/index.xml:83 cps/web.py:1135 msgid "Categories" msgstr "Categorías" -#: cps/render_template.py:71 cps/templates/user_table.html:158 +#: cps/render_template.py:73 cps/templates/user_table.html:158 msgid "Show category selection" msgstr "Mostrar selección de categorías" -#: cps/render_template.py:72 cps/templates/book_edit.html:90 +#: cps/render_template.py:74 cps/templates/book_edit.html:90 #: cps/templates/book_table.html:68 cps/templates/index.xml:90 -#: cps/templates/search_form.html:69 cps/web.py:948 cps/web.py:959 +#: cps/templates/search_form.html:69 cps/web.py:1034 cps/web.py:1041 msgid "Series" msgstr "Series" -#: cps/render_template.py:74 cps/templates/user_table.html:157 +#: cps/render_template.py:76 cps/templates/user_table.html:157 msgid "Show series selection" msgstr "Mostrar selección de series" -#: cps/render_template.py:75 cps/templates/book_table.html:66 +#: cps/render_template.py:77 cps/templates/book_table.html:66 #: cps/templates/index.xml:69 msgid "Authors" msgstr "Autores" -#: cps/render_template.py:77 cps/templates/user_table.html:160 +#: cps/render_template.py:79 cps/templates/user_table.html:160 msgid "Show author selection" msgstr "Mostrar selección de autores" -#: cps/render_template.py:79 cps/templates/book_table.html:72 -#: cps/templates/index.xml:76 cps/web.py:925 +#: cps/render_template.py:81 cps/templates/book_table.html:72 +#: cps/templates/index.xml:76 cps/web.py:1006 msgid "Publishers" msgstr "Editores" -#: cps/render_template.py:81 cps/templates/user_table.html:163 +#: cps/render_template.py:83 cps/templates/user_table.html:163 msgid "Show publisher selection" msgstr "Mostrar selección de editores" -#: cps/render_template.py:82 cps/templates/book_table.html:70 +#: cps/render_template.py:84 cps/templates/book_table.html:70 #: cps/templates/index.xml:97 cps/templates/search_form.html:107 -#: cps/web.py:1018 +#: cps/web.py:1108 msgid "Languages" msgstr "Idiomas" -#: cps/render_template.py:85 cps/templates/user_table.html:155 +#: cps/render_template.py:87 cps/templates/user_table.html:155 msgid "Show language selection" msgstr "Mostrar selección de idiomas" -#: cps/render_template.py:86 cps/templates/index.xml:104 +#: cps/render_template.py:88 cps/templates/index.xml:104 msgid "Ratings" msgstr "Calificaciones" -#: cps/render_template.py:88 cps/templates/user_table.html:164 +#: cps/render_template.py:90 cps/templates/user_table.html:164 msgid "Show ratings selection" msgstr "Mostrar selección de calificaciones" -#: cps/render_template.py:89 cps/templates/index.xml:112 +#: cps/render_template.py:91 cps/templates/index.xml:112 msgid "File formats" msgstr "Formatos de archivo" -#: cps/render_template.py:91 cps/templates/user_table.html:165 +#: cps/render_template.py:93 cps/templates/user_table.html:165 msgid "Show file formats selection" msgstr "Mostrar selección de formatos de archivo" -#: cps/render_template.py:93 cps/web.py:703 +#: cps/render_template.py:95 cps/web.py:755 msgid "Archived Books" msgstr "Libros archivados" -#: cps/render_template.py:95 cps/templates/user_table.html:166 +#: cps/render_template.py:97 cps/templates/user_table.html:166 msgid "Show archived books" msgstr "Mostrar libros archivados" -#: cps/render_template.py:97 cps/web.py:780 +#: cps/render_template.py:100 cps/web.py:837 msgid "Books List" msgstr "Lista de Libros" -#: cps/render_template.py:99 cps/templates/user_table.html:168 +#: cps/render_template.py:102 cps/templates/user_table.html:168 msgid "Show Books List" msgstr "Mostrar Lista de Libros" @@ -1063,262 +1083,266 @@ msgstr "" msgid "Create a Shelf" msgstr "Crear un estante" -#: cps/shelf.py:237 +#: cps/shelf.py:236 #, fuzzy msgid "Sorry you are not allowed to edit this shelf" msgstr "Lo siento, no tiene permiso para eliminar un libro del estante: %(sname)s" -#: cps/shelf.py:239 +#: cps/shelf.py:238 msgid "Edit a shelf" msgstr "Editar un estante" -#: cps/shelf.py:249 +#: cps/shelf.py:248 msgid "Sorry you are not allowed to create a public shelf" msgstr "" -#: cps/shelf.py:266 +#: cps/shelf.py:265 #, python-format msgid "Shelf %(title)s created" msgstr "Estante %(title)s creado" -#: cps/shelf.py:269 +#: cps/shelf.py:268 #, python-format msgid "Shelf %(title)s changed" msgstr "Estante %(title)s cambiado" -#: cps/shelf.py:283 +#: cps/shelf.py:282 msgid "There was an error" msgstr "Ha sucedido un error" -#: cps/shelf.py:305 +#: cps/shelf.py:304 #, python-format msgid "A public shelf with the name '%(title)s' already exists." msgstr "Ya existe un estante público con el nombre '%(title)s'." -#: cps/shelf.py:316 +#: cps/shelf.py:315 #, python-format msgid "A private shelf with the name '%(title)s' already exists." msgstr "Ya existe un estante privado con el nombre '%(title)s'." #: cps/shelf.py:337 +msgid "Error deleting Shelf" +msgstr "" + +#: cps/shelf.py:339 #, fuzzy msgid "Shelf successfully deleted" msgstr "Libro eliminado con éxito" -#: cps/shelf.py:386 +#: cps/shelf.py:389 #, python-format msgid "Change order of Shelf: '%(name)s'" msgstr "Cambiar orden del estante: '%(name)s'" -#: cps/shelf.py:456 +#: cps/shelf.py:461 #, python-format msgid "Shelf: '%(name)s'" msgstr "Estante: '%(name)s'" -#: cps/shelf.py:460 +#: cps/shelf.py:465 msgid "Error opening shelf. Shelf does not exist or is not accessible" msgstr "Error al abrir un estante. El estante no existe o no es accesible" -#: cps/updater.py:403 cps/updater.py:414 cps/updater.py:514 cps/updater.py:529 +#: cps/updater.py:426 cps/updater.py:437 cps/updater.py:538 cps/updater.py:553 msgid "Unexpected data while reading update information" msgstr "Dato inesperado mientras se leía la información de actualización" -#: cps/updater.py:410 cps/updater.py:521 +#: cps/updater.py:433 cps/updater.py:545 msgid "No update available. You already have the latest version installed" msgstr "Actualización no disponible. Ya tienes instalada la versión más reciente" -#: cps/updater.py:428 +#: cps/updater.py:451 msgid "A new update is available. Click on the button below to update to the latest version." msgstr "Una nueva actualización está disponible. Haz clic en el botón inferior para actualizar a la versión más reciente." -#: cps/updater.py:446 +#: cps/updater.py:469 msgid "Could not fetch update information" msgstr "No se puede conseguir información sobre la actualización" -#: cps/updater.py:456 +#: cps/updater.py:479 msgid "Click on the button below to update to the latest stable version." msgstr "Haz clic en el botón de abajo para actualizar a la última versión estable." -#: cps/updater.py:465 cps/updater.py:479 cps/updater.py:490 +#: cps/updater.py:488 cps/updater.py:502 cps/updater.py:513 #, python-format msgid "A new update is available. Click on the button below to update to version: %(version)s" msgstr "Hay una nueva actualización disponible. Haz clic en el botón de abajo para actualizar a la versión: %(version)s" -#: cps/updater.py:507 +#: cps/updater.py:531 msgid "No release information available" msgstr "No hay información del lanzamiento disponible" -#: cps/templates/index.html:5 cps/web.py:440 +#: cps/templates/index.html:5 cps/web.py:434 msgid "Discover (Random Books)" msgstr "Descubrir (Libros al azar)" -#: cps/web.py:471 +#: cps/web.py:470 msgid "Hot Books (Most Downloaded)" msgstr "Libros populares (los más descargados)" -#: cps/web.py:507 +#: cps/web.py:501 #, python-format msgid "Downloaded books by %(user)s" msgstr "Libros descargados por %(user)s" -#: cps/web.py:539 +#: cps/web.py:534 #, python-format msgid "Author: %(name)s" msgstr "Autor/es: %(name)s" -#: cps/web.py:554 +#: cps/web.py:570 #, python-format msgid "Publisher: %(name)s" msgstr "Editor/es: %(name)s" -#: cps/web.py:569 +#: cps/web.py:598 #, python-format msgid "Series: %(serie)s" msgstr "Series: %(serie)s" -#: cps/web.py:582 +#: cps/web.py:610 #, python-format msgid "Rating: %(rating)s stars" msgstr "Calificación: %(rating)s estrellas" -#: cps/web.py:597 +#: cps/web.py:626 #, python-format msgid "File format: %(format)s" msgstr "Formato del archivo: %(format)s" -#: cps/web.py:615 +#: cps/web.py:663 #, python-format msgid "Category: %(name)s" msgstr "Categoría : %(name)s" -#: cps/web.py:631 +#: cps/web.py:690 #, python-format msgid "Language: %(name)s" msgstr "Idioma: %(name)s" -#: cps/templates/layout.html:56 cps/web.py:737 cps/web.py:1371 +#: cps/templates/layout.html:56 cps/web.py:789 cps/web.py:1444 msgid "Advanced Search" msgstr "Búsqueda avanzada" #: cps/templates/book_edit.html:235 cps/templates/feed.xml:33 #: cps/templates/index.xml:11 cps/templates/layout.html:45 #: cps/templates/layout.html:48 cps/templates/search_form.html:226 -#: cps/web.py:750 cps/web.py:1077 +#: cps/web.py:807 cps/web.py:1164 msgid "Search" msgstr "Buscar" -#: cps/templates/admin.html:16 cps/web.py:903 +#: cps/templates/admin.html:16 cps/web.py:979 msgid "Downloads" msgstr "Descargas" -#: cps/web.py:980 +#: cps/web.py:1068 msgid "Ratings list" msgstr "Lista de calificaciones" -#: cps/web.py:1001 +#: cps/web.py:1095 msgid "File formats list" msgstr "Lista de formatos" -#: cps/templates/layout.html:73 cps/templates/tasks.html:7 cps/web.py:1055 +#: cps/templates/layout.html:73 cps/templates/tasks.html:7 cps/web.py:1149 msgid "Tasks" msgstr "Tareas" -#: cps/web.py:1215 +#: cps/web.py:1286 msgid "Published after " msgstr "Publicado después de " -#: cps/web.py:1222 +#: cps/web.py:1293 msgid "Published before " msgstr "Publicado antes de " -#: cps/web.py:1244 +#: cps/web.py:1315 #, python-format msgid "Rating <= %(rating)s" msgstr "Calificación <= %(rating)s" -#: cps/web.py:1246 +#: cps/web.py:1317 #, python-format msgid "Rating >= %(rating)s" msgstr "Calificación >= %(rating)s" -#: cps/web.py:1248 +#: cps/web.py:1319 #, python-format msgid "Read Status = %(status)s" msgstr "Estado de lectura = $(status)s" -#: cps/web.py:1353 +#: cps/web.py:1425 msgid "Error on search for custom columns, please restart Calibre-Web" msgstr "Error en la búsqueda de columnas personalizadas, por favor reinicia Calibre-Web" -#: cps/web.py:1449 +#: cps/web.py:1527 #, python-format msgid "Book successfully queued for sending to %(kindlemail)s" msgstr "Libro puesto en la cola de envío a %(kindlemail)s" -#: cps/web.py:1453 +#: cps/web.py:1531 #, python-format msgid "Oops! There was an error sending this book: %(res)s" msgstr "Ha sucedido un error en el envío del libro: %(res)s" -#: cps/web.py:1455 +#: cps/web.py:1533 msgid "Please update your profile with a valid Send to Kindle E-mail Address." msgstr "Por favor actualiza tu perfil con la dirección de correo de su kindle..." -#: cps/web.py:1472 +#: cps/web.py:1550 msgid "E-Mail server is not configured, please contact your administrator!" msgstr "El servidor de correo no está configurado, por favor, ¡avisa a tu administrador!" -#: cps/templates/layout.html:85 cps/templates/register.html:17 cps/web.py:1473 -#: cps/web.py:1480 cps/web.py:1486 cps/web.py:1505 cps/web.py:1509 -#: cps/web.py:1515 +#: cps/templates/layout.html:85 cps/templates/register.html:17 cps/web.py:1551 +#: cps/web.py:1558 cps/web.py:1564 cps/web.py:1583 cps/web.py:1587 +#: cps/web.py:1593 msgid "Register" msgstr "Registro" -#: cps/web.py:1507 +#: cps/web.py:1585 msgid "Your e-mail is not allowed to register" msgstr "Su correo electrónico no está permitido para registrarse" -#: cps/web.py:1510 +#: cps/web.py:1588 msgid "Confirmation e-mail was send to your e-mail account." msgstr "Se ha enviado un correo electrónico de verificación a su cuenta de correo." -#: cps/web.py:1524 +#: cps/web.py:1602 msgid "Cannot activate LDAP authentication" msgstr "No se puede activar la autenticación LDAP" -#: cps/web.py:1543 +#: cps/web.py:1621 #, python-format msgid "Fallback Login as: '%(nickname)s', LDAP Server not reachable, or user not known" msgstr "Fallback login como: '%(nickname)s', no se puede acceder al servidor LDAP o usuario desconocido" -#: cps/web.py:1549 +#: cps/web.py:1627 #, python-format msgid "Could not login: %(message)s" msgstr "No se pudo entrar: %(message)s" -#: cps/web.py:1553 cps/web.py:1578 +#: cps/web.py:1631 cps/web.py:1656 msgid "Wrong Username or Password" msgstr "Usuario o contraseña inválido" -#: cps/web.py:1560 +#: cps/web.py:1638 msgid "New Password was send to your email address" msgstr "Una nueva contraseña se ha enviado a su cuenta de correo electrónico" -#: cps/web.py:1566 +#: cps/web.py:1644 msgid "Please enter valid username to reset password" msgstr "Por favor, introduce un usuario válido para restablecer la contraseña" -#: cps/web.py:1573 +#: cps/web.py:1651 #, python-format msgid "You are now logged in as: '%(nickname)s'" msgstr "Ahora estás conectado como: '%(nickname)s'" -#: cps/web.py:1639 cps/web.py:1688 +#: cps/web.py:1717 cps/web.py:1766 #, python-format msgid "%(name)s's profile" msgstr "Perfil de %(name)s" -#: cps/web.py:1655 +#: cps/web.py:1733 msgid "Profile updated" msgstr "Perfil actualizado" @@ -1326,36 +1350,36 @@ msgstr "Perfil actualizado" msgid "Found no valid gmail.json file with OAuth information" msgstr "No se ha encontrado ningún archivo gmail.json válido con información OAuth" -#: cps/tasks/convert.py:137 +#: cps/tasks/convert.py:154 #, python-format msgid "Calibre ebook-convert %(tool)s not found" msgstr "Calibre ebook-convert %(tool)s no encontrado" -#: cps/tasks/convert.py:163 +#: cps/tasks/convert.py:187 #, python-format msgid "%(format)s format not found on disk" msgstr "%(format)s format no encontrado en disco" -#: cps/tasks/convert.py:167 +#: cps/tasks/convert.py:191 msgid "Ebook converter failed with unknown error" msgstr "El conversor de Ebook falló con un error desconocido" -#: cps/tasks/convert.py:177 +#: cps/tasks/convert.py:201 #, python-format msgid "Kepubify-converter failed: %(error)s" msgstr "Kepubify-converter falló: %(error)s" -#: cps/tasks/convert.py:199 +#: cps/tasks/convert.py:223 #, python-format msgid "Converted file not found or more than one file in folder %(folder)s" msgstr "Archivo convertido no encontrado, o más de un archivo en el directorio %(folder)s" -#: cps/tasks/convert.py:222 +#: cps/tasks/convert.py:246 #, python-format msgid "Ebook-converter failed: %(error)s" msgstr "Falló Ebook-converter: %(error)s" -#: cps/tasks/convert.py:245 +#: cps/tasks/convert.py:269 #, python-format msgid "Calibre failed with error: %(error)s" msgstr "Calibre falló con el error: %(error)s" @@ -1410,7 +1434,7 @@ msgid "Edit" msgstr "Editar" #: cps/templates/admin.html:25 cps/templates/book_edit.html:16 -#: cps/templates/book_table.html:97 cps/templates/modal_dialogs.html:63 +#: cps/templates/book_table.html:100 cps/templates/modal_dialogs.html:63 #: cps/templates/modal_dialogs.html:116 cps/templates/user_edit.html:67 #: cps/templates/user_table.html:149 msgid "Delete" @@ -1420,180 +1444,180 @@ msgstr "Borrar" msgid "Public Shelf" msgstr "Estantería pública" -#: cps/templates/admin.html:51 +#: cps/templates/admin.html:53 msgid "Add New User" msgstr "Añadir nuevo usuario" -#: cps/templates/admin.html:53 +#: cps/templates/admin.html:55 msgid "Import LDAP Users" msgstr "Importar usuarios LDAP" -#: cps/templates/admin.html:60 +#: cps/templates/admin.html:62 msgid "E-mail Server Settings" msgstr "Ajustes del servidor de correo electrónico" -#: cps/templates/admin.html:65 cps/templates/email_edit.html:31 +#: cps/templates/admin.html:67 cps/templates/email_edit.html:31 msgid "SMTP Hostname" msgstr "Servidor SMTP" -#: cps/templates/admin.html:69 cps/templates/email_edit.html:35 +#: cps/templates/admin.html:71 cps/templates/email_edit.html:35 msgid "SMTP Port" msgstr "Puerto SMTP" -#: cps/templates/admin.html:73 cps/templates/email_edit.html:39 +#: cps/templates/admin.html:75 cps/templates/email_edit.html:39 msgid "Encryption" msgstr "Encriptado" -#: cps/templates/admin.html:77 cps/templates/email_edit.html:47 +#: cps/templates/admin.html:79 cps/templates/email_edit.html:47 msgid "SMTP Login" msgstr "Login SMTP" -#: cps/templates/admin.html:81 cps/templates/admin.html:92 +#: cps/templates/admin.html:83 cps/templates/admin.html:94 #: cps/templates/email_edit.html:55 msgid "From E-mail" msgstr "Desde el correo" -#: cps/templates/admin.html:88 +#: cps/templates/admin.html:90 msgid "E-Mail Service" msgstr "Servicio de Correo" -#: cps/templates/admin.html:89 +#: cps/templates/admin.html:91 msgid "Gmail via Oauth2" msgstr "Gmail por Oauth2" -#: cps/templates/admin.html:104 +#: cps/templates/admin.html:106 msgid "Configuration" msgstr "Configuración" -#: cps/templates/admin.html:107 +#: cps/templates/admin.html:109 msgid "Calibre Database Directory" msgstr "Directorio de la base de datos de Calibre" -#: cps/templates/admin.html:111 cps/templates/config_edit.html:68 +#: cps/templates/admin.html:113 cps/templates/config_edit.html:68 msgid "Log Level" msgstr "Nivel de registro" -#: cps/templates/admin.html:115 +#: cps/templates/admin.html:117 msgid "Port" msgstr "Puerto" -#: cps/templates/admin.html:120 +#: cps/templates/admin.html:122 msgid "External Port" msgstr "Puerto externo" -#: cps/templates/admin.html:127 cps/templates/config_view_edit.html:28 +#: cps/templates/admin.html:129 cps/templates/config_view_edit.html:28 msgid "Books per Page" msgstr "Libros por página" -#: cps/templates/admin.html:131 +#: cps/templates/admin.html:133 msgid "Uploads" msgstr "Subidas" -#: cps/templates/admin.html:135 +#: cps/templates/admin.html:137 msgid "Anonymous Browsing" msgstr "Navegación anónima" -#: cps/templates/admin.html:139 +#: cps/templates/admin.html:141 msgid "Public Registration" msgstr "Registro público" -#: cps/templates/admin.html:143 +#: cps/templates/admin.html:145 msgid "Magic Link Remote Login" msgstr "Acceso remoto mediante enlace mágico" -#: cps/templates/admin.html:147 +#: cps/templates/admin.html:149 msgid "Reverse Proxy Login" msgstr "Acceso mediante Proxy inverso" -#: cps/templates/admin.html:152 cps/templates/config_edit.html:173 +#: cps/templates/admin.html:154 cps/templates/config_edit.html:173 msgid "Reverse Proxy Header Name" msgstr "Nombre de cabecera de Proxy inverso" -#: cps/templates/admin.html:157 +#: cps/templates/admin.html:159 #, fuzzy msgid "Edit Calibre Database Configuration" msgstr "Editar la configuración de la base de datos de Calibre" -#: cps/templates/admin.html:158 +#: cps/templates/admin.html:160 msgid "Edit Basic Configuration" msgstr "Editar la configuración básica" -#: cps/templates/admin.html:159 +#: cps/templates/admin.html:161 msgid "Edit UI Configuration" msgstr "Editar la configuración de la interfaz de usuario" -#: cps/templates/admin.html:164 +#: cps/templates/admin.html:166 msgid "Administration" msgstr "Administración" -#: cps/templates/admin.html:165 +#: cps/templates/admin.html:167 msgid "Download Debug Package" msgstr "Descargar paquete de debug" -#: cps/templates/admin.html:166 +#: cps/templates/admin.html:168 msgid "View Logs" msgstr "Ver archivos de registro" -#: cps/templates/admin.html:169 +#: cps/templates/admin.html:171 msgid "Reconnect Calibre Database" msgstr "Reconectar a la BD Calibre" -#: cps/templates/admin.html:170 +#: cps/templates/admin.html:172 msgid "Restart" msgstr "Reiniciar" -#: cps/templates/admin.html:171 +#: cps/templates/admin.html:173 msgid "Shutdown" msgstr "Apagar" -#: cps/templates/admin.html:176 +#: cps/templates/admin.html:178 msgid "Update" msgstr "Actualizar" -#: cps/templates/admin.html:180 +#: cps/templates/admin.html:182 msgid "Version" msgstr "Versión" -#: cps/templates/admin.html:181 +#: cps/templates/admin.html:183 msgid "Details" msgstr "Detalles" -#: cps/templates/admin.html:187 +#: cps/templates/admin.html:189 msgid "Current version" msgstr "Versión actual" -#: cps/templates/admin.html:194 +#: cps/templates/admin.html:196 msgid "Check for Update" msgstr "Comprobar actualizaciones" -#: cps/templates/admin.html:195 +#: cps/templates/admin.html:197 msgid "Perform Update" msgstr "Realizar actualización" -#: cps/templates/admin.html:208 +#: cps/templates/admin.html:210 msgid "Are you sure you want to restart?" msgstr "¿Realmente quieres reiniciar?" -#: cps/templates/admin.html:213 cps/templates/admin.html:227 -#: cps/templates/admin.html:247 cps/templates/config_db.html:70 +#: cps/templates/admin.html:215 cps/templates/admin.html:229 +#: cps/templates/admin.html:249 cps/templates/config_db.html:70 msgid "OK" msgstr "Ok" -#: cps/templates/admin.html:214 cps/templates/admin.html:228 -#: cps/templates/book_edit.html:213 cps/templates/book_table.html:124 +#: cps/templates/admin.html:216 cps/templates/admin.html:230 +#: cps/templates/book_edit.html:213 cps/templates/book_table.html:127 #: cps/templates/config_db.html:54 cps/templates/config_edit.html:359 -#: cps/templates/config_view_edit.html:173 cps/templates/modal_dialogs.html:64 +#: cps/templates/config_view_edit.html:175 cps/templates/modal_dialogs.html:64 #: cps/templates/modal_dialogs.html:99 cps/templates/modal_dialogs.html:117 #: cps/templates/modal_dialogs.html:135 cps/templates/shelf_edit.html:27 #: cps/templates/user_edit.html:144 msgid "Cancel" msgstr "Cancelar" -#: cps/templates/admin.html:226 +#: cps/templates/admin.html:228 msgid "Are you sure you want to shutdown?" msgstr "¿Realmente quiere detener?" -#: cps/templates/admin.html:238 +#: cps/templates/admin.html:240 msgid "Updating, please do not reload this page" msgstr "Actualizando. Por favor, no recargue la página" @@ -1605,44 +1629,43 @@ msgstr "via" msgid "In Library" msgstr "En la Librería" -#: cps/templates/author.html:26 cps/templates/index.html:72 -#: cps/templates/search.html:29 cps/templates/shelf.html:19 +#: cps/templates/author.html:26 cps/templates/index.html:73 +#: cps/templates/search.html:30 cps/templates/shelf.html:19 msgid "Sort according to book date, newest first" msgstr "Ordenar en base a fecha del libro, más reciente primero" -#: cps/templates/author.html:27 cps/templates/index.html:73 -#: cps/templates/search.html:30 cps/templates/shelf.html:20 +#: cps/templates/author.html:27 cps/templates/index.html:74 +#: cps/templates/search.html:31 cps/templates/shelf.html:20 msgid "Sort according to book date, oldest first" msgstr "Ordenar en base a fecha del libro, menos reciente primero" -#: cps/templates/author.html:28 cps/templates/index.html:74 -#: cps/templates/search.html:31 cps/templates/shelf.html:21 +#: cps/templates/author.html:28 cps/templates/index.html:75 +#: cps/templates/search.html:32 cps/templates/shelf.html:21 msgid "Sort title in alphabetical order" msgstr "Ordenar en base al título en orden alfabético" -#: cps/templates/author.html:29 cps/templates/index.html:75 -#: cps/templates/search.html:32 cps/templates/shelf.html:22 +#: cps/templates/author.html:29 cps/templates/index.html:76 +#: cps/templates/search.html:33 cps/templates/shelf.html:22 msgid "Sort title in reverse alphabetical order" msgstr "Ordenar en base al título en orden alfabético invertido" -#: cps/templates/author.html:30 cps/templates/index.html:78 -#: cps/templates/search.html:35 cps/templates/shelf.html:25 +#: cps/templates/author.html:30 cps/templates/index.html:79 +#: cps/templates/search.html:36 cps/templates/shelf.html:25 msgid "Sort according to publishing date, newest first" msgstr "Ordenar en base a fecha de publicación, más reciente primero" -#: cps/templates/author.html:31 cps/templates/index.html:79 -#: cps/templates/search.html:36 cps/templates/shelf.html:26 +#: cps/templates/author.html:31 cps/templates/index.html:80 +#: cps/templates/search.html:37 cps/templates/shelf.html:26 msgid "Sort according to publishing date, oldest first" msgstr "Ordenar en base a fecha de publicación, menos reciente primero" -#: cps/templates/author.html:57 cps/templates/author.html:117 -#: cps/templates/discover.html:30 cps/templates/index.html:29 -#: cps/templates/index.html:111 cps/templates/search.html:65 -#: cps/templates/shelf.html:54 +#: cps/templates/author.html:56 cps/templates/author.html:115 +#: cps/templates/index.html:29 cps/templates/index.html:112 +#: cps/templates/search.html:66 cps/templates/shelf.html:54 msgid "reduce" msgstr "reducir" -#: cps/templates/author.html:101 +#: cps/templates/author.html:99 msgid "More by" msgstr "Más de" @@ -1767,7 +1790,7 @@ msgid "Fetch Metadata" msgstr "Obtener metadatos" #: cps/templates/book_edit.html:212 cps/templates/config_db.html:53 -#: cps/templates/config_edit.html:358 cps/templates/config_view_edit.html:172 +#: cps/templates/config_edit.html:358 cps/templates/config_view_edit.html:174 #: cps/templates/email_edit.html:65 cps/templates/shelf_edit.html:25 #: cps/templates/shelf_order.html:41 cps/templates/user_edit.html:142 msgid "Save" @@ -1896,27 +1919,35 @@ msgstr "Introducir nombre de dominio" msgid "Comments" msgstr "" -#: cps/templates/book_table.html:77 cps/templates/book_table.html:79 -#: cps/templates/book_table.html:81 cps/templates/book_table.html:83 -#: cps/templates/book_table.html:87 cps/templates/book_table.html:89 -#: cps/templates/book_table.html:91 cps/templates/book_table.html:93 +#: cps/templates/book_table.html:75 +msgid "Archiv Status" +msgstr "" + +#: cps/templates/book_table.html:77 cps/templates/search_form.html:42 +msgid "Read Status" +msgstr "Leer estado" + +#: cps/templates/book_table.html:80 cps/templates/book_table.html:82 +#: cps/templates/book_table.html:84 cps/templates/book_table.html:86 +#: cps/templates/book_table.html:90 cps/templates/book_table.html:92 +#: cps/templates/book_table.html:96 #, fuzzy msgid "Enter " msgstr "Identificadores" -#: cps/templates/book_table.html:110 cps/templates/modal_dialogs.html:46 +#: cps/templates/book_table.html:113 cps/templates/modal_dialogs.html:46 msgid "Are you really sure?" msgstr "¿Estás realmente seguro?" -#: cps/templates/book_table.html:114 +#: cps/templates/book_table.html:117 msgid "Books with Title will be merged from:" msgstr "Libros con título serán fusionados de:" -#: cps/templates/book_table.html:118 +#: cps/templates/book_table.html:121 msgid "Into Book with Title:" msgstr "En el libro con el título:" -#: cps/templates/book_table.html:123 +#: cps/templates/book_table.html:126 msgid "Merge" msgstr "Fusionar" @@ -2093,11 +2124,6 @@ msgstr "Puerto del servidor LDAP" msgid "LDAP Encryption" msgstr "Encriptación LDAP" -#: cps/templates/config_edit.html:204 cps/templates/config_view_edit.html:62 -#: cps/templates/email_edit.html:41 -msgid "None" -msgstr "Ninguno" - #: cps/templates/config_edit.html:205 msgid "TLS" msgstr "TLS" @@ -2316,11 +2342,11 @@ msgstr "Visibilidad predeterminada para nuevos usuarios" msgid "Show Random Books in Detail View" msgstr "Mostrar libros aleatorios en la vista detallada" -#: cps/templates/config_view_edit.html:165 cps/templates/user_edit.html:87 +#: cps/templates/config_view_edit.html:166 cps/templates/user_edit.html:87 msgid "Add Allowed/Denied Tags" msgstr "Añadir etiquetas Permitidas/Denegados" -#: cps/templates/config_view_edit.html:166 +#: cps/templates/config_view_edit.html:167 msgid "Add Allowed/Denied custom column values" msgstr "Añadir valores personalizados Permitidos/Denegados" @@ -2369,13 +2395,13 @@ msgstr "Archivado" msgid "Description:" msgstr "Descripción:" -#: cps/templates/detail.html:256 cps/templates/search.html:14 +#: cps/templates/detail.html:256 cps/templates/search.html:15 msgid "Add to shelf" msgstr "Agregar al estante" #: cps/templates/detail.html:267 cps/templates/detail.html:284 #: cps/templates/feed.xml:79 cps/templates/layout.html:137 -#: cps/templates/search.html:20 +#: cps/templates/search.html:21 msgid "(Public)" msgstr "(Público)" @@ -2453,10 +2479,15 @@ msgstr "Dominios prohibidos (Blaclist)" msgid "Next" msgstr "Siguiente" -#: cps/templates/generate_kobo_auth_url.html:5 +#: cps/templates/generate_kobo_auth_url.html:6 msgid "Open the .kobo/Kobo eReader.conf file in a text editor and add (or edit):" msgstr "Abre el archivo .kobo/Kobo eReader.conf en un editor de texto y añade (o edita):" +#: cps/templates/generate_kobo_auth_url.html:11 +#, fuzzy +msgid "Kobo Token:" +msgstr "Token de sincronización de Kobo" + #: cps/templates/http_error.html:31 #, fuzzy msgid "Calibre-Web Instance is unconfigured, please contact your administrator" @@ -2474,29 +2505,29 @@ msgstr "Volver al inicio" msgid "Logout User" msgstr "Cerrar sesión" -#: cps/templates/index.html:69 +#: cps/templates/index.html:70 msgid "Sort ascending according to download count" msgstr "" -#: cps/templates/index.html:70 +#: cps/templates/index.html:71 msgid "Sort descending according to download count" msgstr "" -#: cps/templates/index.html:76 cps/templates/search.html:33 +#: cps/templates/index.html:77 cps/templates/search.html:34 #: cps/templates/shelf.html:23 msgid "Sort authors in alphabetical order" msgstr "Ordenar autores en orden alfabético" -#: cps/templates/index.html:77 cps/templates/search.html:34 +#: cps/templates/index.html:78 cps/templates/search.html:35 #: cps/templates/shelf.html:24 msgid "Sort authors in reverse alphabetical order" msgstr "Ordenar autores en orden alfabético inverso" -#: cps/templates/index.html:81 +#: cps/templates/index.html:82 msgid "Sort ascending according to series index" msgstr "Ordenar ascendientemente en base al índice de serie" -#: cps/templates/index.html:82 +#: cps/templates/index.html:83 msgid "Sort descending according to series index" msgstr "Ordenar descendientemente en base al índice de serie" @@ -2932,10 +2963,6 @@ msgstr "Fecha de publicación desde" msgid "Published Date To" msgstr "Fecha de publicación hasta" -#: cps/templates/search_form.html:42 -msgid "Read Status" -msgstr "Leer estado" - #: cps/templates/search_form.html:59 msgid "Exclude Tags" msgstr "Excluir etiquetas" diff --git a/cps/translations/fi/LC_MESSAGES/messages.mo b/cps/translations/fi/LC_MESSAGES/messages.mo index 7c98af45..ecb99d14 100644 Binary files a/cps/translations/fi/LC_MESSAGES/messages.mo and b/cps/translations/fi/LC_MESSAGES/messages.mo differ diff --git a/cps/translations/fi/LC_MESSAGES/messages.po b/cps/translations/fi/LC_MESSAGES/messages.po index 40b237d9..09dee98c 100644 --- a/cps/translations/fi/LC_MESSAGES/messages.po +++ b/cps/translations/fi/LC_MESSAGES/messages.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Calibre-Web\n" "Report-Msgid-Bugs-To: https://github.com/janeczku/Calibre-Web\n" -"POT-Creation-Date: 2022-01-15 09:19+0100\n" +"POT-Creation-Date: 2022-04-18 20:01+0200\n" "PO-Revision-Date: 2020-01-12 13:56+0100\n" "Last-Translator: Samuli Valavuo \n" "Language: fi\n" @@ -16,586 +16,589 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.9.0\n" +"Generated-By: Babel 2.9.1\n" -#: cps/about.py:34 cps/about.py:49 cps/about.py:65 cps/converter.py:31 -msgid "not installed" -msgstr "ei asennettu" - -#: cps/about.py:47 cps/about.py:63 -msgid "installed" -msgstr "asennettu" - -#: cps/about.py:145 +#: cps/about.py:86 msgid "Statistics" msgstr "Tilastot" -#: cps/admin.py:144 +#: cps/admin.py:141 msgid "Server restarted, please reload page" msgstr "Palvelin uudelleenkäynnistetty, ole hyvä ja päivitä sivu" -#: cps/admin.py:146 +#: cps/admin.py:143 msgid "Performing shutdown of server, please close window" msgstr "Palvelinta sammutetaan, ole hyvä ja sulje sivu" -#: cps/admin.py:154 +#: cps/admin.py:151 msgid "Reconnect successful" msgstr "" -#: cps/admin.py:157 +#: cps/admin.py:154 msgid "Unknown command" msgstr "" -#: cps/admin.py:167 cps/editbooks.py:707 cps/editbooks.py:721 -#: cps/editbooks.py:866 cps/editbooks.py:868 cps/editbooks.py:895 -#: cps/editbooks.py:911 cps/updater.py:584 cps/uploader.py:93 -#: cps/uploader.py:103 +#: cps/admin.py:176 cps/editbooks.py:713 cps/editbooks.py:892 +#: cps/editbooks.py:894 cps/editbooks.py:930 cps/editbooks.py:947 +#: cps/updater.py:608 cps/uploader.py:93 cps/uploader.py:103 msgid "Unknown" msgstr "Tuntematon" -#: cps/admin.py:188 +#: cps/admin.py:197 msgid "Admin page" msgstr "Ylläpitosivu" -#: cps/admin.py:207 +#: cps/admin.py:217 msgid "Basic Configuration" msgstr "Perusasetukset" -#: cps/admin.py:244 +#: cps/admin.py:255 msgid "UI Configuration" msgstr "Käyttöliittymän asetukset" -#: cps/admin.py:277 cps/templates/admin.html:50 +#: cps/admin.py:289 cps/templates/admin.html:51 #, fuzzy msgid "Edit Users" msgstr "Pääkäyttäjä" -#: cps/admin.py:318 cps/opds.py:109 cps/opds.py:198 cps/opds.py:275 -#: cps/opds.py:327 cps/templates/grid.html:13 cps/templates/languages.html:9 +#: cps/admin.py:333 cps/opds.py:529 cps/templates/grid.html:13 #: cps/templates/list.html:13 msgid "All" msgstr "Kaikki" -#: cps/admin.py:343 cps/admin.py:1615 +#: cps/admin.py:360 cps/admin.py:1648 msgid "User not found" msgstr "" -#: cps/admin.py:357 +#: cps/admin.py:374 msgid "{} users deleted successfully" msgstr "" -#: cps/admin.py:379 cps/templates/config_view_edit.html:133 +#: cps/admin.py:397 cps/templates/config_view_edit.html:133 #: cps/templates/user_edit.html:45 cps/templates/user_table.html:81 msgid "Show All" msgstr "Näytä kaikki" -#: cps/admin.py:400 cps/admin.py:406 +#: cps/admin.py:418 cps/admin.py:424 msgid "Malformed request" msgstr "" -#: cps/admin.py:418 cps/admin.py:1493 +#: cps/admin.py:436 cps/admin.py:1526 msgid "Guest Name can't be changed" msgstr "" -#: cps/admin.py:430 +#: cps/admin.py:448 msgid "Guest can't have this role" msgstr "" -#: cps/admin.py:442 cps/admin.py:1451 +#: cps/admin.py:460 cps/admin.py:1484 msgid "No admin user remaining, can't remove admin role" msgstr "" -#: cps/admin.py:446 cps/admin.py:460 +#: cps/admin.py:464 cps/admin.py:478 msgid "Value has to be true or false" msgstr "" -#: cps/admin.py:448 +#: cps/admin.py:466 msgid "Invalid role" msgstr "" -#: cps/admin.py:452 +#: cps/admin.py:470 msgid "Guest can't have this view" msgstr "" -#: cps/admin.py:462 +#: cps/admin.py:480 msgid "Invalid view" msgstr "" -#: cps/admin.py:465 +#: cps/admin.py:483 msgid "Guest's Locale is determined automatically and can't be set" msgstr "" -#: cps/admin.py:469 +#: cps/admin.py:487 msgid "No Valid Locale Given" msgstr "" -#: cps/admin.py:480 +#: cps/admin.py:498 msgid "No Valid Book Language Given" msgstr "" -#: cps/admin.py:482 +#: cps/admin.py:500 cps/editbooks.py:1267 msgid "Parameter not found" msgstr "" -#: cps/admin.py:533 +#: cps/admin.py:553 msgid "Invalid Read Column" msgstr "" -#: cps/admin.py:539 +#: cps/admin.py:559 msgid "Invalid Restricted Column" msgstr "" -#: cps/admin.py:560 cps/admin.py:1323 +#: cps/admin.py:579 cps/admin.py:1355 msgid "Calibre-Web configuration updated" msgstr "Calibre-Web asetukset päivitetty" -#: cps/admin.py:572 +#: cps/admin.py:591 msgid "Do you really want to delete the Kobo Token?" msgstr "" -#: cps/admin.py:574 +#: cps/admin.py:593 msgid "Do you really want to delete this domain?" msgstr "" -#: cps/admin.py:576 +#: cps/admin.py:595 msgid "Do you really want to delete this user?" msgstr "" -#: cps/admin.py:578 +#: cps/admin.py:597 msgid "Are you sure you want to delete this shelf?" msgstr "Oletko varma, että haluat poistaa hyllyn?" -#: cps/admin.py:580 +#: cps/admin.py:599 #, fuzzy msgid "Are you sure you want to change locales of selected user(s)?" msgstr "Oletko varma, että haluat poistaa hyllyn?" -#: cps/admin.py:582 +#: cps/admin.py:601 msgid "Are you sure you want to change visible book languages for selected user(s)?" msgstr "" -#: cps/admin.py:584 +#: cps/admin.py:603 msgid "Are you sure you want to change the selected role for the selected user(s)?" msgstr "" -#: cps/admin.py:586 +#: cps/admin.py:605 #, fuzzy msgid "Are you sure you want to change the selected restrictions for the selected user(s)?" msgstr "Oletko varma, että haluat poistaa hyllyn?" -#: cps/admin.py:588 +#: cps/admin.py:607 msgid "Are you sure you want to change the selected visibility restrictions for the selected user(s)?" msgstr "" -#: cps/admin.py:590 +#: cps/admin.py:610 #, fuzzy msgid "Are you sure you want to change shelf sync behavior for the selected user(s)?" msgstr "Oletko varma, että haluat poistaa hyllyn?" -#: cps/admin.py:592 +#: cps/admin.py:612 #, fuzzy msgid "Are you sure you want to change Calibre library location?" msgstr "Haluatko varmasti pysäyttää Calibre-Webin?" -#: cps/admin.py:594 +#: cps/admin.py:614 msgid "Are you sure you want delete Calibre-Web's sync database to force a full sync with your Kobo Reader?" msgstr "" -#: cps/admin.py:743 +#: cps/admin.py:764 msgid "Tag not found" msgstr "" -#: cps/admin.py:755 +#: cps/admin.py:776 msgid "Invalid Action" msgstr "" -#: cps/admin.py:871 cps/admin.py:877 cps/admin.py:887 cps/admin.py:897 +#: cps/admin.py:893 cps/admin.py:899 cps/admin.py:909 cps/admin.py:919 #: cps/templates/modal_dialogs.html:29 cps/templates/user_table.html:41 #: cps/templates/user_table.html:58 msgid "Deny" msgstr "" -#: cps/admin.py:873 cps/admin.py:879 cps/admin.py:889 cps/admin.py:899 +#: cps/admin.py:895 cps/admin.py:901 cps/admin.py:911 cps/admin.py:921 #: cps/templates/modal_dialogs.html:28 cps/templates/user_table.html:44 #: cps/templates/user_table.html:61 msgid "Allow" msgstr "" -#: cps/admin.py:913 +#: cps/admin.py:936 msgid "{} sync entries deleted" msgstr "" -#: cps/admin.py:1036 +#: cps/admin.py:1059 msgid "client_secrets.json Is Not Configured For Web Application" msgstr "" -#: cps/admin.py:1081 +#: cps/admin.py:1104 msgid "Logfile Location is not Valid, Please Enter Correct Path" msgstr "" -#: cps/admin.py:1087 +#: cps/admin.py:1110 msgid "Access Logfile Location is not Valid, Please Enter Correct Path" msgstr "" -#: cps/admin.py:1117 +#: cps/admin.py:1140 msgid "Please Enter a LDAP Provider, Port, DN and User Object Identifier" msgstr "" -#: cps/admin.py:1123 +#: cps/admin.py:1146 msgid "Please Enter a LDAP Service Account and Password" msgstr "" -#: cps/admin.py:1126 +#: cps/admin.py:1149 msgid "Please Enter a LDAP Service Account" msgstr "" -#: cps/admin.py:1131 +#: cps/admin.py:1154 #, python-format msgid "LDAP Group Object Filter Needs to Have One \"%s\" Format Identifier" msgstr "" -#: cps/admin.py:1133 +#: cps/admin.py:1156 msgid "LDAP Group Object Filter Has Unmatched Parenthesis" msgstr "" -#: cps/admin.py:1137 +#: cps/admin.py:1160 #, python-format msgid "LDAP User Object Filter needs to Have One \"%s\" Format Identifier" msgstr "" -#: cps/admin.py:1139 +#: cps/admin.py:1162 msgid "LDAP User Object Filter Has Unmatched Parenthesis" msgstr "" -#: cps/admin.py:1146 +#: cps/admin.py:1169 #, python-format msgid "LDAP Member User Filter needs to Have One \"%s\" Format Identifier" msgstr "" -#: cps/admin.py:1148 +#: cps/admin.py:1171 msgid "LDAP Member User Filter Has Unmatched Parenthesis" msgstr "" -#: cps/admin.py:1155 +#: cps/admin.py:1178 msgid "LDAP CACertificate, Certificate or Key Location is not Valid, Please Enter Correct Path" msgstr "" -#: cps/admin.py:1197 cps/admin.py:1308 cps/admin.py:1405 cps/admin.py:1521 -#: cps/admin.py:1590 cps/shelf.py:100 cps/shelf.py:160 cps/shelf.py:203 -#: cps/shelf.py:279 cps/shelf.py:341 cps/shelf.py:376 cps/shelf.py:451 -msgid "Settings DB is not Writeable" -msgstr "" - -#: cps/admin.py:1208 -msgid "DB Location is not Valid, Please Enter Correct Path" -msgstr "" - -#: cps/admin.py:1223 -msgid "DB is not Writeable" -msgstr "" - -#: cps/admin.py:1235 -msgid "Keyfile Location is not Valid, Please Enter Correct Path" -msgstr "" - -#: cps/admin.py:1239 -msgid "Certfile Location is not Valid, Please Enter Correct Path" -msgstr "" - -#: cps/admin.py:1346 -#, fuzzy -msgid "Database Settings updated" -msgstr "Sähköpostipalvelimen tiedot päivitetty" - -#: cps/admin.py:1354 -#, fuzzy -msgid "Database Configuration" -msgstr "Ominaisuuksien asetukset" - -#: cps/admin.py:1370 cps/web.py:1479 -msgid "Please fill out all fields!" -msgstr "Ole hyvä ja täytä kaikki kentät!" - -#: cps/admin.py:1378 -msgid "E-mail is not from valid domain" -msgstr "Sähköpostiosoite ei ole toimivasta domainista" - -#: cps/admin.py:1384 cps/admin.py:1543 -msgid "Add new user" -msgstr "Lisää uusi käyttäjä" - -#: cps/admin.py:1395 -#, python-format -msgid "User '%(user)s' created" -msgstr "Käyttäjä '%(user)s' lisätty" - -#: cps/admin.py:1401 -#, fuzzy -msgid "Found an existing account for this e-mail address or name." -msgstr "Tälle sähköpostiosoitteelle tai tunnukselle löytyi jo tili." - -#: cps/admin.py:1430 -#, python-format -msgid "User '%(nick)s' deleted" -msgstr "Käyttäjä '%(nick)s' poistettu" - -#: cps/admin.py:1432 cps/admin.py:1433 -msgid "Can't delete Guest User" -msgstr "" - -#: cps/admin.py:1436 -msgid "No admin user remaining, can't delete user" -msgstr "Pääkäyttäjiä ei jää jäljelle, käyttäjää ei voi poistaa" - -#: cps/admin.py:1509 cps/admin.py:1634 -#, python-format -msgid "Edit User %(nick)s" -msgstr "Muokkaa käyttäjää %(nick)s" - -#: cps/admin.py:1513 -#, python-format -msgid "User '%(nick)s' updated" -msgstr "Käyttäjä '%(nick)s' päivitetty" - -#: cps/admin.py:1517 cps/admin.py:1649 cps/web.py:1504 cps/web.py:1564 -msgid "An unknown error occurred. Please try again later." -msgstr "Tapahtui tuntematon virhe. Yritä myöhemmin uudelleen." - -#: cps/admin.py:1552 cps/templates/admin.html:98 -msgid "Edit E-mail Server Settings" -msgstr "Muuta SMTP asetuksia" - -#: cps/admin.py:1571 -msgid "Gmail Account Verification Successful" -msgstr "" - -#: cps/admin.py:1597 -#, python-format -msgid "Test e-mail queued for sending to %(email)s, please check Tasks for result" -msgstr "" - -#: cps/admin.py:1600 -#, python-format -msgid "There was an error sending the Test e-mail: %(res)s" -msgstr "Testisähköpostin lähetyksessä tapahtui virhe: %(res)s" - -#: cps/admin.py:1602 -msgid "Please configure your e-mail address first..." -msgstr "" - -#: cps/admin.py:1604 -msgid "E-mail server settings updated" -msgstr "Sähköpostipalvelimen tiedot päivitetty" - -#: cps/admin.py:1646 -#, python-format -msgid "Password for user %(user)s reset" -msgstr "Käyttäjän %(user)s salasana palautettu" - -#: cps/admin.py:1652 cps/web.py:1444 -msgid "Please configure the SMTP mail settings first..." -msgstr "Ole hyvä ja aseta SMTP postiasetukset ensin..." - -#: cps/admin.py:1663 -msgid "Logfile viewer" -msgstr "Lokitiedoston katselin" - -#: cps/admin.py:1729 -msgid "Requesting update package" -msgstr "Haetaan päivitystiedostoa" - -#: cps/admin.py:1730 -msgid "Downloading update package" -msgstr "Ladataan päivitystiedostoa" - -#: cps/admin.py:1731 -msgid "Unzipping update package" -msgstr "Puretaan päivitystiedostoa" - -#: cps/admin.py:1732 -msgid "Replacing files" -msgstr "Korvataan tiedostoja" - -#: cps/admin.py:1733 -msgid "Database connections are closed" -msgstr "Tietokantayhteydet on katkaistu" - -#: cps/admin.py:1734 -msgid "Stopping server" -msgstr "Sammutetaan palvelin" - -#: cps/admin.py:1735 -msgid "Update finished, please press okay and reload page" -msgstr "Päivitys valmistui, ole hyvä ja paina OK ja lataa sivu uudelleen" - -#: cps/admin.py:1736 cps/admin.py:1737 cps/admin.py:1738 cps/admin.py:1739 -#: cps/admin.py:1740 cps/admin.py:1741 -msgid "Update failed:" -msgstr "Päivitys epäonnistui:" - -#: cps/admin.py:1736 cps/updater.py:385 cps/updater.py:595 cps/updater.py:597 -msgid "HTTP Error" -msgstr "HTTP virhe" - -#: cps/admin.py:1737 cps/updater.py:387 cps/updater.py:599 -msgid "Connection error" -msgstr "Yhteysvirhe" - -#: cps/admin.py:1738 cps/updater.py:389 cps/updater.py:601 -msgid "Timeout while establishing connection" -msgstr "Aikakatkaisu yhteyttä luotaessa" - -#: cps/admin.py:1739 cps/updater.py:391 cps/updater.py:603 -msgid "General error" -msgstr "Yleinen virhe" - -#: cps/admin.py:1740 -msgid "Update file could not be saved in temp dir" -msgstr "" - -#: cps/admin.py:1741 -msgid "Files could not be replaced during update" -msgstr "" - -#: cps/admin.py:1765 -msgid "Failed to extract at least One LDAP User" -msgstr "" - -#: cps/admin.py:1810 -msgid "Failed to Create at Least One LDAP User" -msgstr "" - -#: cps/admin.py:1823 -#, python-format -msgid "Error: %(ldaperror)s" -msgstr "" - -#: cps/admin.py:1827 -msgid "Error: No user returned in response of LDAP server" -msgstr "" - -#: cps/admin.py:1860 -msgid "At Least One LDAP User Not Found in Database" -msgstr "" - -#: cps/admin.py:1862 -msgid "{} User Successfully Imported" -msgstr "" - -#: cps/converter.py:30 -msgid "not configured" -msgstr "" - -#: cps/converter.py:32 -msgid "Execution permissions missing" -msgstr "" - -#: cps/db.py:651 cps/web.py:667 cps/web.py:1155 -#, python-format -msgid "Custom Column No.%(column)d is not existing in calibre database" -msgstr "" - -#: cps/editbooks.py:300 cps/editbooks.py:302 -msgid "Book Format Successfully Deleted" -msgstr "" - -#: cps/editbooks.py:309 cps/editbooks.py:311 -msgid "Book Successfully Deleted" -msgstr "" - -#: cps/editbooks.py:361 -msgid "You are missing permissions to delete books" -msgstr "" - -#: cps/editbooks.py:376 cps/editbooks.py:763 cps/web.py:523 cps/web.py:1703 -#: cps/web.py:1744 cps/web.py:1811 -msgid "Oops! Selected book title is unavailable. File does not exist or is not accessible" -msgstr "Virhe eKirjan avaamisessa. Tiedostoa ei ole tai se ei ole saatavilla:" - -#: cps/editbooks.py:410 -msgid "edit metadata" -msgstr "muokkaa metadataa" - -#: cps/editbooks.py:458 -#, python-format -msgid "%(seriesindex)s is not a valid number, skipping" -msgstr "" - -#: cps/editbooks.py:494 cps/editbooks.py:958 -#, fuzzy, python-format -msgid "'%(langname)s' is not a valid language" -msgstr "%(langname)s ei ole kelvollinen kieli" - -#: cps/editbooks.py:634 cps/editbooks.py:985 -#, python-format -msgid "File extension '%(ext)s' is not allowed to be uploaded to this server" -msgstr "Tiedostopääte '%(ext)s' ei ole sallittujen palvelimelle ladattavien listalla" - -#: cps/editbooks.py:638 cps/editbooks.py:989 -msgid "File to be uploaded must have an extension" -msgstr "Ladattavalla tiedostolla on oltava tiedostopääte" - -#: cps/editbooks.py:650 -#, python-format -msgid "Failed to create path %(path)s (Permission denied)." -msgstr "Polun %(path)s luonti epäonnistui (Ei oikeutta)." - -#: cps/editbooks.py:655 -#, python-format -msgid "Failed to store file %(file)s." -msgstr "Tiedoston %(file)s tallennus epäonnistui." - -#: cps/editbooks.py:673 cps/editbooks.py:1076 cps/web.py:1664 +#: cps/admin.py:1223 cps/admin.py:1339 cps/admin.py:1437 cps/admin.py:1554 +#: cps/admin.py:1623 cps/editbooks.py:678 cps/editbooks.py:882 +#: cps/editbooks.py:1130 cps/shelf.py:100 cps/shelf.py:160 cps/shelf.py:203 +#: cps/shelf.py:278 cps/shelf.py:343 cps/shelf.py:380 cps/shelf.py:456 +#: cps/web.py:1742 #, python-format msgid "Database error: %(error)s." msgstr "" -#: cps/editbooks.py:678 +#: cps/admin.py:1235 +msgid "DB Location is not Valid, Please Enter Correct Path" +msgstr "" + +#: cps/admin.py:1253 +msgid "DB is not Writeable" +msgstr "" + +#: cps/admin.py:1266 +msgid "Keyfile Location is not Valid, Please Enter Correct Path" +msgstr "" + +#: cps/admin.py:1270 +msgid "Certfile Location is not Valid, Please Enter Correct Path" +msgstr "" + +#: cps/admin.py:1378 +#, fuzzy +msgid "Database Settings updated" +msgstr "Sähköpostipalvelimen tiedot päivitetty" + +#: cps/admin.py:1386 +#, fuzzy +msgid "Database Configuration" +msgstr "Ominaisuuksien asetukset" + +#: cps/admin.py:1402 cps/web.py:1557 +msgid "Please fill out all fields!" +msgstr "Ole hyvä ja täytä kaikki kentät!" + +#: cps/admin.py:1410 +msgid "E-mail is not from valid domain" +msgstr "Sähköpostiosoite ei ole toimivasta domainista" + +#: cps/admin.py:1416 cps/admin.py:1576 +msgid "Add new user" +msgstr "Lisää uusi käyttäjä" + +#: cps/admin.py:1427 +#, python-format +msgid "User '%(user)s' created" +msgstr "Käyttäjä '%(user)s' lisätty" + +#: cps/admin.py:1433 +#, fuzzy +msgid "Found an existing account for this e-mail address or name." +msgstr "Tälle sähköpostiosoitteelle tai tunnukselle löytyi jo tili." + +#: cps/admin.py:1463 +#, python-format +msgid "User '%(nick)s' deleted" +msgstr "Käyttäjä '%(nick)s' poistettu" + +#: cps/admin.py:1465 cps/admin.py:1466 +msgid "Can't delete Guest User" +msgstr "" + +#: cps/admin.py:1469 +msgid "No admin user remaining, can't delete user" +msgstr "Pääkäyttäjiä ei jää jäljelle, käyttäjää ei voi poistaa" + +#: cps/admin.py:1542 cps/admin.py:1667 +#, python-format +msgid "Edit User %(nick)s" +msgstr "Muokkaa käyttäjää %(nick)s" + +#: cps/admin.py:1546 +#, python-format +msgid "User '%(nick)s' updated" +msgstr "Käyttäjä '%(nick)s' päivitetty" + +#: cps/admin.py:1550 cps/admin.py:1682 cps/web.py:1582 cps/web.py:1642 +msgid "An unknown error occurred. Please try again later." +msgstr "Tapahtui tuntematon virhe. Yritä myöhemmin uudelleen." + +#: cps/admin.py:1585 cps/templates/admin.html:100 +msgid "Edit E-mail Server Settings" +msgstr "Muuta SMTP asetuksia" + +#: cps/admin.py:1604 +msgid "Gmail Account Verification Successful" +msgstr "" + +#: cps/admin.py:1630 +#, python-format +msgid "Test e-mail queued for sending to %(email)s, please check Tasks for result" +msgstr "" + +#: cps/admin.py:1633 +#, python-format +msgid "There was an error sending the Test e-mail: %(res)s" +msgstr "Testisähköpostin lähetyksessä tapahtui virhe: %(res)s" + +#: cps/admin.py:1635 +msgid "Please configure your e-mail address first..." +msgstr "" + +#: cps/admin.py:1637 +msgid "E-mail server settings updated" +msgstr "Sähköpostipalvelimen tiedot päivitetty" + +#: cps/admin.py:1679 +#, python-format +msgid "Password for user %(user)s reset" +msgstr "Käyttäjän %(user)s salasana palautettu" + +#: cps/admin.py:1685 cps/web.py:1522 +msgid "Please configure the SMTP mail settings first..." +msgstr "Ole hyvä ja aseta SMTP postiasetukset ensin..." + +#: cps/admin.py:1696 +msgid "Logfile viewer" +msgstr "Lokitiedoston katselin" + +#: cps/admin.py:1762 +msgid "Requesting update package" +msgstr "Haetaan päivitystiedostoa" + +#: cps/admin.py:1763 +msgid "Downloading update package" +msgstr "Ladataan päivitystiedostoa" + +#: cps/admin.py:1764 +msgid "Unzipping update package" +msgstr "Puretaan päivitystiedostoa" + +#: cps/admin.py:1765 +msgid "Replacing files" +msgstr "Korvataan tiedostoja" + +#: cps/admin.py:1766 +msgid "Database connections are closed" +msgstr "Tietokantayhteydet on katkaistu" + +#: cps/admin.py:1767 +msgid "Stopping server" +msgstr "Sammutetaan palvelin" + +#: cps/admin.py:1768 +msgid "Update finished, please press okay and reload page" +msgstr "Päivitys valmistui, ole hyvä ja paina OK ja lataa sivu uudelleen" + +#: cps/admin.py:1769 cps/admin.py:1770 cps/admin.py:1771 cps/admin.py:1772 +#: cps/admin.py:1773 cps/admin.py:1774 +msgid "Update failed:" +msgstr "Päivitys epäonnistui:" + +#: cps/admin.py:1769 cps/updater.py:384 cps/updater.py:619 cps/updater.py:621 +msgid "HTTP Error" +msgstr "HTTP virhe" + +#: cps/admin.py:1770 cps/updater.py:386 cps/updater.py:623 +msgid "Connection error" +msgstr "Yhteysvirhe" + +#: cps/admin.py:1771 cps/updater.py:388 cps/updater.py:625 +msgid "Timeout while establishing connection" +msgstr "Aikakatkaisu yhteyttä luotaessa" + +#: cps/admin.py:1772 cps/updater.py:390 cps/updater.py:627 +msgid "General error" +msgstr "Yleinen virhe" + +#: cps/admin.py:1773 +msgid "Update file could not be saved in temp dir" +msgstr "" + +#: cps/admin.py:1774 +msgid "Files could not be replaced during update" +msgstr "" + +#: cps/admin.py:1798 +msgid "Failed to extract at least One LDAP User" +msgstr "" + +#: cps/admin.py:1843 +msgid "Failed to Create at Least One LDAP User" +msgstr "" + +#: cps/admin.py:1856 +#, python-format +msgid "Error: %(ldaperror)s" +msgstr "" + +#: cps/admin.py:1860 +msgid "Error: No user returned in response of LDAP server" +msgstr "" + +#: cps/admin.py:1893 +msgid "At Least One LDAP User Not Found in Database" +msgstr "" + +#: cps/admin.py:1895 +msgid "{} User Successfully Imported" +msgstr "" + +#: cps/converter.py:30 +msgid "not installed" +msgstr "ei asennettu" + +#: cps/converter.py:31 +msgid "Execution permissions missing" +msgstr "" + +#: cps/db.py:674 cps/web.py:710 cps/web.py:1222 +#, python-format +msgid "Custom Column No.%(column)d is not existing in calibre database" +msgstr "" + +#: cps/db.py:917 cps/templates/config_edit.html:204 +#: cps/templates/config_view_edit.html:62 cps/templates/email_edit.html:41 +#: cps/web.py:551 cps/web.py:585 cps/web.py:646 cps/web.py:671 cps/web.py:1003 +#: cps/web.py:1032 cps/web.py:1066 cps/web.py:1093 cps/web.py:1132 +msgid "None" +msgstr "Ei mitään" + +#: cps/editbooks.py:295 cps/editbooks.py:297 +msgid "Book Format Successfully Deleted" +msgstr "" + +#: cps/editbooks.py:304 cps/editbooks.py:306 +msgid "Book Successfully Deleted" +msgstr "" + +#: cps/editbooks.py:358 +msgid "You are missing permissions to delete books" +msgstr "" + +#: cps/editbooks.py:373 cps/editbooks.py:765 cps/web.py:518 cps/web.py:1783 +#: cps/web.py:1825 cps/web.py:1870 +msgid "Oops! Selected book title is unavailable. File does not exist or is not accessible" +msgstr "Virhe eKirjan avaamisessa. Tiedostoa ei ole tai se ei ole saatavilla:" + +#: cps/editbooks.py:408 +msgid "edit metadata" +msgstr "muokkaa metadataa" + +#: cps/editbooks.py:457 +#, python-format +msgid "%(seriesindex)s is not a valid number, skipping" +msgstr "" + +#: cps/editbooks.py:493 cps/editbooks.py:1001 +#, fuzzy, python-format +msgid "'%(langname)s' is not a valid language" +msgstr "%(langname)s ei ole kelvollinen kieli" + +#: cps/editbooks.py:634 +msgid "User has no rights to upload additional file formats" +msgstr "" + +#: cps/editbooks.py:639 cps/editbooks.py:1029 +#, python-format +msgid "File extension '%(ext)s' is not allowed to be uploaded to this server" +msgstr "Tiedostopääte '%(ext)s' ei ole sallittujen palvelimelle ladattavien listalla" + +#: cps/editbooks.py:643 cps/editbooks.py:1033 +msgid "File to be uploaded must have an extension" +msgstr "Ladattavalla tiedostolla on oltava tiedostopääte" + +#: cps/editbooks.py:655 +#, python-format +msgid "Failed to create path %(path)s (Permission denied)." +msgstr "Polun %(path)s luonti epäonnistui (Ei oikeutta)." + +#: cps/editbooks.py:660 +#, python-format +msgid "Failed to store file %(file)s." +msgstr "Tiedoston %(file)s tallennus epäonnistui." + +#: cps/editbooks.py:683 #, python-format msgid "File format %(ext)s added to %(book)s" msgstr "Tiedostoformaatti %(ext)s lisätty %(book)s" -#: cps/editbooks.py:814 +#: cps/editbooks.py:697 cps/editbooks.py:809 +msgid "User has no rights to upload cover" +msgstr "" + +#: cps/editbooks.py:828 msgid "Identifiers are not Case Sensitive, Overwriting Old Identifier" msgstr "" -#: cps/editbooks.py:848 +#: cps/editbooks.py:869 msgid "Metadata successfully updated" msgstr "Metadata päivitetty onnistuneesti" -#: cps/editbooks.py:861 -msgid "Error editing book, please check logfile for details" -msgstr "Kirjan editoinnissa tapahtui virhe, tarkista virheilmoitus lokista" +#: cps/editbooks.py:887 +msgid "Error editing book: {}" +msgstr "" -#: cps/editbooks.py:899 +#: cps/editbooks.py:951 msgid "Uploaded book probably exists in the library, consider to change before upload new: " msgstr "" -#: cps/editbooks.py:997 +#: cps/editbooks.py:1041 #, python-format msgid "File %(filename)s could not saved to temp dir" msgstr "" -#: cps/editbooks.py:1016 +#: cps/editbooks.py:1061 #, python-format msgid "Failed to Move Cover File %(file)s: %(error)s" msgstr "" -#: cps/editbooks.py:1063 +#: cps/editbooks.py:1117 #, python-format msgid "File %(file)s uploaded" msgstr "Tiedosto %(file)s tallennettu" -#: cps/editbooks.py:1088 +#: cps/editbooks.py:1143 msgid "Source or destination format for conversion missing" msgstr "Lähteen tai kohteen tiedostomuoto puuttuu" -#: cps/editbooks.py:1096 +#: cps/editbooks.py:1151 #, python-format msgid "Book successfully queued for converting to %(book_format)s" msgstr "Kirja lisätty muutosjonoon muotoon %(book_format)s" -#: cps/editbooks.py:1100 +#: cps/editbooks.py:1155 #, python-format msgid "There was an error converting this book: %(res)s" msgstr "Kirjan muunnoksessa tapahtui virhe: %(res)s" @@ -608,175 +611,191 @@ msgstr "Google Drive asetukset ei ole valmiit. Koita poistaa Google Drive käyt msgid "Callback domain is not verified, please follow steps to verify domain in google developer console" msgstr "Paluuosoitteen domain ei ole varmistettu, seuraa ohjeita vamistaaksesi sen googlen kehittäjäkonsolissa" -#: cps/helper.py:77 +#: cps/helper.py:81 #, python-format msgid "%(format)s format not found for book id: %(book)d" msgstr "%(format)s tiedostomuotoa ei löytynyt kirjalle: %(book)d" -#: cps/helper.py:83 cps/tasks/convert.py:73 +#: cps/helper.py:87 cps/tasks/convert.py:75 #, python-format msgid "%(format)s not found on Google Drive: %(fn)s" msgstr "%(format)s ei löytynyt Google Drivesta: %(fn)s" -#: cps/helper.py:88 +#: cps/helper.py:92 #, python-format msgid "%(format)s not found: %(fn)s" msgstr "%(format)s ei löydy: %(fn)s" -#: cps/helper.py:93 cps/helper.py:217 cps/templates/detail.html:41 +#: cps/helper.py:97 cps/helper.py:221 cps/templates/detail.html:41 #: cps/templates/detail.html:45 msgid "Send to Kindle" msgstr "Lähetä Kindleen" -#: cps/helper.py:94 cps/helper.py:111 cps/helper.py:219 +#: cps/helper.py:98 cps/helper.py:115 cps/helper.py:223 msgid "This e-mail has been sent via Calibre-Web." msgstr "Tämä sähköposti on lähetetty Calibre-Web:sta." -#: cps/helper.py:109 +#: cps/helper.py:113 msgid "Calibre-Web test e-mail" msgstr "Calibre-Web testisähköposti" -#: cps/helper.py:110 +#: cps/helper.py:114 msgid "Test e-mail" msgstr "Testi sähköposti" -#: cps/helper.py:127 +#: cps/helper.py:131 msgid "Get Started with Calibre-Web" msgstr "Aloita Calibre-Web:in käyttö" -#: cps/helper.py:132 +#: cps/helper.py:136 #, python-format msgid "Registration e-mail for user: %(name)s" msgstr "Rekiströintisähköposti käyttäjälle: %(name)s" -#: cps/helper.py:143 cps/helper.py:149 +#: cps/helper.py:147 cps/helper.py:153 #, python-format msgid "Convert %(orig)s to %(format)s and send to Kindle" msgstr "Muunna %(orig)s muotoon %(format)s ja lähetä Kindleen" -#: cps/helper.py:168 cps/helper.py:172 cps/helper.py:176 +#: cps/helper.py:172 cps/helper.py:176 cps/helper.py:180 #, python-format msgid "Send %(format)s to Kindle" msgstr "Lähetä %(format)s Kindleen" -#: cps/helper.py:216 cps/tasks/convert.py:90 +#: cps/helper.py:220 cps/tasks/convert.py:92 #, fuzzy, python-format msgid "%(book)s send to Kindle" msgstr "Lähetä Kindleen" -#: cps/helper.py:221 +#: cps/helper.py:225 msgid "The requested file could not be read. Maybe wrong permissions?" msgstr "Haettua tiedostoa ei pystytty lukemaan. Ehkä vaäärät oikeudet?" -#: cps/helper.py:313 +#: cps/helper.py:353 +msgid "Read status could not set: {}" +msgstr "" + +#: cps/helper.py:376 #, python-format msgid "Deleting bookfolder for book %(id)s failed, path has subfolders: %(path)s" msgstr "" -#: cps/helper.py:319 +#: cps/helper.py:382 #, python-format msgid "Deleting book %(id)s failed: %(message)s" msgstr "" -#: cps/helper.py:330 +#: cps/helper.py:393 #, python-format msgid "Deleting book %(id)s from database only, book path in database not valid: %(path)s" msgstr "" -#: cps/helper.py:385 -#, python-format -msgid "Rename title from: '%(src)s' to '%(dest)s' failed with error: %(error)s" +#: cps/helper.py:458 +#, fuzzy, python-format +msgid "Rename author from: '%(src)s' to '%(dest)s' failed with error: %(error)s" msgstr "Tiedon muuttaminen arvosta: '%(src)s' arvoon '%(dest)s' epäonnistui virheeseen: %(error)s" -#: cps/helper.py:400 -#, python-format -msgid "Rename file in path '%(src)s' to '%(dest)s' failed with error: %(error)s" -msgstr "Tiedoston nimeäminen polusta '%(src)s' polkuun '%(dest)s' epäonnistui virheeseen: %(error)s" - -#: cps/helper.py:425 cps/helper.py:435 cps/helper.py:443 +#: cps/helper.py:529 cps/helper.py:538 #, python-format msgid "File %(file)s not found on Google Drive" msgstr "Tiedostoa %(file)s ei löytynyt Google Drivesta" -#: cps/helper.py:464 +#: cps/helper.py:572 +#, python-format +msgid "Rename title from: '%(src)s' to '%(dest)s' failed with error: %(error)s" +msgstr "Tiedon muuttaminen arvosta: '%(src)s' arvoon '%(dest)s' epäonnistui virheeseen: %(error)s" + +#: cps/helper.py:592 +msgid "Error in rename file in path: {}" +msgstr "" + +#: cps/helper.py:610 #, python-format msgid "Book path %(path)s not found on Google Drive" msgstr "Kirjan polkua %(path)s ei löytynyt Google Drivesta" -#: cps/helper.py:504 cps/web.py:1659 +#: cps/helper.py:651 cps/web.py:1737 #, fuzzy msgid "Found an existing account for this e-mail address" msgstr "Tälle sähköpostiosoitteelle läytyi jo käyttäjätunnus." -#: cps/helper.py:512 +#: cps/helper.py:659 msgid "This username is already taken" msgstr "" -#: cps/helper.py:522 +#: cps/helper.py:669 msgid "Invalid e-mail address format" msgstr "" -#: cps/helper.py:595 +#: cps/helper.py:754 +msgid "Python modul 'advocate' is not installed but is needed for cover downloads" +msgstr "" + +#: cps/helper.py:767 msgid "Error Downloading Cover" msgstr "" -#: cps/helper.py:598 +#: cps/helper.py:770 msgid "Cover Format Error" msgstr "" -#: cps/helper.py:608 +#: cps/helper.py:773 +msgid "You are not allowed to access localhost or the local network for cover uploads" +msgstr "" + +#: cps/helper.py:783 msgid "Failed to create path for cover" msgstr "" -#: cps/helper.py:624 +#: cps/helper.py:799 msgid "Cover-file is not a valid image file, or could not be stored" msgstr "" -#: cps/helper.py:635 +#: cps/helper.py:810 msgid "Only jpg/jpeg/png/webp/bmp files are supported as coverfile" msgstr "" -#: cps/helper.py:648 +#: cps/helper.py:822 msgid "Invalid cover file content" msgstr "" -#: cps/helper.py:652 +#: cps/helper.py:826 msgid "Only jpg/jpeg files are supported as coverfile" msgstr "" -#: cps/helper.py:704 +#: cps/helper.py:878 msgid "Unrar binary file not found" msgstr "" -#: cps/helper.py:715 +#: cps/helper.py:889 msgid "Error excecuting UnRar" msgstr "" -#: cps/helper.py:763 +#: cps/helper.py:937 msgid "Waiting" msgstr "Odottaa" -#: cps/helper.py:765 +#: cps/helper.py:939 msgid "Failed" msgstr "Epäonnistui" -#: cps/helper.py:767 +#: cps/helper.py:941 msgid "Started" msgstr "Aloitettu" -#: cps/helper.py:769 +#: cps/helper.py:943 msgid "Finished" msgstr "Valmistui" -#: cps/helper.py:771 +#: cps/helper.py:945 msgid "Unknown Status" msgstr "Tuntematon tila" -#: cps/kobo_auth.py:127 -msgid "PLease access calibre-web from non localhost to get valid api_endpoint for kobo device" +#: cps/kobo_auth.py:128 +msgid "Please access Calibre-Web from non localhost to get valid api_endpoint for kobo device" msgstr "" -#: cps/kobo_auth.py:130 cps/kobo_auth.py:158 +#: cps/kobo_auth.py:154 msgid "Kobo Setup" msgstr "" @@ -785,7 +804,7 @@ msgstr "" msgid "Register with %(provider)s" msgstr "Rekisteröi tuottajalle %(provider)s" -#: cps/oauth_bb.py:138 cps/remotelogin.py:133 cps/web.py:1535 +#: cps/oauth_bb.py:138 cps/remotelogin.py:130 cps/web.py:1613 #, python-format msgid "you are now logged in as: '%(nickname)s'" msgstr "olet nyt kirjautunut tunnuksella: \"%(nickname)s\"" @@ -846,163 +865,163 @@ msgstr "Google Oauth virhe, yritä myöhemmin uudelleen." msgid "Google Oauth error: {}" msgstr "" -#: cps/opds.py:384 +#: cps/opds.py:298 msgid "{} Stars" msgstr "" -#: cps/remotelogin.py:65 cps/templates/layout.html:84 -#: cps/templates/login.html:4 cps/templates/login.html:21 cps/web.py:1584 +#: cps/remotelogin.py:62 cps/templates/layout.html:84 +#: cps/templates/login.html:4 cps/templates/login.html:21 cps/web.py:1662 msgid "Login" msgstr "Kirjaudu sisään" -#: cps/remotelogin.py:77 cps/remotelogin.py:111 +#: cps/remotelogin.py:74 cps/remotelogin.py:108 msgid "Token not found" msgstr "Valtuutusta ei löytynyt" -#: cps/remotelogin.py:86 cps/remotelogin.py:119 +#: cps/remotelogin.py:83 cps/remotelogin.py:116 msgid "Token has expired" msgstr "Valtuutus vanhentunut" -#: cps/remotelogin.py:95 +#: cps/remotelogin.py:92 msgid "Success! Please return to your device" msgstr "Onnistui! Ole hyvä ja palaa laitteellesi" -#: cps/render_template.py:39 cps/web.py:416 +#: cps/render_template.py:41 cps/web.py:407 msgid "Books" msgstr "Kirjat" -#: cps/render_template.py:41 +#: cps/render_template.py:43 msgid "Show recent books" msgstr "Näytä viimeisimmät kirjat" -#: cps/render_template.py:42 cps/templates/index.xml:25 +#: cps/render_template.py:44 cps/templates/index.xml:25 msgid "Hot Books" msgstr "Kuumat kirjat" -#: cps/render_template.py:44 +#: cps/render_template.py:46 msgid "Show Hot Books" msgstr "Näytä kuumat kirjat" -#: cps/render_template.py:46 cps/render_template.py:51 +#: cps/render_template.py:48 cps/render_template.py:53 msgid "Downloaded Books" msgstr "" -#: cps/render_template.py:48 cps/render_template.py:53 +#: cps/render_template.py:50 cps/render_template.py:55 #: cps/templates/user_table.html:167 msgid "Show Downloaded Books" msgstr "" -#: cps/render_template.py:56 cps/templates/index.xml:32 cps/web.py:430 +#: cps/render_template.py:58 cps/templates/index.xml:32 cps/web.py:422 msgid "Top Rated Books" msgstr "Parhaiten arvioidut kirjat" -#: cps/render_template.py:58 cps/templates/user_table.html:161 +#: cps/render_template.py:60 cps/templates/user_table.html:161 msgid "Show Top Rated Books" msgstr "Näytä parhaiten arvioidut kirjat" -#: cps/render_template.py:59 cps/templates/index.xml:54 -#: cps/templates/index.xml:58 cps/web.py:676 +#: cps/render_template.py:61 cps/templates/index.xml:54 +#: cps/templates/index.xml:58 cps/web.py:729 msgid "Read Books" msgstr "Luetut kirjat" -#: cps/render_template.py:61 +#: cps/render_template.py:63 msgid "Show read and unread" msgstr "Näytä luetut ja lukemattomat" -#: cps/render_template.py:63 cps/templates/index.xml:61 -#: cps/templates/index.xml:65 cps/web.py:679 +#: cps/render_template.py:65 cps/templates/index.xml:61 +#: cps/templates/index.xml:65 cps/web.py:732 msgid "Unread Books" msgstr "Lukemattomat kirjat" -#: cps/render_template.py:65 +#: cps/render_template.py:67 msgid "Show unread" msgstr "Näyt lukemattomat" -#: cps/render_template.py:66 +#: cps/render_template.py:68 msgid "Discover" msgstr "Löydä" -#: cps/render_template.py:68 cps/templates/index.xml:50 +#: cps/render_template.py:70 cps/templates/index.xml:50 #: cps/templates/user_table.html:162 msgid "Show Random Books" msgstr "Näytä satunnausia kirjoja" -#: cps/render_template.py:69 cps/templates/book_table.html:67 -#: cps/templates/index.xml:83 cps/web.py:1041 +#: cps/render_template.py:71 cps/templates/book_table.html:67 +#: cps/templates/index.xml:83 cps/web.py:1135 msgid "Categories" msgstr "Kategoriat" -#: cps/render_template.py:71 cps/templates/user_table.html:158 +#: cps/render_template.py:73 cps/templates/user_table.html:158 msgid "Show category selection" msgstr "Näytä kategoriavalinta" -#: cps/render_template.py:72 cps/templates/book_edit.html:90 +#: cps/render_template.py:74 cps/templates/book_edit.html:90 #: cps/templates/book_table.html:68 cps/templates/index.xml:90 -#: cps/templates/search_form.html:69 cps/web.py:948 cps/web.py:959 +#: cps/templates/search_form.html:69 cps/web.py:1034 cps/web.py:1041 msgid "Series" msgstr "Sarjat" -#: cps/render_template.py:74 cps/templates/user_table.html:157 +#: cps/render_template.py:76 cps/templates/user_table.html:157 msgid "Show series selection" msgstr "Näytä sarjavalinta" -#: cps/render_template.py:75 cps/templates/book_table.html:66 +#: cps/render_template.py:77 cps/templates/book_table.html:66 #: cps/templates/index.xml:69 msgid "Authors" msgstr "Kirjailijat" -#: cps/render_template.py:77 cps/templates/user_table.html:160 +#: cps/render_template.py:79 cps/templates/user_table.html:160 msgid "Show author selection" msgstr "Näytä kirjailijavalinta" -#: cps/render_template.py:79 cps/templates/book_table.html:72 -#: cps/templates/index.xml:76 cps/web.py:925 +#: cps/render_template.py:81 cps/templates/book_table.html:72 +#: cps/templates/index.xml:76 cps/web.py:1006 msgid "Publishers" msgstr "Julkaisijat" -#: cps/render_template.py:81 cps/templates/user_table.html:163 +#: cps/render_template.py:83 cps/templates/user_table.html:163 msgid "Show publisher selection" msgstr "Näytä julkaisijavalinta" -#: cps/render_template.py:82 cps/templates/book_table.html:70 +#: cps/render_template.py:84 cps/templates/book_table.html:70 #: cps/templates/index.xml:97 cps/templates/search_form.html:107 -#: cps/web.py:1018 +#: cps/web.py:1108 msgid "Languages" msgstr "Kielet" -#: cps/render_template.py:85 cps/templates/user_table.html:155 +#: cps/render_template.py:87 cps/templates/user_table.html:155 msgid "Show language selection" msgstr "Näytä keilivalinta" -#: cps/render_template.py:86 cps/templates/index.xml:104 +#: cps/render_template.py:88 cps/templates/index.xml:104 msgid "Ratings" msgstr "Arvostelut" -#: cps/render_template.py:88 cps/templates/user_table.html:164 +#: cps/render_template.py:90 cps/templates/user_table.html:164 msgid "Show ratings selection" msgstr "Näytä arvosteluvalinta" -#: cps/render_template.py:89 cps/templates/index.xml:112 +#: cps/render_template.py:91 cps/templates/index.xml:112 msgid "File formats" msgstr "Tiedotomuodot" -#: cps/render_template.py:91 cps/templates/user_table.html:165 +#: cps/render_template.py:93 cps/templates/user_table.html:165 msgid "Show file formats selection" msgstr "Näytä tiedostomuotovalinta" -#: cps/render_template.py:93 cps/web.py:703 +#: cps/render_template.py:95 cps/web.py:755 msgid "Archived Books" msgstr "" -#: cps/render_template.py:95 cps/templates/user_table.html:166 +#: cps/render_template.py:97 cps/templates/user_table.html:166 msgid "Show archived books" msgstr "" -#: cps/render_template.py:97 cps/web.py:780 +#: cps/render_template.py:100 cps/web.py:837 msgid "Books List" msgstr "" -#: cps/render_template.py:99 cps/templates/user_table.html:168 +#: cps/render_template.py:102 cps/templates/user_table.html:168 msgid "Show Books List" msgstr "" @@ -1057,262 +1076,266 @@ msgstr "" msgid "Create a Shelf" msgstr "luo hylly" -#: cps/shelf.py:237 +#: cps/shelf.py:236 #, fuzzy msgid "Sorry you are not allowed to edit this shelf" msgstr "Valitettavsti sinulla ei ole oikeutta poistaa kirjaa hyllystä: %(sname)s" -#: cps/shelf.py:239 +#: cps/shelf.py:238 msgid "Edit a shelf" msgstr "Muokkaa hyllyä" -#: cps/shelf.py:249 +#: cps/shelf.py:248 msgid "Sorry you are not allowed to create a public shelf" msgstr "" -#: cps/shelf.py:266 +#: cps/shelf.py:265 #, python-format msgid "Shelf %(title)s created" msgstr "Hylly %(title)s luotu" -#: cps/shelf.py:269 +#: cps/shelf.py:268 #, python-format msgid "Shelf %(title)s changed" msgstr "Hylly %(title)s muutettu" -#: cps/shelf.py:283 +#: cps/shelf.py:282 msgid "There was an error" msgstr "Tapahtui virhe" -#: cps/shelf.py:305 +#: cps/shelf.py:304 #, python-format msgid "A public shelf with the name '%(title)s' already exists." msgstr "" -#: cps/shelf.py:316 +#: cps/shelf.py:315 #, python-format msgid "A private shelf with the name '%(title)s' already exists." msgstr "" #: cps/shelf.py:337 +msgid "Error deleting Shelf" +msgstr "" + +#: cps/shelf.py:339 #, fuzzy msgid "Shelf successfully deleted" msgstr "Metadata päivitetty onnistuneesti" -#: cps/shelf.py:386 +#: cps/shelf.py:389 #, python-format msgid "Change order of Shelf: '%(name)s'" msgstr "Muuta hyllyn: '%(name)s' järjestystä" -#: cps/shelf.py:456 +#: cps/shelf.py:461 #, python-format msgid "Shelf: '%(name)s'" msgstr "Hylly: '%(name)s'" -#: cps/shelf.py:460 +#: cps/shelf.py:465 msgid "Error opening shelf. Shelf does not exist or is not accessible" msgstr "Virhe hyllyn avauksessa. Hyllyä ei ole tai se ei ole saatavilla" -#: cps/updater.py:403 cps/updater.py:414 cps/updater.py:514 cps/updater.py:529 +#: cps/updater.py:426 cps/updater.py:437 cps/updater.py:538 cps/updater.py:553 msgid "Unexpected data while reading update information" msgstr "Odottamatonta tietoa luettaessa päivitystietoa" -#: cps/updater.py:410 cps/updater.py:521 +#: cps/updater.py:433 cps/updater.py:545 msgid "No update available. You already have the latest version installed" msgstr "Ei päivitystä saatavilla. Sinulla on jo uusin versio" -#: cps/updater.py:428 +#: cps/updater.py:451 msgid "A new update is available. Click on the button below to update to the latest version." msgstr "Uusi päivitys saatavilla. Paina alla olevaa nappia päivittääksesi uusimpaan versioon." -#: cps/updater.py:446 +#: cps/updater.py:469 msgid "Could not fetch update information" msgstr "Päivitystiedon hakeminen epäonnistui" -#: cps/updater.py:456 +#: cps/updater.py:479 msgid "Click on the button below to update to the latest stable version." msgstr "Paina alla olevaa nappia päivittääksesi uusimpaan vakaaseen versioon." -#: cps/updater.py:465 cps/updater.py:479 cps/updater.py:490 +#: cps/updater.py:488 cps/updater.py:502 cps/updater.py:513 #, python-format msgid "A new update is available. Click on the button below to update to version: %(version)s" msgstr "Uusi päivitys saatavilla. Paina alla olevaa nappia päivittääksesi versioon: %(version)s" -#: cps/updater.py:507 +#: cps/updater.py:531 msgid "No release information available" msgstr "Ei päivitystietoa saatavilla" -#: cps/templates/index.html:5 cps/web.py:440 +#: cps/templates/index.html:5 cps/web.py:434 msgid "Discover (Random Books)" msgstr "Löydä (satunnaiset kirjat)" -#: cps/web.py:471 +#: cps/web.py:470 msgid "Hot Books (Most Downloaded)" msgstr "Kuumat kirjat (ladatuimmat)" -#: cps/web.py:507 +#: cps/web.py:501 #, python-format msgid "Downloaded books by %(user)s" msgstr "" -#: cps/web.py:539 +#: cps/web.py:534 #, python-format msgid "Author: %(name)s" msgstr "Kirjailija: %(name)s" -#: cps/web.py:554 +#: cps/web.py:570 #, python-format msgid "Publisher: %(name)s" msgstr "Julkaisija: %(name)s" -#: cps/web.py:569 +#: cps/web.py:598 #, python-format msgid "Series: %(serie)s" msgstr "Sarja: %(serie)s" -#: cps/web.py:582 +#: cps/web.py:610 #, python-format msgid "Rating: %(rating)s stars" msgstr "Arvostelu: %(rating)s tähteä" -#: cps/web.py:597 +#: cps/web.py:626 #, python-format msgid "File format: %(format)s" msgstr "Tiedostomuoto: %(format)s" -#: cps/web.py:615 +#: cps/web.py:663 #, python-format msgid "Category: %(name)s" msgstr "Kategoria: %(name)s" -#: cps/web.py:631 +#: cps/web.py:690 #, python-format msgid "Language: %(name)s" msgstr "Kieli: %(name)s" -#: cps/templates/layout.html:56 cps/web.py:737 cps/web.py:1371 +#: cps/templates/layout.html:56 cps/web.py:789 cps/web.py:1444 msgid "Advanced Search" msgstr "Edistynyt haku" #: cps/templates/book_edit.html:235 cps/templates/feed.xml:33 #: cps/templates/index.xml:11 cps/templates/layout.html:45 #: cps/templates/layout.html:48 cps/templates/search_form.html:226 -#: cps/web.py:750 cps/web.py:1077 +#: cps/web.py:807 cps/web.py:1164 msgid "Search" msgstr "Hae" -#: cps/templates/admin.html:16 cps/web.py:903 +#: cps/templates/admin.html:16 cps/web.py:979 msgid "Downloads" msgstr "DLS" -#: cps/web.py:980 +#: cps/web.py:1068 msgid "Ratings list" msgstr "Arvostelulistaus" -#: cps/web.py:1001 +#: cps/web.py:1095 msgid "File formats list" msgstr "Tiedostomuotolistaus" -#: cps/templates/layout.html:73 cps/templates/tasks.html:7 cps/web.py:1055 +#: cps/templates/layout.html:73 cps/templates/tasks.html:7 cps/web.py:1149 msgid "Tasks" msgstr "Tehtävät" -#: cps/web.py:1215 +#: cps/web.py:1286 msgid "Published after " msgstr "Julkaistu alkaen " -#: cps/web.py:1222 +#: cps/web.py:1293 msgid "Published before " msgstr "Julkaisut ennen " -#: cps/web.py:1244 +#: cps/web.py:1315 #, python-format msgid "Rating <= %(rating)s" msgstr "Arvostelu <= %(rating)s" -#: cps/web.py:1246 +#: cps/web.py:1317 #, python-format msgid "Rating >= %(rating)s" msgstr "Arvostelu >= %(rating)s" -#: cps/web.py:1248 +#: cps/web.py:1319 #, python-format msgid "Read Status = %(status)s" msgstr "" -#: cps/web.py:1353 +#: cps/web.py:1425 msgid "Error on search for custom columns, please restart Calibre-Web" msgstr "" -#: cps/web.py:1449 +#: cps/web.py:1527 #, python-format msgid "Book successfully queued for sending to %(kindlemail)s" msgstr "Kirja lisätty onnistuneeksi lähetettäväksi osoitteeseen %(kindlemail)s" -#: cps/web.py:1453 +#: cps/web.py:1531 #, python-format msgid "Oops! There was an error sending this book: %(res)s" msgstr "Kirjan: %(res)s lähettämisessa tapahtui virhe" -#: cps/web.py:1455 +#: cps/web.py:1533 msgid "Please update your profile with a valid Send to Kindle E-mail Address." msgstr "Ole hyvä ja aseta Kindle sähköpostiosoite ensin..." -#: cps/web.py:1472 +#: cps/web.py:1550 msgid "E-Mail server is not configured, please contact your administrator!" msgstr "" -#: cps/templates/layout.html:85 cps/templates/register.html:17 cps/web.py:1473 -#: cps/web.py:1480 cps/web.py:1486 cps/web.py:1505 cps/web.py:1509 -#: cps/web.py:1515 +#: cps/templates/layout.html:85 cps/templates/register.html:17 cps/web.py:1551 +#: cps/web.py:1558 cps/web.py:1564 cps/web.py:1583 cps/web.py:1587 +#: cps/web.py:1593 msgid "Register" msgstr "Rekisteröi" -#: cps/web.py:1507 +#: cps/web.py:1585 msgid "Your e-mail is not allowed to register" msgstr "Sähköpostiosoitteellasi ei ole sallittua rekisteröityä" -#: cps/web.py:1510 +#: cps/web.py:1588 msgid "Confirmation e-mail was send to your e-mail account." msgstr "Vahvistusviesti on lähetetty sähköpostiosoitteeseesi." -#: cps/web.py:1524 +#: cps/web.py:1602 msgid "Cannot activate LDAP authentication" msgstr "LDAP autnetikoinnin aktivointi ei onnistu" -#: cps/web.py:1543 +#: cps/web.py:1621 #, python-format msgid "Fallback Login as: '%(nickname)s', LDAP Server not reachable, or user not known" msgstr "" -#: cps/web.py:1549 +#: cps/web.py:1627 #, python-format msgid "Could not login: %(message)s" msgstr "" -#: cps/web.py:1553 cps/web.py:1578 +#: cps/web.py:1631 cps/web.py:1656 msgid "Wrong Username or Password" msgstr "Väärä käyttäjätunnus tai salasana" -#: cps/web.py:1560 +#: cps/web.py:1638 msgid "New Password was send to your email address" msgstr "" -#: cps/web.py:1566 +#: cps/web.py:1644 msgid "Please enter valid username to reset password" msgstr "" -#: cps/web.py:1573 +#: cps/web.py:1651 #, python-format msgid "You are now logged in as: '%(nickname)s'" msgstr "olet kirjautunut tunnuksella: '%(nickname)s'" -#: cps/web.py:1639 cps/web.py:1688 +#: cps/web.py:1717 cps/web.py:1766 #, python-format msgid "%(name)s's profile" msgstr "%(name)sn profiili" -#: cps/web.py:1655 +#: cps/web.py:1733 msgid "Profile updated" msgstr "Profiili päivitetty" @@ -1320,36 +1343,36 @@ msgstr "Profiili päivitetty" msgid "Found no valid gmail.json file with OAuth information" msgstr "" -#: cps/tasks/convert.py:137 +#: cps/tasks/convert.py:154 #, python-format msgid "Calibre ebook-convert %(tool)s not found" msgstr "" -#: cps/tasks/convert.py:163 +#: cps/tasks/convert.py:187 #, python-format msgid "%(format)s format not found on disk" msgstr "" -#: cps/tasks/convert.py:167 +#: cps/tasks/convert.py:191 msgid "Ebook converter failed with unknown error" msgstr "" -#: cps/tasks/convert.py:177 +#: cps/tasks/convert.py:201 #, python-format msgid "Kepubify-converter failed: %(error)s" msgstr "" -#: cps/tasks/convert.py:199 +#: cps/tasks/convert.py:223 #, python-format msgid "Converted file not found or more than one file in folder %(folder)s" msgstr "" -#: cps/tasks/convert.py:222 +#: cps/tasks/convert.py:246 #, python-format msgid "Ebook-converter failed: %(error)s" msgstr "E-kirjan muunnos epäonnistui: %(error)s" -#: cps/tasks/convert.py:245 +#: cps/tasks/convert.py:269 #, python-format msgid "Calibre failed with error: %(error)s" msgstr "" @@ -1404,7 +1427,7 @@ msgid "Edit" msgstr "Muokkaa" #: cps/templates/admin.html:25 cps/templates/book_edit.html:16 -#: cps/templates/book_table.html:97 cps/templates/modal_dialogs.html:63 +#: cps/templates/book_table.html:100 cps/templates/modal_dialogs.html:63 #: cps/templates/modal_dialogs.html:116 cps/templates/user_edit.html:67 #: cps/templates/user_table.html:149 msgid "Delete" @@ -1414,180 +1437,180 @@ msgstr "Poista" msgid "Public Shelf" msgstr "" -#: cps/templates/admin.html:51 +#: cps/templates/admin.html:53 msgid "Add New User" msgstr "" -#: cps/templates/admin.html:53 +#: cps/templates/admin.html:55 msgid "Import LDAP Users" msgstr "" -#: cps/templates/admin.html:60 +#: cps/templates/admin.html:62 msgid "E-mail Server Settings" msgstr "SMTP sähköpostipalvelimen asetukset" -#: cps/templates/admin.html:65 cps/templates/email_edit.html:31 +#: cps/templates/admin.html:67 cps/templates/email_edit.html:31 msgid "SMTP Hostname" msgstr "SMTP palvein" -#: cps/templates/admin.html:69 cps/templates/email_edit.html:35 +#: cps/templates/admin.html:71 cps/templates/email_edit.html:35 msgid "SMTP Port" msgstr "SMTP portti" -#: cps/templates/admin.html:73 cps/templates/email_edit.html:39 +#: cps/templates/admin.html:75 cps/templates/email_edit.html:39 msgid "Encryption" msgstr "SSL" -#: cps/templates/admin.html:77 cps/templates/email_edit.html:47 +#: cps/templates/admin.html:79 cps/templates/email_edit.html:47 msgid "SMTP Login" msgstr "SMTP tunnus" -#: cps/templates/admin.html:81 cps/templates/admin.html:92 +#: cps/templates/admin.html:83 cps/templates/admin.html:94 #: cps/templates/email_edit.html:55 msgid "From E-mail" msgstr "Lähettäjän sähköposti" -#: cps/templates/admin.html:88 +#: cps/templates/admin.html:90 msgid "E-Mail Service" msgstr "" -#: cps/templates/admin.html:89 +#: cps/templates/admin.html:91 msgid "Gmail via Oauth2" msgstr "" -#: cps/templates/admin.html:104 +#: cps/templates/admin.html:106 msgid "Configuration" msgstr "Asetukset" -#: cps/templates/admin.html:107 +#: cps/templates/admin.html:109 msgid "Calibre Database Directory" msgstr "Calibre DB hakemisto" -#: cps/templates/admin.html:111 cps/templates/config_edit.html:68 +#: cps/templates/admin.html:113 cps/templates/config_edit.html:68 msgid "Log Level" msgstr "Lokitaso" -#: cps/templates/admin.html:115 +#: cps/templates/admin.html:117 msgid "Port" msgstr "Portti" -#: cps/templates/admin.html:120 +#: cps/templates/admin.html:122 msgid "External Port" msgstr "" -#: cps/templates/admin.html:127 cps/templates/config_view_edit.html:28 +#: cps/templates/admin.html:129 cps/templates/config_view_edit.html:28 msgid "Books per Page" msgstr "Kirjaa sivulla" -#: cps/templates/admin.html:131 +#: cps/templates/admin.html:133 msgid "Uploads" msgstr "Lähetetään" -#: cps/templates/admin.html:135 +#: cps/templates/admin.html:137 msgid "Anonymous Browsing" msgstr "Nimetön selaus" -#: cps/templates/admin.html:139 +#: cps/templates/admin.html:141 msgid "Public Registration" msgstr "Julkinen rekisteröinti" -#: cps/templates/admin.html:143 +#: cps/templates/admin.html:145 msgid "Magic Link Remote Login" msgstr "Etäkirjautuminen" -#: cps/templates/admin.html:147 +#: cps/templates/admin.html:149 msgid "Reverse Proxy Login" msgstr "" -#: cps/templates/admin.html:152 cps/templates/config_edit.html:173 +#: cps/templates/admin.html:154 cps/templates/config_edit.html:173 msgid "Reverse Proxy Header Name" msgstr "" -#: cps/templates/admin.html:157 +#: cps/templates/admin.html:159 #, fuzzy msgid "Edit Calibre Database Configuration" msgstr "Calibre DB hakemisto" -#: cps/templates/admin.html:158 +#: cps/templates/admin.html:160 msgid "Edit Basic Configuration" msgstr "" -#: cps/templates/admin.html:159 +#: cps/templates/admin.html:161 msgid "Edit UI Configuration" msgstr "" -#: cps/templates/admin.html:164 +#: cps/templates/admin.html:166 msgid "Administration" msgstr "Ylläpito" -#: cps/templates/admin.html:165 +#: cps/templates/admin.html:167 msgid "Download Debug Package" msgstr "" -#: cps/templates/admin.html:166 +#: cps/templates/admin.html:168 msgid "View Logs" msgstr "Katsele lokitiedostoja" -#: cps/templates/admin.html:169 +#: cps/templates/admin.html:171 msgid "Reconnect Calibre Database" msgstr "Uudelleenyhdistä Calibre DB" -#: cps/templates/admin.html:170 +#: cps/templates/admin.html:172 msgid "Restart" msgstr "Uudellenkäynnistä Calibre-Web" -#: cps/templates/admin.html:171 +#: cps/templates/admin.html:173 msgid "Shutdown" msgstr "Sammuta Calibre-Web" -#: cps/templates/admin.html:176 +#: cps/templates/admin.html:178 msgid "Update" msgstr "Päivitä" -#: cps/templates/admin.html:180 +#: cps/templates/admin.html:182 msgid "Version" msgstr "Versio" -#: cps/templates/admin.html:181 +#: cps/templates/admin.html:183 msgid "Details" msgstr "Yksityiskohdat" -#: cps/templates/admin.html:187 +#: cps/templates/admin.html:189 msgid "Current version" msgstr "Nykyinen versio" -#: cps/templates/admin.html:194 +#: cps/templates/admin.html:196 msgid "Check for Update" msgstr "Tarkista päivitykset" -#: cps/templates/admin.html:195 +#: cps/templates/admin.html:197 msgid "Perform Update" msgstr "Päivitä" -#: cps/templates/admin.html:208 +#: cps/templates/admin.html:210 msgid "Are you sure you want to restart?" msgstr "Haluatko varmasti uudelleenkäynnistää Calibre-Webin?" -#: cps/templates/admin.html:213 cps/templates/admin.html:227 -#: cps/templates/admin.html:247 cps/templates/config_db.html:70 +#: cps/templates/admin.html:215 cps/templates/admin.html:229 +#: cps/templates/admin.html:249 cps/templates/config_db.html:70 msgid "OK" msgstr "Ok" -#: cps/templates/admin.html:214 cps/templates/admin.html:228 -#: cps/templates/book_edit.html:213 cps/templates/book_table.html:124 +#: cps/templates/admin.html:216 cps/templates/admin.html:230 +#: cps/templates/book_edit.html:213 cps/templates/book_table.html:127 #: cps/templates/config_db.html:54 cps/templates/config_edit.html:359 -#: cps/templates/config_view_edit.html:173 cps/templates/modal_dialogs.html:64 +#: cps/templates/config_view_edit.html:175 cps/templates/modal_dialogs.html:64 #: cps/templates/modal_dialogs.html:99 cps/templates/modal_dialogs.html:117 #: cps/templates/modal_dialogs.html:135 cps/templates/shelf_edit.html:27 #: cps/templates/user_edit.html:144 msgid "Cancel" msgstr "" -#: cps/templates/admin.html:226 +#: cps/templates/admin.html:228 msgid "Are you sure you want to shutdown?" msgstr "Haluatko varmasti pysäyttää Calibre-Webin?" -#: cps/templates/admin.html:238 +#: cps/templates/admin.html:240 msgid "Updating, please do not reload this page" msgstr "Päivitetään, älä päivitä sivua" @@ -1599,44 +1622,43 @@ msgstr "" msgid "In Library" msgstr "Kirjastossa" -#: cps/templates/author.html:26 cps/templates/index.html:72 -#: cps/templates/search.html:29 cps/templates/shelf.html:19 +#: cps/templates/author.html:26 cps/templates/index.html:73 +#: cps/templates/search.html:30 cps/templates/shelf.html:19 msgid "Sort according to book date, newest first" msgstr "" -#: cps/templates/author.html:27 cps/templates/index.html:73 -#: cps/templates/search.html:30 cps/templates/shelf.html:20 +#: cps/templates/author.html:27 cps/templates/index.html:74 +#: cps/templates/search.html:31 cps/templates/shelf.html:20 msgid "Sort according to book date, oldest first" msgstr "" -#: cps/templates/author.html:28 cps/templates/index.html:74 -#: cps/templates/search.html:31 cps/templates/shelf.html:21 +#: cps/templates/author.html:28 cps/templates/index.html:75 +#: cps/templates/search.html:32 cps/templates/shelf.html:21 msgid "Sort title in alphabetical order" msgstr "" -#: cps/templates/author.html:29 cps/templates/index.html:75 -#: cps/templates/search.html:32 cps/templates/shelf.html:22 +#: cps/templates/author.html:29 cps/templates/index.html:76 +#: cps/templates/search.html:33 cps/templates/shelf.html:22 msgid "Sort title in reverse alphabetical order" msgstr "" -#: cps/templates/author.html:30 cps/templates/index.html:78 -#: cps/templates/search.html:35 cps/templates/shelf.html:25 +#: cps/templates/author.html:30 cps/templates/index.html:79 +#: cps/templates/search.html:36 cps/templates/shelf.html:25 msgid "Sort according to publishing date, newest first" msgstr "" -#: cps/templates/author.html:31 cps/templates/index.html:79 -#: cps/templates/search.html:36 cps/templates/shelf.html:26 +#: cps/templates/author.html:31 cps/templates/index.html:80 +#: cps/templates/search.html:37 cps/templates/shelf.html:26 msgid "Sort according to publishing date, oldest first" msgstr "" -#: cps/templates/author.html:57 cps/templates/author.html:117 -#: cps/templates/discover.html:30 cps/templates/index.html:29 -#: cps/templates/index.html:111 cps/templates/search.html:65 -#: cps/templates/shelf.html:54 +#: cps/templates/author.html:56 cps/templates/author.html:115 +#: cps/templates/index.html:29 cps/templates/index.html:112 +#: cps/templates/search.html:66 cps/templates/shelf.html:54 msgid "reduce" msgstr "vähennä" -#: cps/templates/author.html:101 +#: cps/templates/author.html:99 msgid "More by" msgstr "Enemmän" @@ -1761,7 +1783,7 @@ msgid "Fetch Metadata" msgstr "Hae metadata" #: cps/templates/book_edit.html:212 cps/templates/config_db.html:53 -#: cps/templates/config_edit.html:358 cps/templates/config_view_edit.html:172 +#: cps/templates/config_edit.html:358 cps/templates/config_view_edit.html:174 #: cps/templates/email_edit.html:65 cps/templates/shelf_edit.html:25 #: cps/templates/shelf_order.html:41 cps/templates/user_edit.html:142 msgid "Save" @@ -1890,27 +1912,35 @@ msgstr "Syötä domainnimi" msgid "Comments" msgstr "" -#: cps/templates/book_table.html:77 cps/templates/book_table.html:79 -#: cps/templates/book_table.html:81 cps/templates/book_table.html:83 -#: cps/templates/book_table.html:87 cps/templates/book_table.html:89 -#: cps/templates/book_table.html:91 cps/templates/book_table.html:93 +#: cps/templates/book_table.html:75 +msgid "Archiv Status" +msgstr "" + +#: cps/templates/book_table.html:77 cps/templates/search_form.html:42 +msgid "Read Status" +msgstr "" + +#: cps/templates/book_table.html:80 cps/templates/book_table.html:82 +#: cps/templates/book_table.html:84 cps/templates/book_table.html:86 +#: cps/templates/book_table.html:90 cps/templates/book_table.html:92 +#: cps/templates/book_table.html:96 #, fuzzy msgid "Enter " msgstr "Rekisteröi" -#: cps/templates/book_table.html:110 cps/templates/modal_dialogs.html:46 +#: cps/templates/book_table.html:113 cps/templates/modal_dialogs.html:46 msgid "Are you really sure?" msgstr "Oletko aivan varma?" -#: cps/templates/book_table.html:114 +#: cps/templates/book_table.html:117 msgid "Books with Title will be merged from:" msgstr "" -#: cps/templates/book_table.html:118 +#: cps/templates/book_table.html:121 msgid "Into Book with Title:" msgstr "" -#: cps/templates/book_table.html:123 +#: cps/templates/book_table.html:126 msgid "Merge" msgstr "" @@ -2086,11 +2116,6 @@ msgstr "LDAP Palveimen portti" msgid "LDAP Encryption" msgstr "" -#: cps/templates/config_edit.html:204 cps/templates/config_view_edit.html:62 -#: cps/templates/email_edit.html:41 -msgid "None" -msgstr "Ei mitään" - #: cps/templates/config_edit.html:205 msgid "TLS" msgstr "" @@ -2309,11 +2334,11 @@ msgstr "Oletusnäkymä uusille käyttäjille" msgid "Show Random Books in Detail View" msgstr "Näytä satunnaisia kirjoja näkymässä" -#: cps/templates/config_view_edit.html:165 cps/templates/user_edit.html:87 +#: cps/templates/config_view_edit.html:166 cps/templates/user_edit.html:87 msgid "Add Allowed/Denied Tags" msgstr "" -#: cps/templates/config_view_edit.html:166 +#: cps/templates/config_view_edit.html:167 msgid "Add Allowed/Denied custom column values" msgstr "" @@ -2362,13 +2387,13 @@ msgstr "" msgid "Description:" msgstr "Kuvaus:" -#: cps/templates/detail.html:256 cps/templates/search.html:14 +#: cps/templates/detail.html:256 cps/templates/search.html:15 msgid "Add to shelf" msgstr "Lisää hyllyyn" #: cps/templates/detail.html:267 cps/templates/detail.html:284 #: cps/templates/feed.xml:79 cps/templates/layout.html:137 -#: cps/templates/search.html:20 +#: cps/templates/search.html:21 msgid "(Public)" msgstr "" @@ -2446,10 +2471,14 @@ msgstr "" msgid "Next" msgstr "Seuraava" -#: cps/templates/generate_kobo_auth_url.html:5 +#: cps/templates/generate_kobo_auth_url.html:6 msgid "Open the .kobo/Kobo eReader.conf file in a text editor and add (or edit):" msgstr "" +#: cps/templates/generate_kobo_auth_url.html:11 +msgid "Kobo Token:" +msgstr "" + #: cps/templates/http_error.html:31 msgid "Calibre-Web Instance is unconfigured, please contact your administrator" msgstr "" @@ -2466,29 +2495,29 @@ msgstr "Palaa kotiin" msgid "Logout User" msgstr "" -#: cps/templates/index.html:69 +#: cps/templates/index.html:70 msgid "Sort ascending according to download count" msgstr "" -#: cps/templates/index.html:70 +#: cps/templates/index.html:71 msgid "Sort descending according to download count" msgstr "" -#: cps/templates/index.html:76 cps/templates/search.html:33 +#: cps/templates/index.html:77 cps/templates/search.html:34 #: cps/templates/shelf.html:23 msgid "Sort authors in alphabetical order" msgstr "" -#: cps/templates/index.html:77 cps/templates/search.html:34 +#: cps/templates/index.html:78 cps/templates/search.html:35 #: cps/templates/shelf.html:24 msgid "Sort authors in reverse alphabetical order" msgstr "" -#: cps/templates/index.html:81 +#: cps/templates/index.html:82 msgid "Sort ascending according to series index" msgstr "" -#: cps/templates/index.html:82 +#: cps/templates/index.html:83 msgid "Sort descending according to series index" msgstr "" @@ -2924,10 +2953,6 @@ msgstr "Julkaisupäivästä" msgid "Published Date To" msgstr "Julkaisupäivään" -#: cps/templates/search_form.html:42 -msgid "Read Status" -msgstr "" - #: cps/templates/search_form.html:59 msgid "Exclude Tags" msgstr "Poissulje merkintä" diff --git a/cps/translations/fr/LC_MESSAGES/messages.mo b/cps/translations/fr/LC_MESSAGES/messages.mo index d06c2568..898520fa 100644 Binary files a/cps/translations/fr/LC_MESSAGES/messages.mo and b/cps/translations/fr/LC_MESSAGES/messages.mo differ diff --git a/cps/translations/fr/LC_MESSAGES/messages.po b/cps/translations/fr/LC_MESSAGES/messages.po index 7380af1d..c5eb0fab 100644 --- a/cps/translations/fr/LC_MESSAGES/messages.po +++ b/cps/translations/fr/LC_MESSAGES/messages.po @@ -22,7 +22,7 @@ msgid "" msgstr "" "Project-Id-Version: Calibre-Web\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2022-01-15 09:19+0100\n" +"POT-Creation-Date: 2022-04-18 20:01+0200\n" "PO-Revision-Date: 2020-06-07 06:47+0200\n" "Last-Translator: \n" "Language: fr\n" @@ -31,589 +31,592 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.9.0\n" +"Generated-By: Babel 2.9.1\n" -#: cps/about.py:34 cps/about.py:49 cps/about.py:65 cps/converter.py:31 -msgid "not installed" -msgstr "non installé" - -#: cps/about.py:47 cps/about.py:63 -msgid "installed" -msgstr "installé" - -#: cps/about.py:145 +#: cps/about.py:86 msgid "Statistics" msgstr "Statistiques" -#: cps/admin.py:144 +#: cps/admin.py:141 msgid "Server restarted, please reload page" msgstr "Serveur redémarré, merci de rafraîchir la page" -#: cps/admin.py:146 +#: cps/admin.py:143 msgid "Performing shutdown of server, please close window" msgstr "Arrêt du serveur en cours, merci de fermer la fenêtre" -#: cps/admin.py:154 +#: cps/admin.py:151 msgid "Reconnect successful" msgstr "Reconnecté avec succès" -#: cps/admin.py:157 +#: cps/admin.py:154 msgid "Unknown command" msgstr "Commande inconnue" -#: cps/admin.py:167 cps/editbooks.py:707 cps/editbooks.py:721 -#: cps/editbooks.py:866 cps/editbooks.py:868 cps/editbooks.py:895 -#: cps/editbooks.py:911 cps/updater.py:584 cps/uploader.py:93 -#: cps/uploader.py:103 +#: cps/admin.py:176 cps/editbooks.py:713 cps/editbooks.py:892 +#: cps/editbooks.py:894 cps/editbooks.py:930 cps/editbooks.py:947 +#: cps/updater.py:608 cps/uploader.py:93 cps/uploader.py:103 msgid "Unknown" msgstr "Inconnu" -#: cps/admin.py:188 +#: cps/admin.py:197 msgid "Admin page" msgstr "Page admin" -#: cps/admin.py:207 +#: cps/admin.py:217 msgid "Basic Configuration" msgstr "Configuration principale" -#: cps/admin.py:244 +#: cps/admin.py:255 msgid "UI Configuration" msgstr "Configuration de l’interface utilisateur" -#: cps/admin.py:277 cps/templates/admin.html:50 +#: cps/admin.py:289 cps/templates/admin.html:51 #, fuzzy msgid "Edit Users" msgstr "Éditer les utilisateurs" -#: cps/admin.py:318 cps/opds.py:109 cps/opds.py:198 cps/opds.py:275 -#: cps/opds.py:327 cps/templates/grid.html:13 cps/templates/languages.html:9 +#: cps/admin.py:333 cps/opds.py:529 cps/templates/grid.html:13 #: cps/templates/list.html:13 msgid "All" msgstr "Tout" -#: cps/admin.py:343 cps/admin.py:1615 +#: cps/admin.py:360 cps/admin.py:1648 msgid "User not found" msgstr "L'utilisateur n'a pas été trouvé" -#: cps/admin.py:357 +#: cps/admin.py:374 msgid "{} users deleted successfully" msgstr "{} utilisateurs supprimés avec succès" -#: cps/admin.py:379 cps/templates/config_view_edit.html:133 +#: cps/admin.py:397 cps/templates/config_view_edit.html:133 #: cps/templates/user_edit.html:45 cps/templates/user_table.html:81 msgid "Show All" msgstr "Montrer tout" -#: cps/admin.py:400 cps/admin.py:406 +#: cps/admin.py:418 cps/admin.py:424 msgid "Malformed request" msgstr "Demande malformée" -#: cps/admin.py:418 cps/admin.py:1493 +#: cps/admin.py:436 cps/admin.py:1526 msgid "Guest Name can't be changed" msgstr "Le nom de l’invité ne peut pas être modifié" -#: cps/admin.py:430 +#: cps/admin.py:448 msgid "Guest can't have this role" msgstr "L’invité ne peut pas avoir ce rôle" -#: cps/admin.py:442 cps/admin.py:1451 +#: cps/admin.py:460 cps/admin.py:1484 msgid "No admin user remaining, can't remove admin role" msgstr "Aucun utilisateur admin restant, impossible de supprimer le rôle admin" -#: cps/admin.py:446 cps/admin.py:460 +#: cps/admin.py:464 cps/admin.py:478 msgid "Value has to be true or false" msgstr "La valeur doit être vraie ou fausse" -#: cps/admin.py:448 +#: cps/admin.py:466 msgid "Invalid role" msgstr "Rôle invalide" -#: cps/admin.py:452 +#: cps/admin.py:470 msgid "Guest can't have this view" msgstr "L’invité ne peut pas avoir cette vue" -#: cps/admin.py:462 +#: cps/admin.py:480 msgid "Invalid view" msgstr "Vue invalide" -#: cps/admin.py:465 +#: cps/admin.py:483 msgid "Guest's Locale is determined automatically and can't be set" msgstr "Les paramètres régionaux de l’invité sont déterminés automatiquement et ne peuvent pas être définis" -#: cps/admin.py:469 +#: cps/admin.py:487 msgid "No Valid Locale Given" msgstr "Aucun paramètre régional valide n’est donné" -#: cps/admin.py:480 +#: cps/admin.py:498 msgid "No Valid Book Language Given" msgstr "Aucune langue de livre valide donnée" -#: cps/admin.py:482 +#: cps/admin.py:500 cps/editbooks.py:1267 msgid "Parameter not found" msgstr "Paramètre non trouvé" -#: cps/admin.py:533 +#: cps/admin.py:553 msgid "Invalid Read Column" msgstr "Colonne de lecture non valide" -#: cps/admin.py:539 +#: cps/admin.py:559 msgid "Invalid Restricted Column" msgstr "Colonne restreinte non valide" -#: cps/admin.py:560 cps/admin.py:1323 +#: cps/admin.py:579 cps/admin.py:1355 msgid "Calibre-Web configuration updated" msgstr "Configuration de Calibre-Web mise à jour" -#: cps/admin.py:572 +#: cps/admin.py:591 msgid "Do you really want to delete the Kobo Token?" msgstr "Voulez-vous vraiment supprimer le jeton Kobo ?" -#: cps/admin.py:574 +#: cps/admin.py:593 msgid "Do you really want to delete this domain?" msgstr "Voulez-vous vraiment supprimer ce domaine ?" -#: cps/admin.py:576 +#: cps/admin.py:595 msgid "Do you really want to delete this user?" msgstr "Voulez-vous vraiment supprimer cet utilisateur ?" -#: cps/admin.py:578 +#: cps/admin.py:597 msgid "Are you sure you want to delete this shelf?" msgstr "Voulez-vous vraiment supprimer l’étagère ?" -#: cps/admin.py:580 +#: cps/admin.py:599 #, fuzzy msgid "Are you sure you want to change locales of selected user(s)?" msgstr "Voulez-vous vraiment supprimer l’étagère ?" -#: cps/admin.py:582 +#: cps/admin.py:601 msgid "Are you sure you want to change visible book languages for selected user(s)?" msgstr "Voulez-vous vraiment modifier les langues de livre visibles pour le ou les utilisateurs sélectionnés ?" -#: cps/admin.py:584 +#: cps/admin.py:603 msgid "Are you sure you want to change the selected role for the selected user(s)?" msgstr "Voulez-vous vraiment modifier le rôle sélectionné pour le ou les utilisateurs sélectionnés ?" -#: cps/admin.py:586 +#: cps/admin.py:605 #, fuzzy msgid "Are you sure you want to change the selected restrictions for the selected user(s)?" msgstr "Voulez-vous vraiment modifier les restrictions sélectionnées pour le ou les utilisateurs sélectionnés ?" -#: cps/admin.py:588 +#: cps/admin.py:607 msgid "Are you sure you want to change the selected visibility restrictions for the selected user(s)?" msgstr "Voulez-vous vraiment modifier les restrictions de visibilité sélectionnées pour le ou les utilisateurs sélectionnés ?" -#: cps/admin.py:590 +#: cps/admin.py:610 #, fuzzy msgid "Are you sure you want to change shelf sync behavior for the selected user(s)?" msgstr "Voulez-vous vraiment supprimer l’étagère?" -#: cps/admin.py:592 +#: cps/admin.py:612 #, fuzzy msgid "Are you sure you want to change Calibre library location?" msgstr "Voulez-vous vraiment arrêter Calibre-Web ?" -#: cps/admin.py:594 +#: cps/admin.py:614 msgid "Are you sure you want delete Calibre-Web's sync database to force a full sync with your Kobo Reader?" msgstr "Êtes-vous certain de vouloir supprimer la base de données de synchronisation de Calibre-Web pour forcer une synchronisation complète avec votre liseuse Kobo ?" -#: cps/admin.py:743 +#: cps/admin.py:764 msgid "Tag not found" msgstr "Étiquette introuvable" -#: cps/admin.py:755 +#: cps/admin.py:776 msgid "Invalid Action" msgstr "Action invalide" -#: cps/admin.py:871 cps/admin.py:877 cps/admin.py:887 cps/admin.py:897 +#: cps/admin.py:893 cps/admin.py:899 cps/admin.py:909 cps/admin.py:919 #: cps/templates/modal_dialogs.html:29 cps/templates/user_table.html:41 #: cps/templates/user_table.html:58 msgid "Deny" msgstr "Refuser" -#: cps/admin.py:873 cps/admin.py:879 cps/admin.py:889 cps/admin.py:899 +#: cps/admin.py:895 cps/admin.py:901 cps/admin.py:911 cps/admin.py:921 #: cps/templates/modal_dialogs.html:28 cps/templates/user_table.html:44 #: cps/templates/user_table.html:61 msgid "Allow" msgstr "Autoriser" -#: cps/admin.py:913 +#: cps/admin.py:936 msgid "{} sync entries deleted" msgstr "{} entrées de synchronisation supprimées" -#: cps/admin.py:1036 +#: cps/admin.py:1059 msgid "client_secrets.json Is Not Configured For Web Application" msgstr "client_secrets.json n'est pas configuré pour l'application Web" -#: cps/admin.py:1081 +#: cps/admin.py:1104 msgid "Logfile Location is not Valid, Please Enter Correct Path" msgstr "L'emplacement du fichier logfile est incorrect, veuillez saisir un chemin valide" -#: cps/admin.py:1087 +#: cps/admin.py:1110 msgid "Access Logfile Location is not Valid, Please Enter Correct Path" msgstr "L'emplacement du fichier Access Logfile est incorrect, veuillez saisir un chemin valide" -#: cps/admin.py:1117 +#: cps/admin.py:1140 msgid "Please Enter a LDAP Provider, Port, DN and User Object Identifier" msgstr "Veuillez saisir un fournisseur LDAP, Port, DN et l'identifiant objet de l'utilisateur" -#: cps/admin.py:1123 +#: cps/admin.py:1146 #, fuzzy msgid "Please Enter a LDAP Service Account and Password" msgstr "Veuillez entrer un nom d'utilisateur valide pour réinitialiser le mot de passe" -#: cps/admin.py:1126 +#: cps/admin.py:1149 msgid "Please Enter a LDAP Service Account" msgstr "Veuillez entrer un compte de service LDAP" -#: cps/admin.py:1131 +#: cps/admin.py:1154 #, python-format msgid "LDAP Group Object Filter Needs to Have One \"%s\" Format Identifier" msgstr "Le filtre objet du groupe LDAP a besoin d'un identifiant de format \"%s\"" -#: cps/admin.py:1133 +#: cps/admin.py:1156 msgid "LDAP Group Object Filter Has Unmatched Parenthesis" msgstr "Le filtre objet du groupe LDAP a une parenthèse non gérée" -#: cps/admin.py:1137 +#: cps/admin.py:1160 #, python-format msgid "LDAP User Object Filter needs to Have One \"%s\" Format Identifier" msgstr "Le filtre objet de l'utilisateur LDAP a besoin d'un identifiant de format \"%s\"" -#: cps/admin.py:1139 +#: cps/admin.py:1162 msgid "LDAP User Object Filter Has Unmatched Parenthesis" msgstr "Le filtre objet de l'utilisateur LDAP a une parenthèse non gérée" -#: cps/admin.py:1146 +#: cps/admin.py:1169 #, python-format msgid "LDAP Member User Filter needs to Have One \"%s\" Format Identifier" msgstr "Le filtre utilisateur des membres LDAP doit avoir un identificateur de format \"%s\\ »" -#: cps/admin.py:1148 +#: cps/admin.py:1171 msgid "LDAP Member User Filter Has Unmatched Parenthesis" msgstr "Le filtre utilisateur de membre LDAP a des parenthèses non appariées" -#: cps/admin.py:1155 +#: cps/admin.py:1178 msgid "LDAP CACertificate, Certificate or Key Location is not Valid, Please Enter Correct Path" msgstr "LDAP CACertificat, certificat ou emplacement de clé non valide, veuillez entrer le chemin correct" -#: cps/admin.py:1197 cps/admin.py:1308 cps/admin.py:1405 cps/admin.py:1521 -#: cps/admin.py:1590 cps/shelf.py:100 cps/shelf.py:160 cps/shelf.py:203 -#: cps/shelf.py:279 cps/shelf.py:341 cps/shelf.py:376 cps/shelf.py:451 -msgid "Settings DB is not Writeable" -msgstr "Les paramètres de la base de données ne sont pas accessibles en écriture" - -#: cps/admin.py:1208 -msgid "DB Location is not Valid, Please Enter Correct Path" -msgstr "L'emplacement de la base de données est incorrect, veuillez saisir un chemin valide" - -#: cps/admin.py:1223 -msgid "DB is not Writeable" -msgstr "La base de données n'est pas accessible en écriture" - -#: cps/admin.py:1235 -msgid "Keyfile Location is not Valid, Please Enter Correct Path" -msgstr "L'emplacement du fichier Keyfile est incorrect, veuillez saisir un chemin valide" - -#: cps/admin.py:1239 -msgid "Certfile Location is not Valid, Please Enter Correct Path" -msgstr "L'emplacement du fichier Certfile est incorrect, veuillez saisir un chemin valide" - -#: cps/admin.py:1346 -#, fuzzy -msgid "Database Settings updated" -msgstr "Les paramètres du serveur de courriels ont été mis à jour" - -#: cps/admin.py:1354 -#, fuzzy -msgid "Database Configuration" -msgstr "Configuration des options" - -#: cps/admin.py:1370 cps/web.py:1479 -msgid "Please fill out all fields!" -msgstr "Veuillez compléter tous les champs !" - -#: cps/admin.py:1378 -msgid "E-mail is not from valid domain" -msgstr "Cette adresse de courriel n’appartient pas à un domaine valide" - -#: cps/admin.py:1384 cps/admin.py:1543 -msgid "Add new user" -msgstr "Ajouter un nouvel utilisateur" - -#: cps/admin.py:1395 -#, python-format -msgid "User '%(user)s' created" -msgstr "Utilisateur '%(user)s' créé" - -#: cps/admin.py:1401 -#, fuzzy -msgid "Found an existing account for this e-mail address or name." -msgstr "Un compte existant a été trouvé pour cette adresse de courriel ou pour ce surnom." - -#: cps/admin.py:1430 -#, python-format -msgid "User '%(nick)s' deleted" -msgstr "Utilisateur '%(nick)s' supprimé" - -#: cps/admin.py:1432 cps/admin.py:1433 -msgid "Can't delete Guest User" -msgstr "Impossible de supprimer l’utilisateur Invité" - -#: cps/admin.py:1436 -msgid "No admin user remaining, can't delete user" -msgstr "Aucun utilisateur admin restant, impossible de supprimer l’utilisateur" - -#: cps/admin.py:1509 cps/admin.py:1634 -#, python-format -msgid "Edit User %(nick)s" -msgstr "Éditer l'utilisateur %(nick)s" - -#: cps/admin.py:1513 -#, python-format -msgid "User '%(nick)s' updated" -msgstr "Utilisateur '%(nick)s' mis à jour" - -#: cps/admin.py:1517 cps/admin.py:1649 cps/web.py:1504 cps/web.py:1564 -msgid "An unknown error occurred. Please try again later." -msgstr "Une erreur inconnue est survenue. Veuillez réessayer plus tard." - -#: cps/admin.py:1552 cps/templates/admin.html:98 -msgid "Edit E-mail Server Settings" -msgstr "Modifier les paramètres du serveur de courriels" - -#: cps/admin.py:1571 -msgid "Gmail Account Verification Successful" -msgstr "La vérification du compte Gmail réussie" - -#: cps/admin.py:1597 -#, python-format -msgid "Test e-mail queued for sending to %(email)s, please check Tasks for result" -msgstr "Teste les courriels en file d’attente pour l’envoi à %(email)s, veuillez vérifier le résultat des tâches" - -#: cps/admin.py:1600 -#, python-format -msgid "There was an error sending the Test e-mail: %(res)s" -msgstr "Il y a eu une erreur pendant l’envoi du courriel de test : %(res)s" - -#: cps/admin.py:1602 -msgid "Please configure your e-mail address first..." -msgstr "Veuillez d'abord configurer votre adresse de courriel..." - -#: cps/admin.py:1604 -msgid "E-mail server settings updated" -msgstr "Les paramètres du serveur de courriels ont été mis à jour" - -#: cps/admin.py:1646 -#, python-format -msgid "Password for user %(user)s reset" -msgstr "Le mot de passe de l’utilisateur %(user)s a été réinitialisé" - -#: cps/admin.py:1652 cps/web.py:1444 -msgid "Please configure the SMTP mail settings first..." -msgstr "Veuillez configurer les paramètres SMTP au préalable..." - -#: cps/admin.py:1663 -msgid "Logfile viewer" -msgstr "Visualiseur de fichier journal" - -#: cps/admin.py:1729 -msgid "Requesting update package" -msgstr "Demande de mise à jour" - -#: cps/admin.py:1730 -msgid "Downloading update package" -msgstr "Téléchargement de la mise à jour" - -#: cps/admin.py:1731 -msgid "Unzipping update package" -msgstr "Décompression de la mise à jour" - -#: cps/admin.py:1732 -msgid "Replacing files" -msgstr "Remplacement des fichiers" - -#: cps/admin.py:1733 -msgid "Database connections are closed" -msgstr "Les connexions à la base de données ont été fermées" - -#: cps/admin.py:1734 -msgid "Stopping server" -msgstr "Arrêt du serveur" - -#: cps/admin.py:1735 -msgid "Update finished, please press okay and reload page" -msgstr "Mise à jour terminée, merci d’appuyer sur okay et de rafraîchir la page" - -#: cps/admin.py:1736 cps/admin.py:1737 cps/admin.py:1738 cps/admin.py:1739 -#: cps/admin.py:1740 cps/admin.py:1741 -msgid "Update failed:" -msgstr "La mise à jour a échoué :" - -#: cps/admin.py:1736 cps/updater.py:385 cps/updater.py:595 cps/updater.py:597 -msgid "HTTP Error" -msgstr "Erreur HTTP" - -#: cps/admin.py:1737 cps/updater.py:387 cps/updater.py:599 -msgid "Connection error" -msgstr "Erreur de connexion" - -#: cps/admin.py:1738 cps/updater.py:389 cps/updater.py:601 -msgid "Timeout while establishing connection" -msgstr "Délai d'attente dépassé lors de l'établissement de connexion" - -#: cps/admin.py:1739 cps/updater.py:391 cps/updater.py:603 -msgid "General error" -msgstr "Erreur générale" - -#: cps/admin.py:1740 -#, fuzzy -msgid "Update file could not be saved in temp dir" -msgstr "Le fichier de mise à jour ne peut pas être sauvegardé dans le répertoire temporaire" - -#: cps/admin.py:1741 -msgid "Files could not be replaced during update" -msgstr "Les fichiers n’ont pas pu être remplacés pendant la mise à jour" - -#: cps/admin.py:1765 -#, fuzzy -msgid "Failed to extract at least One LDAP User" -msgstr "Impossible de créer au moins un utilisateur LDAP" - -#: cps/admin.py:1810 -msgid "Failed to Create at Least One LDAP User" -msgstr "Impossible de créer au moins un utilisateur LDAP" - -#: cps/admin.py:1823 -#, python-format -msgid "Error: %(ldaperror)s" -msgstr "Erreur : %(ldaperror)s" - -#: cps/admin.py:1827 -msgid "Error: No user returned in response of LDAP server" -msgstr "Erreur : Aucun utilisateur renvoyé dans la réponse LDAP du serveur" - -#: cps/admin.py:1860 -msgid "At Least One LDAP User Not Found in Database" -msgstr "Au moins un utilisateur LDAP n'a pas été trouvé dans la base de données" - -#: cps/admin.py:1862 -msgid "{} User Successfully Imported" -msgstr "{} utilisateur importé avec succès" - -#: cps/converter.py:30 -msgid "not configured" -msgstr "non configuré" - -#: cps/converter.py:32 -msgid "Execution permissions missing" -msgstr "Les permissions d'exécutions manquantes" - -#: cps/db.py:651 cps/web.py:667 cps/web.py:1155 -#, python-format -msgid "Custom Column No.%(column)d is not existing in calibre database" -msgstr "La colonne personnalisée No.%(column)d n'existe pas dans la base de données calibre" - -#: cps/editbooks.py:300 cps/editbooks.py:302 -msgid "Book Format Successfully Deleted" -msgstr "Le format du livre a été supprimé avec succès" - -#: cps/editbooks.py:309 cps/editbooks.py:311 -msgid "Book Successfully Deleted" -msgstr "Le livre a été supprimé avec succès" - -#: cps/editbooks.py:361 -msgid "You are missing permissions to delete books" -msgstr "Vous n’avez par les permissions pour supprimer les livres" - -#: cps/editbooks.py:376 cps/editbooks.py:763 cps/web.py:523 cps/web.py:1703 -#: cps/web.py:1744 cps/web.py:1811 -msgid "Oops! Selected book title is unavailable. File does not exist or is not accessible" -msgstr "Erreur d'ouverture du livre numérique. Le fichier n'existe pas ou n'est pas accessible" - -#: cps/editbooks.py:410 -msgid "edit metadata" -msgstr "modifier les métadonnées" - -#: cps/editbooks.py:458 -#, python-format -msgid "%(seriesindex)s is not a valid number, skipping" -msgstr "%(seriesindex)s n’est pas un nombre valide, ignoré" - -#: cps/editbooks.py:494 cps/editbooks.py:958 -#, fuzzy, python-format -msgid "'%(langname)s' is not a valid language" -msgstr "%(langname)s n'est pas une langue valide" - -#: cps/editbooks.py:634 cps/editbooks.py:985 -#, python-format -msgid "File extension '%(ext)s' is not allowed to be uploaded to this server" -msgstr "L’extension de fichier '%(ext)s' n’est pas autorisée pour être déposée sur ce serveur" - -#: cps/editbooks.py:638 cps/editbooks.py:989 -msgid "File to be uploaded must have an extension" -msgstr "Pour être déposé le fichier doit avoir une extension" - -#: cps/editbooks.py:650 -#, python-format -msgid "Failed to create path %(path)s (Permission denied)." -msgstr "Impossible de créer le chemin %(path)s (Permission refusée)." - -#: cps/editbooks.py:655 -#, python-format -msgid "Failed to store file %(file)s." -msgstr "Échec de la sauvegarde du fichier %(file)s." - -#: cps/editbooks.py:673 cps/editbooks.py:1076 cps/web.py:1664 +#: cps/admin.py:1223 cps/admin.py:1339 cps/admin.py:1437 cps/admin.py:1554 +#: cps/admin.py:1623 cps/editbooks.py:678 cps/editbooks.py:882 +#: cps/editbooks.py:1130 cps/shelf.py:100 cps/shelf.py:160 cps/shelf.py:203 +#: cps/shelf.py:278 cps/shelf.py:343 cps/shelf.py:380 cps/shelf.py:456 +#: cps/web.py:1742 #, python-format msgid "Database error: %(error)s." msgstr "Erreur de la base de données: %(error)s." -#: cps/editbooks.py:678 +#: cps/admin.py:1235 +msgid "DB Location is not Valid, Please Enter Correct Path" +msgstr "L'emplacement de la base de données est incorrect, veuillez saisir un chemin valide" + +#: cps/admin.py:1253 +msgid "DB is not Writeable" +msgstr "La base de données n'est pas accessible en écriture" + +#: cps/admin.py:1266 +msgid "Keyfile Location is not Valid, Please Enter Correct Path" +msgstr "L'emplacement du fichier Keyfile est incorrect, veuillez saisir un chemin valide" + +#: cps/admin.py:1270 +msgid "Certfile Location is not Valid, Please Enter Correct Path" +msgstr "L'emplacement du fichier Certfile est incorrect, veuillez saisir un chemin valide" + +#: cps/admin.py:1378 +#, fuzzy +msgid "Database Settings updated" +msgstr "Les paramètres du serveur de courriels ont été mis à jour" + +#: cps/admin.py:1386 +#, fuzzy +msgid "Database Configuration" +msgstr "Configuration des options" + +#: cps/admin.py:1402 cps/web.py:1557 +msgid "Please fill out all fields!" +msgstr "Veuillez compléter tous les champs !" + +#: cps/admin.py:1410 +msgid "E-mail is not from valid domain" +msgstr "Cette adresse de courriel n’appartient pas à un domaine valide" + +#: cps/admin.py:1416 cps/admin.py:1576 +msgid "Add new user" +msgstr "Ajouter un nouvel utilisateur" + +#: cps/admin.py:1427 +#, python-format +msgid "User '%(user)s' created" +msgstr "Utilisateur '%(user)s' créé" + +#: cps/admin.py:1433 +#, fuzzy +msgid "Found an existing account for this e-mail address or name." +msgstr "Un compte existant a été trouvé pour cette adresse de courriel ou pour ce surnom." + +#: cps/admin.py:1463 +#, python-format +msgid "User '%(nick)s' deleted" +msgstr "Utilisateur '%(nick)s' supprimé" + +#: cps/admin.py:1465 cps/admin.py:1466 +msgid "Can't delete Guest User" +msgstr "Impossible de supprimer l’utilisateur Invité" + +#: cps/admin.py:1469 +msgid "No admin user remaining, can't delete user" +msgstr "Aucun utilisateur admin restant, impossible de supprimer l’utilisateur" + +#: cps/admin.py:1542 cps/admin.py:1667 +#, python-format +msgid "Edit User %(nick)s" +msgstr "Éditer l'utilisateur %(nick)s" + +#: cps/admin.py:1546 +#, python-format +msgid "User '%(nick)s' updated" +msgstr "Utilisateur '%(nick)s' mis à jour" + +#: cps/admin.py:1550 cps/admin.py:1682 cps/web.py:1582 cps/web.py:1642 +msgid "An unknown error occurred. Please try again later." +msgstr "Une erreur inconnue est survenue. Veuillez réessayer plus tard." + +#: cps/admin.py:1585 cps/templates/admin.html:100 +msgid "Edit E-mail Server Settings" +msgstr "Modifier les paramètres du serveur de courriels" + +#: cps/admin.py:1604 +msgid "Gmail Account Verification Successful" +msgstr "La vérification du compte Gmail réussie" + +#: cps/admin.py:1630 +#, python-format +msgid "Test e-mail queued for sending to %(email)s, please check Tasks for result" +msgstr "Teste les courriels en file d’attente pour l’envoi à %(email)s, veuillez vérifier le résultat des tâches" + +#: cps/admin.py:1633 +#, python-format +msgid "There was an error sending the Test e-mail: %(res)s" +msgstr "Il y a eu une erreur pendant l’envoi du courriel de test : %(res)s" + +#: cps/admin.py:1635 +msgid "Please configure your e-mail address first..." +msgstr "Veuillez d'abord configurer votre adresse de courriel..." + +#: cps/admin.py:1637 +msgid "E-mail server settings updated" +msgstr "Les paramètres du serveur de courriels ont été mis à jour" + +#: cps/admin.py:1679 +#, python-format +msgid "Password for user %(user)s reset" +msgstr "Le mot de passe de l’utilisateur %(user)s a été réinitialisé" + +#: cps/admin.py:1685 cps/web.py:1522 +msgid "Please configure the SMTP mail settings first..." +msgstr "Veuillez configurer les paramètres SMTP au préalable..." + +#: cps/admin.py:1696 +msgid "Logfile viewer" +msgstr "Visualiseur de fichier journal" + +#: cps/admin.py:1762 +msgid "Requesting update package" +msgstr "Demande de mise à jour" + +#: cps/admin.py:1763 +msgid "Downloading update package" +msgstr "Téléchargement de la mise à jour" + +#: cps/admin.py:1764 +msgid "Unzipping update package" +msgstr "Décompression de la mise à jour" + +#: cps/admin.py:1765 +msgid "Replacing files" +msgstr "Remplacement des fichiers" + +#: cps/admin.py:1766 +msgid "Database connections are closed" +msgstr "Les connexions à la base de données ont été fermées" + +#: cps/admin.py:1767 +msgid "Stopping server" +msgstr "Arrêt du serveur" + +#: cps/admin.py:1768 +msgid "Update finished, please press okay and reload page" +msgstr "Mise à jour terminée, merci d’appuyer sur okay et de rafraîchir la page" + +#: cps/admin.py:1769 cps/admin.py:1770 cps/admin.py:1771 cps/admin.py:1772 +#: cps/admin.py:1773 cps/admin.py:1774 +msgid "Update failed:" +msgstr "La mise à jour a échoué :" + +#: cps/admin.py:1769 cps/updater.py:384 cps/updater.py:619 cps/updater.py:621 +msgid "HTTP Error" +msgstr "Erreur HTTP" + +#: cps/admin.py:1770 cps/updater.py:386 cps/updater.py:623 +msgid "Connection error" +msgstr "Erreur de connexion" + +#: cps/admin.py:1771 cps/updater.py:388 cps/updater.py:625 +msgid "Timeout while establishing connection" +msgstr "Délai d'attente dépassé lors de l'établissement de connexion" + +#: cps/admin.py:1772 cps/updater.py:390 cps/updater.py:627 +msgid "General error" +msgstr "Erreur générale" + +#: cps/admin.py:1773 +#, fuzzy +msgid "Update file could not be saved in temp dir" +msgstr "Le fichier de mise à jour ne peut pas être sauvegardé dans le répertoire temporaire" + +#: cps/admin.py:1774 +msgid "Files could not be replaced during update" +msgstr "Les fichiers n’ont pas pu être remplacés pendant la mise à jour" + +#: cps/admin.py:1798 +#, fuzzy +msgid "Failed to extract at least One LDAP User" +msgstr "Impossible de créer au moins un utilisateur LDAP" + +#: cps/admin.py:1843 +msgid "Failed to Create at Least One LDAP User" +msgstr "Impossible de créer au moins un utilisateur LDAP" + +#: cps/admin.py:1856 +#, python-format +msgid "Error: %(ldaperror)s" +msgstr "Erreur : %(ldaperror)s" + +#: cps/admin.py:1860 +msgid "Error: No user returned in response of LDAP server" +msgstr "Erreur : Aucun utilisateur renvoyé dans la réponse LDAP du serveur" + +#: cps/admin.py:1893 +msgid "At Least One LDAP User Not Found in Database" +msgstr "Au moins un utilisateur LDAP n'a pas été trouvé dans la base de données" + +#: cps/admin.py:1895 +msgid "{} User Successfully Imported" +msgstr "{} utilisateur importé avec succès" + +#: cps/converter.py:30 +msgid "not installed" +msgstr "non installé" + +#: cps/converter.py:31 +msgid "Execution permissions missing" +msgstr "Les permissions d'exécutions manquantes" + +#: cps/db.py:674 cps/web.py:710 cps/web.py:1222 +#, python-format +msgid "Custom Column No.%(column)d is not existing in calibre database" +msgstr "La colonne personnalisée No.%(column)d n'existe pas dans la base de données calibre" + +#: cps/db.py:917 cps/templates/config_edit.html:204 +#: cps/templates/config_view_edit.html:62 cps/templates/email_edit.html:41 +#: cps/web.py:551 cps/web.py:585 cps/web.py:646 cps/web.py:671 cps/web.py:1003 +#: cps/web.py:1032 cps/web.py:1066 cps/web.py:1093 cps/web.py:1132 +msgid "None" +msgstr "Aucun" + +#: cps/editbooks.py:295 cps/editbooks.py:297 +msgid "Book Format Successfully Deleted" +msgstr "Le format du livre a été supprimé avec succès" + +#: cps/editbooks.py:304 cps/editbooks.py:306 +msgid "Book Successfully Deleted" +msgstr "Le livre a été supprimé avec succès" + +#: cps/editbooks.py:358 +msgid "You are missing permissions to delete books" +msgstr "Vous n’avez par les permissions pour supprimer les livres" + +#: cps/editbooks.py:373 cps/editbooks.py:765 cps/web.py:518 cps/web.py:1783 +#: cps/web.py:1825 cps/web.py:1870 +msgid "Oops! Selected book title is unavailable. File does not exist or is not accessible" +msgstr "Erreur d'ouverture du livre numérique. Le fichier n'existe pas ou n'est pas accessible" + +#: cps/editbooks.py:408 +msgid "edit metadata" +msgstr "modifier les métadonnées" + +#: cps/editbooks.py:457 +#, python-format +msgid "%(seriesindex)s is not a valid number, skipping" +msgstr "%(seriesindex)s n’est pas un nombre valide, ignoré" + +#: cps/editbooks.py:493 cps/editbooks.py:1001 +#, fuzzy, python-format +msgid "'%(langname)s' is not a valid language" +msgstr "%(langname)s n'est pas une langue valide" + +#: cps/editbooks.py:634 +msgid "User has no rights to upload additional file formats" +msgstr "" + +#: cps/editbooks.py:639 cps/editbooks.py:1029 +#, python-format +msgid "File extension '%(ext)s' is not allowed to be uploaded to this server" +msgstr "L’extension de fichier '%(ext)s' n’est pas autorisée pour être déposée sur ce serveur" + +#: cps/editbooks.py:643 cps/editbooks.py:1033 +msgid "File to be uploaded must have an extension" +msgstr "Pour être déposé le fichier doit avoir une extension" + +#: cps/editbooks.py:655 +#, python-format +msgid "Failed to create path %(path)s (Permission denied)." +msgstr "Impossible de créer le chemin %(path)s (Permission refusée)." + +#: cps/editbooks.py:660 +#, python-format +msgid "Failed to store file %(file)s." +msgstr "Échec de la sauvegarde du fichier %(file)s." + +#: cps/editbooks.py:683 #, python-format msgid "File format %(ext)s added to %(book)s" msgstr "Le format de fichier %(ext)s a été ajouté à %(book)s" -#: cps/editbooks.py:814 +#: cps/editbooks.py:697 cps/editbooks.py:809 +msgid "User has no rights to upload cover" +msgstr "" + +#: cps/editbooks.py:828 msgid "Identifiers are not Case Sensitive, Overwriting Old Identifier" msgstr "Les identificateurs ne sont pas sensibles à la casse, écrasant l’ancien identificateur" -#: cps/editbooks.py:848 +#: cps/editbooks.py:869 msgid "Metadata successfully updated" msgstr "Les métadonnées ont bien été mises à jour" -#: cps/editbooks.py:861 -msgid "Error editing book, please check logfile for details" -msgstr "Erreur d’édition du livre, veuillez consulter le journal (log) pour plus de détails" +#: cps/editbooks.py:887 +msgid "Error editing book: {}" +msgstr "" -#: cps/editbooks.py:899 +#: cps/editbooks.py:951 msgid "Uploaded book probably exists in the library, consider to change before upload new: " msgstr "Le fichier téléchargé existe probablement dans la librairie, veuillez le modifier avant de le télécharger de nouveau: " -#: cps/editbooks.py:997 +#: cps/editbooks.py:1041 #, python-format msgid "File %(filename)s could not saved to temp dir" msgstr "Le fichier %(filename)s ne peut pas être sauvegardé dans le répertoire temporaire" -#: cps/editbooks.py:1016 +#: cps/editbooks.py:1061 #, python-format msgid "Failed to Move Cover File %(file)s: %(error)s" msgstr "Impossible de déplacer le fichier de couverture %(file)s: %(error)s" -#: cps/editbooks.py:1063 +#: cps/editbooks.py:1117 #, python-format msgid "File %(file)s uploaded" msgstr "Le fichier %(file)s a été téléchargé" -#: cps/editbooks.py:1088 +#: cps/editbooks.py:1143 msgid "Source or destination format for conversion missing" msgstr "Le format de conversion de la source ou de la destination est manquant" -#: cps/editbooks.py:1096 +#: cps/editbooks.py:1151 #, python-format msgid "Book successfully queued for converting to %(book_format)s" msgstr "Le livre a été mis avec succès en file de traitement pour conversion vers %(book_format)s" -#: cps/editbooks.py:1100 +#: cps/editbooks.py:1155 #, python-format msgid "There was an error converting this book: %(res)s" msgstr "Une erreur est survenue au cours de la conversion du livre : %(res)s" @@ -626,175 +629,192 @@ msgstr "La configuration de Google Drive n’est pas terminée, essayez de désa msgid "Callback domain is not verified, please follow steps to verify domain in google developer console" msgstr "Le domaine de retour d’appel (Callback domain) est non vérifié, veuillez suivre les étapes nécessaires pour vérifier le domaine dans la console de développement de Google" -#: cps/helper.py:77 +#: cps/helper.py:81 #, python-format msgid "%(format)s format not found for book id: %(book)d" msgstr "le format %(format)s est introuvable pour le livre : %(book)d" -#: cps/helper.py:83 cps/tasks/convert.py:73 +#: cps/helper.py:87 cps/tasks/convert.py:75 #, python-format msgid "%(format)s not found on Google Drive: %(fn)s" msgstr "le %(format)s est introuvable sur Google Drive : %(fn)s" -#: cps/helper.py:88 +#: cps/helper.py:92 #, python-format msgid "%(format)s not found: %(fn)s" msgstr "%(format)s introuvable : %(fn)s" -#: cps/helper.py:93 cps/helper.py:217 cps/templates/detail.html:41 +#: cps/helper.py:97 cps/helper.py:221 cps/templates/detail.html:41 #: cps/templates/detail.html:45 msgid "Send to Kindle" msgstr "Envoyer vers Kindle" -#: cps/helper.py:94 cps/helper.py:111 cps/helper.py:219 +#: cps/helper.py:98 cps/helper.py:115 cps/helper.py:223 msgid "This e-mail has been sent via Calibre-Web." msgstr "Ce courriel a été envoyé depuis Calibre-Web." -#: cps/helper.py:109 +#: cps/helper.py:113 msgid "Calibre-Web test e-mail" msgstr "Courriel de test de Calibre-Web" -#: cps/helper.py:110 +#: cps/helper.py:114 msgid "Test e-mail" msgstr "Courriel de test" -#: cps/helper.py:127 +#: cps/helper.py:131 msgid "Get Started with Calibre-Web" msgstr "Bien démarrer avec Calibre-Web" -#: cps/helper.py:132 +#: cps/helper.py:136 #, python-format msgid "Registration e-mail for user: %(name)s" msgstr "Courriel d’inscription pour l’utilisateur : %(name)s" -#: cps/helper.py:143 cps/helper.py:149 +#: cps/helper.py:147 cps/helper.py:153 #, python-format msgid "Convert %(orig)s to %(format)s and send to Kindle" msgstr "Convertir de %(orig)s vers %(format)s et envoyer au Kindle" -#: cps/helper.py:168 cps/helper.py:172 cps/helper.py:176 +#: cps/helper.py:172 cps/helper.py:176 cps/helper.py:180 #, python-format msgid "Send %(format)s to Kindle" msgstr "Envoyer %(format)s vers le Kindle" -#: cps/helper.py:216 cps/tasks/convert.py:90 +#: cps/helper.py:220 cps/tasks/convert.py:92 #, fuzzy, python-format msgid "%(book)s send to Kindle" msgstr "Envoyer vers Kindle" -#: cps/helper.py:221 +#: cps/helper.py:225 msgid "The requested file could not be read. Maybe wrong permissions?" msgstr "Le fichier demandé n’a pu être lu. Problème de permission d’accès ?" -#: cps/helper.py:313 +#: cps/helper.py:353 +msgid "Read status could not set: {}" +msgstr "" + +#: cps/helper.py:376 #, python-format msgid "Deleting bookfolder for book %(id)s failed, path has subfolders: %(path)s" msgstr "Échec de la suppression du dossier de livre pour le livre %(id)s, le chemin d’accès comporte des sous-dossiers : %(path)s" -#: cps/helper.py:319 +#: cps/helper.py:382 #, python-format msgid "Deleting book %(id)s failed: %(message)s" msgstr "La suppression du livre %(id)s a échoué: %(message)s" -#: cps/helper.py:330 +#: cps/helper.py:393 #, fuzzy, python-format msgid "Deleting book %(id)s from database only, book path in database not valid: %(path)s" msgstr "Suppression du livre %(id)s, le chemin du livre est invalide : %(path)s" -#: cps/helper.py:385 -#, python-format -msgid "Rename title from: '%(src)s' to '%(dest)s' failed with error: %(error)s" +#: cps/helper.py:458 +#, fuzzy, python-format +msgid "Rename author from: '%(src)s' to '%(dest)s' failed with error: %(error)s" msgstr "Renommer le titre de : '%(src)s' à '%(dest)s' a échoué avec l’erreur : %(error)s" -#: cps/helper.py:400 -#, python-format -msgid "Rename file in path '%(src)s' to '%(dest)s' failed with error: %(error)s" -msgstr "La modification du nom de fichier du chemin : '%(src)s' vers '%(dest)s' a échoué avec l’erreur : %(error)s" - -#: cps/helper.py:425 cps/helper.py:435 cps/helper.py:443 +#: cps/helper.py:529 cps/helper.py:538 #, python-format msgid "File %(file)s not found on Google Drive" msgstr "Le fichier %(file)s n'a pas été trouvé dans Google Drive" -#: cps/helper.py:464 +#: cps/helper.py:572 +#, python-format +msgid "Rename title from: '%(src)s' to '%(dest)s' failed with error: %(error)s" +msgstr "Renommer le titre de : '%(src)s' à '%(dest)s' a échoué avec l’erreur : %(error)s" + +#: cps/helper.py:592 +msgid "Error in rename file in path: {}" +msgstr "" + +#: cps/helper.py:610 #, python-format msgid "Book path %(path)s not found on Google Drive" msgstr "Le chemin du livre %(path)s n'a pas été trouvé dans Google Drive" -#: cps/helper.py:504 cps/web.py:1659 +#: cps/helper.py:651 cps/web.py:1737 #, fuzzy msgid "Found an existing account for this e-mail address" msgstr "Un compte existant a été trouvé pour cette adresse de courriel." -#: cps/helper.py:512 +#: cps/helper.py:659 msgid "This username is already taken" msgstr "Cet utilisateur est déjà pris" -#: cps/helper.py:522 +#: cps/helper.py:669 msgid "Invalid e-mail address format" msgstr "Format de l’adresse courriel invalide" -#: cps/helper.py:595 +#: cps/helper.py:754 +msgid "Python modul 'advocate' is not installed but is needed for cover downloads" +msgstr "" + +#: cps/helper.py:767 msgid "Error Downloading Cover" msgstr "Erreur lors du téléchargement de la couverture" -#: cps/helper.py:598 +#: cps/helper.py:770 msgid "Cover Format Error" msgstr "Erreur de format de couverture" -#: cps/helper.py:608 +#: cps/helper.py:773 +msgid "You are not allowed to access localhost or the local network for cover uploads" +msgstr "" + +#: cps/helper.py:783 msgid "Failed to create path for cover" msgstr "Impossible de créer le chemin pour la couverture" -#: cps/helper.py:624 +#: cps/helper.py:799 msgid "Cover-file is not a valid image file, or could not be stored" msgstr "Le fichier couverture n'est pas un fichier image valide, ou ne peut pas être stocké" -#: cps/helper.py:635 +#: cps/helper.py:810 msgid "Only jpg/jpeg/png/webp/bmp files are supported as coverfile" msgstr "Seuls les fichiers jpg/jpeg/png/webp/bmp sont supportés comme fichier de couverture" -#: cps/helper.py:648 +#: cps/helper.py:822 msgid "Invalid cover file content" msgstr "Contenu du fichier de couverture invalide" -#: cps/helper.py:652 +#: cps/helper.py:826 msgid "Only jpg/jpeg files are supported as coverfile" msgstr "Seuls les fichiers jpg/jpeg sont supportés comme fichier de couverture" -#: cps/helper.py:704 +#: cps/helper.py:878 msgid "Unrar binary file not found" msgstr "Fichier binaire Unrar non trouvé" -#: cps/helper.py:715 +#: cps/helper.py:889 msgid "Error excecuting UnRar" msgstr "Une erreur est survenue lors de l'exécution d'UnRar" -#: cps/helper.py:763 +#: cps/helper.py:937 msgid "Waiting" msgstr "En attente" -#: cps/helper.py:765 +#: cps/helper.py:939 msgid "Failed" msgstr "Echoué" -#: cps/helper.py:767 +#: cps/helper.py:941 msgid "Started" msgstr "Débuté" -#: cps/helper.py:769 +#: cps/helper.py:943 msgid "Finished" msgstr "Terminé" -#: cps/helper.py:771 +#: cps/helper.py:945 msgid "Unknown Status" msgstr "Statut inconnu" -#: cps/kobo_auth.py:127 -msgid "PLease access calibre-web from non localhost to get valid api_endpoint for kobo device" +#: cps/kobo_auth.py:128 +#, fuzzy +msgid "Please access Calibre-Web from non localhost to get valid api_endpoint for kobo device" msgstr "Veuilllez ne pas accéder à calibre-web par localhost pour obtenir un api_endpoint valide pour un appareil kobo" -#: cps/kobo_auth.py:130 cps/kobo_auth.py:158 +#: cps/kobo_auth.py:154 msgid "Kobo Setup" msgstr "Configuration Kobo" @@ -803,7 +823,7 @@ msgstr "Configuration Kobo" msgid "Register with %(provider)s" msgstr "Enregistrer avec %(provider)s" -#: cps/oauth_bb.py:138 cps/remotelogin.py:133 cps/web.py:1535 +#: cps/oauth_bb.py:138 cps/remotelogin.py:130 cps/web.py:1613 #, python-format msgid "you are now logged in as: '%(nickname)s'" msgstr "vous êtes maintenant connecté comme : '%(nickname)s'" @@ -864,163 +884,163 @@ msgstr "Erreur Oauth Google, veuillez réessayer plus tard." msgid "Google Oauth error: {}" msgstr "Erreur Oauth Google : {}" -#: cps/opds.py:384 +#: cps/opds.py:298 msgid "{} Stars" msgstr "{} Étoiles" -#: cps/remotelogin.py:65 cps/templates/layout.html:84 -#: cps/templates/login.html:4 cps/templates/login.html:21 cps/web.py:1584 +#: cps/remotelogin.py:62 cps/templates/layout.html:84 +#: cps/templates/login.html:4 cps/templates/login.html:21 cps/web.py:1662 msgid "Login" msgstr "Connexion" -#: cps/remotelogin.py:77 cps/remotelogin.py:111 +#: cps/remotelogin.py:74 cps/remotelogin.py:108 msgid "Token not found" msgstr "Jeton non trouvé" -#: cps/remotelogin.py:86 cps/remotelogin.py:119 +#: cps/remotelogin.py:83 cps/remotelogin.py:116 msgid "Token has expired" msgstr "Jeton expiré" -#: cps/remotelogin.py:95 +#: cps/remotelogin.py:92 msgid "Success! Please return to your device" msgstr "Réussite! Merci de vous tourner vers votre appareil" -#: cps/render_template.py:39 cps/web.py:416 +#: cps/render_template.py:41 cps/web.py:407 msgid "Books" msgstr "Livres" -#: cps/render_template.py:41 +#: cps/render_template.py:43 msgid "Show recent books" msgstr "Afficher les livres récents" -#: cps/render_template.py:42 cps/templates/index.xml:25 +#: cps/render_template.py:44 cps/templates/index.xml:25 msgid "Hot Books" msgstr "Livres populaires" -#: cps/render_template.py:44 +#: cps/render_template.py:46 msgid "Show Hot Books" msgstr "Montrer les livres populaires" -#: cps/render_template.py:46 cps/render_template.py:51 +#: cps/render_template.py:48 cps/render_template.py:53 msgid "Downloaded Books" msgstr "Livres téléchargés" -#: cps/render_template.py:48 cps/render_template.py:53 +#: cps/render_template.py:50 cps/render_template.py:55 #: cps/templates/user_table.html:167 msgid "Show Downloaded Books" msgstr "Montrer les livres téléchargés" -#: cps/render_template.py:56 cps/templates/index.xml:32 cps/web.py:430 +#: cps/render_template.py:58 cps/templates/index.xml:32 cps/web.py:422 msgid "Top Rated Books" msgstr "Livres les mieux notés" -#: cps/render_template.py:58 cps/templates/user_table.html:161 +#: cps/render_template.py:60 cps/templates/user_table.html:161 msgid "Show Top Rated Books" msgstr "Montrer les livres les mieux notés" -#: cps/render_template.py:59 cps/templates/index.xml:54 -#: cps/templates/index.xml:58 cps/web.py:676 +#: cps/render_template.py:61 cps/templates/index.xml:54 +#: cps/templates/index.xml:58 cps/web.py:729 msgid "Read Books" msgstr "Livres lus" -#: cps/render_template.py:61 +#: cps/render_template.py:63 msgid "Show read and unread" msgstr "Montrer lus et non-lus" -#: cps/render_template.py:63 cps/templates/index.xml:61 -#: cps/templates/index.xml:65 cps/web.py:679 +#: cps/render_template.py:65 cps/templates/index.xml:61 +#: cps/templates/index.xml:65 cps/web.py:732 msgid "Unread Books" msgstr "Livres non-lus" -#: cps/render_template.py:65 +#: cps/render_template.py:67 msgid "Show unread" msgstr "Afficher non-lus" -#: cps/render_template.py:66 +#: cps/render_template.py:68 msgid "Discover" msgstr "Découvrir" -#: cps/render_template.py:68 cps/templates/index.xml:50 +#: cps/render_template.py:70 cps/templates/index.xml:50 #: cps/templates/user_table.html:162 msgid "Show Random Books" msgstr "Montrer des livres au hasard" -#: cps/render_template.py:69 cps/templates/book_table.html:67 -#: cps/templates/index.xml:83 cps/web.py:1041 +#: cps/render_template.py:71 cps/templates/book_table.html:67 +#: cps/templates/index.xml:83 cps/web.py:1135 msgid "Categories" msgstr "Catégories" -#: cps/render_template.py:71 cps/templates/user_table.html:158 +#: cps/render_template.py:73 cps/templates/user_table.html:158 msgid "Show category selection" msgstr "Montrer la sélection par catégories" -#: cps/render_template.py:72 cps/templates/book_edit.html:90 +#: cps/render_template.py:74 cps/templates/book_edit.html:90 #: cps/templates/book_table.html:68 cps/templates/index.xml:90 -#: cps/templates/search_form.html:69 cps/web.py:948 cps/web.py:959 +#: cps/templates/search_form.html:69 cps/web.py:1034 cps/web.py:1041 msgid "Series" msgstr "Séries" -#: cps/render_template.py:74 cps/templates/user_table.html:157 +#: cps/render_template.py:76 cps/templates/user_table.html:157 msgid "Show series selection" msgstr "Montrer la sélection par séries" -#: cps/render_template.py:75 cps/templates/book_table.html:66 +#: cps/render_template.py:77 cps/templates/book_table.html:66 #: cps/templates/index.xml:69 msgid "Authors" msgstr "Auteurs" -#: cps/render_template.py:77 cps/templates/user_table.html:160 +#: cps/render_template.py:79 cps/templates/user_table.html:160 msgid "Show author selection" msgstr "Montrer la sélection par auteur" -#: cps/render_template.py:79 cps/templates/book_table.html:72 -#: cps/templates/index.xml:76 cps/web.py:925 +#: cps/render_template.py:81 cps/templates/book_table.html:72 +#: cps/templates/index.xml:76 cps/web.py:1006 msgid "Publishers" msgstr "Éditeurs" -#: cps/render_template.py:81 cps/templates/user_table.html:163 +#: cps/render_template.py:83 cps/templates/user_table.html:163 msgid "Show publisher selection" msgstr "Montrer la sélection par éditeur" -#: cps/render_template.py:82 cps/templates/book_table.html:70 +#: cps/render_template.py:84 cps/templates/book_table.html:70 #: cps/templates/index.xml:97 cps/templates/search_form.html:107 -#: cps/web.py:1018 +#: cps/web.py:1108 msgid "Languages" msgstr "Langues" -#: cps/render_template.py:85 cps/templates/user_table.html:155 +#: cps/render_template.py:87 cps/templates/user_table.html:155 msgid "Show language selection" msgstr "Montrer la sélection par langue" -#: cps/render_template.py:86 cps/templates/index.xml:104 +#: cps/render_template.py:88 cps/templates/index.xml:104 msgid "Ratings" msgstr "Notes" -#: cps/render_template.py:88 cps/templates/user_table.html:164 +#: cps/render_template.py:90 cps/templates/user_table.html:164 msgid "Show ratings selection" msgstr "Afficher la sélection des évaluations" -#: cps/render_template.py:89 cps/templates/index.xml:112 +#: cps/render_template.py:91 cps/templates/index.xml:112 msgid "File formats" msgstr "Formats de fichier" -#: cps/render_template.py:91 cps/templates/user_table.html:165 +#: cps/render_template.py:93 cps/templates/user_table.html:165 msgid "Show file formats selection" msgstr "Afficher la sélection des formats de fichiers" -#: cps/render_template.py:93 cps/web.py:703 +#: cps/render_template.py:95 cps/web.py:755 msgid "Archived Books" msgstr "Livres archivés" -#: cps/render_template.py:95 cps/templates/user_table.html:166 +#: cps/render_template.py:97 cps/templates/user_table.html:166 msgid "Show archived books" msgstr "Afficher les livres archivés" -#: cps/render_template.py:97 cps/web.py:780 +#: cps/render_template.py:100 cps/web.py:837 msgid "Books List" msgstr "Liste des livres" -#: cps/render_template.py:99 cps/templates/user_table.html:168 +#: cps/render_template.py:102 cps/templates/user_table.html:168 msgid "Show Books List" msgstr "Montrer la liste des livres" @@ -1075,262 +1095,266 @@ msgstr "Désolé, vous n’êtes pas autorisé à supprimer un livre de cette é msgid "Create a Shelf" msgstr "Créer une étagère" -#: cps/shelf.py:237 +#: cps/shelf.py:236 #, fuzzy msgid "Sorry you are not allowed to edit this shelf" msgstr "Désolé, vous n’êtes pas autorisé à enlever un livre de cette étagère : %(sname)s" -#: cps/shelf.py:239 +#: cps/shelf.py:238 msgid "Edit a shelf" msgstr "Modifier une étagère" -#: cps/shelf.py:249 +#: cps/shelf.py:248 msgid "Sorry you are not allowed to create a public shelf" msgstr "Désolé, vous n’êtes pas autorisé à créer une étagère publique" -#: cps/shelf.py:266 +#: cps/shelf.py:265 #, python-format msgid "Shelf %(title)s created" msgstr "Étagère %(title)s créée" -#: cps/shelf.py:269 +#: cps/shelf.py:268 #, python-format msgid "Shelf %(title)s changed" msgstr "L’étagère %(title)s a été modifiée" -#: cps/shelf.py:283 +#: cps/shelf.py:282 msgid "There was an error" msgstr "Il y a eu une erreur" -#: cps/shelf.py:305 +#: cps/shelf.py:304 #, python-format msgid "A public shelf with the name '%(title)s' already exists." msgstr "Une étagère publique avec le nom '%(title)s' existe déjà." -#: cps/shelf.py:316 +#: cps/shelf.py:315 #, python-format msgid "A private shelf with the name '%(title)s' already exists." msgstr "Une étagère privée avec le nom '%(title)s' existe déjà." #: cps/shelf.py:337 +msgid "Error deleting Shelf" +msgstr "" + +#: cps/shelf.py:339 #, fuzzy msgid "Shelf successfully deleted" msgstr "Le livre a été supprimé avec succès" -#: cps/shelf.py:386 +#: cps/shelf.py:389 #, python-format msgid "Change order of Shelf: '%(name)s'" msgstr "Modifier l’arrangement de l’étagère : ‘%(name)s’" -#: cps/shelf.py:456 +#: cps/shelf.py:461 #, python-format msgid "Shelf: '%(name)s'" msgstr "Étagère : '%(name)s'" -#: cps/shelf.py:460 +#: cps/shelf.py:465 msgid "Error opening shelf. Shelf does not exist or is not accessible" msgstr "Erreur à l’ouverture de l’étagère. Elle n’existe plus ou n’est plus accessible" -#: cps/updater.py:403 cps/updater.py:414 cps/updater.py:514 cps/updater.py:529 +#: cps/updater.py:426 cps/updater.py:437 cps/updater.py:538 cps/updater.py:553 msgid "Unexpected data while reading update information" msgstr "Données inattendues lors de la lecture des informations de mise à jour" -#: cps/updater.py:410 cps/updater.py:521 +#: cps/updater.py:433 cps/updater.py:545 msgid "No update available. You already have the latest version installed" msgstr "Aucune mise à jour disponible. Vous avez déjà la dernière version installée" -#: cps/updater.py:428 +#: cps/updater.py:451 msgid "A new update is available. Click on the button below to update to the latest version." msgstr "Une nouvelle mise à jour est disponible. Cliquez sur le bouton ci-dessous pour charger la dernière version." -#: cps/updater.py:446 +#: cps/updater.py:469 msgid "Could not fetch update information" msgstr "Impossible d'extraire les informations de mise à jour" -#: cps/updater.py:456 +#: cps/updater.py:479 msgid "Click on the button below to update to the latest stable version." msgstr "Téléchargez la dernière version en cliquant sur le bouton ci-dessous." -#: cps/updater.py:465 cps/updater.py:479 cps/updater.py:490 +#: cps/updater.py:488 cps/updater.py:502 cps/updater.py:513 #, python-format msgid "A new update is available. Click on the button below to update to version: %(version)s" msgstr "Une nouvelle mise à jour est disponible. Cliquez sur le bouton ci-dessous pour charger la version: %(version)s" -#: cps/updater.py:507 +#: cps/updater.py:531 msgid "No release information available" msgstr "Aucune information concernant cette version n’est disponible" -#: cps/templates/index.html:5 cps/web.py:440 +#: cps/templates/index.html:5 cps/web.py:434 msgid "Discover (Random Books)" msgstr "Découvrir (Livres au hasard)" -#: cps/web.py:471 +#: cps/web.py:470 msgid "Hot Books (Most Downloaded)" msgstr "Livres populaires (les plus téléchargés)" -#: cps/web.py:507 +#: cps/web.py:501 #, python-format msgid "Downloaded books by %(user)s" msgstr "Livres téléchargés par %(user)s" -#: cps/web.py:539 +#: cps/web.py:534 #, python-format msgid "Author: %(name)s" msgstr "Auteur : %(name)s" -#: cps/web.py:554 +#: cps/web.py:570 #, python-format msgid "Publisher: %(name)s" msgstr "Éditeur : '%(name)s'" -#: cps/web.py:569 +#: cps/web.py:598 #, python-format msgid "Series: %(serie)s" msgstr "Séries : %(serie)s" -#: cps/web.py:582 +#: cps/web.py:610 #, python-format msgid "Rating: %(rating)s stars" msgstr "Évaluation : %(rating)s étoiles" -#: cps/web.py:597 +#: cps/web.py:626 #, python-format msgid "File format: %(format)s" msgstr "Format de fichier : %(format)s" -#: cps/web.py:615 +#: cps/web.py:663 #, python-format msgid "Category: %(name)s" msgstr "Catégorie : %(name)s" -#: cps/web.py:631 +#: cps/web.py:690 #, python-format msgid "Language: %(name)s" msgstr "Langue : %(name)s" -#: cps/templates/layout.html:56 cps/web.py:737 cps/web.py:1371 +#: cps/templates/layout.html:56 cps/web.py:789 cps/web.py:1444 msgid "Advanced Search" msgstr "Recherche avancée" #: cps/templates/book_edit.html:235 cps/templates/feed.xml:33 #: cps/templates/index.xml:11 cps/templates/layout.html:45 #: cps/templates/layout.html:48 cps/templates/search_form.html:226 -#: cps/web.py:750 cps/web.py:1077 +#: cps/web.py:807 cps/web.py:1164 msgid "Search" msgstr "Chercher" -#: cps/templates/admin.html:16 cps/web.py:903 +#: cps/templates/admin.html:16 cps/web.py:979 msgid "Downloads" msgstr "Téléchargements" -#: cps/web.py:980 +#: cps/web.py:1068 msgid "Ratings list" msgstr "Liste des évaluations" -#: cps/web.py:1001 +#: cps/web.py:1095 msgid "File formats list" msgstr "Liste de formats de fichiers" -#: cps/templates/layout.html:73 cps/templates/tasks.html:7 cps/web.py:1055 +#: cps/templates/layout.html:73 cps/templates/tasks.html:7 cps/web.py:1149 msgid "Tasks" msgstr "Tâches" -#: cps/web.py:1215 +#: cps/web.py:1286 msgid "Published after " msgstr "Publié après le " -#: cps/web.py:1222 +#: cps/web.py:1293 msgid "Published before " msgstr "Publié avant le " -#: cps/web.py:1244 +#: cps/web.py:1315 #, python-format msgid "Rating <= %(rating)s" msgstr "Évaluation <= %(rating)s" -#: cps/web.py:1246 +#: cps/web.py:1317 #, python-format msgid "Rating >= %(rating)s" msgstr "Évaluation >= %(rating)s" -#: cps/web.py:1248 +#: cps/web.py:1319 #, python-format msgid "Read Status = %(status)s" msgstr "Status de lecture = %(status)s" -#: cps/web.py:1353 +#: cps/web.py:1425 msgid "Error on search for custom columns, please restart Calibre-Web" msgstr "Erreur lors de la recherche de colonnes personnalisées, veuillez redémarrer Calibre-Web" -#: cps/web.py:1449 +#: cps/web.py:1527 #, python-format msgid "Book successfully queued for sending to %(kindlemail)s" msgstr "Le livre a été mis en file de traitement avec succès pour un envoi vers %(kindlemail)s" -#: cps/web.py:1453 +#: cps/web.py:1531 #, python-format msgid "Oops! There was an error sending this book: %(res)s" msgstr "Il y a eu une erreur en envoyant ce livre : %(res)s" -#: cps/web.py:1455 +#: cps/web.py:1533 msgid "Please update your profile with a valid Send to Kindle E-mail Address." msgstr "Veuillez mettre à jour votre profil avec une adresse de courriel Kindle valide." -#: cps/web.py:1472 +#: cps/web.py:1550 msgid "E-Mail server is not configured, please contact your administrator!" msgstr "Le serveur de courriel n'est pas configuré, veuillez contacter votre administrateur!" -#: cps/templates/layout.html:85 cps/templates/register.html:17 cps/web.py:1473 -#: cps/web.py:1480 cps/web.py:1486 cps/web.py:1505 cps/web.py:1509 -#: cps/web.py:1515 +#: cps/templates/layout.html:85 cps/templates/register.html:17 cps/web.py:1551 +#: cps/web.py:1558 cps/web.py:1564 cps/web.py:1583 cps/web.py:1587 +#: cps/web.py:1593 msgid "Register" msgstr "Créer un compte" -#: cps/web.py:1507 +#: cps/web.py:1585 msgid "Your e-mail is not allowed to register" msgstr "Votre adresse de courriel n’est pas autorisé pour une inscription" -#: cps/web.py:1510 +#: cps/web.py:1588 msgid "Confirmation e-mail was send to your e-mail account." msgstr "Le courriel de confirmation a été envoyé à votre adresse." -#: cps/web.py:1524 +#: cps/web.py:1602 msgid "Cannot activate LDAP authentication" msgstr "Impossible d’activer l’authentification LDAP" -#: cps/web.py:1543 +#: cps/web.py:1621 #, python-format msgid "Fallback Login as: '%(nickname)s', LDAP Server not reachable, or user not known" msgstr "Connexion de secours comme: '%(nickname)s', le serveur LDAP est indisponible, ou l'utilisateur est inconnu" -#: cps/web.py:1549 +#: cps/web.py:1627 #, python-format msgid "Could not login: %(message)s" msgstr "Impossible de se connecter: %(message)s" -#: cps/web.py:1553 cps/web.py:1578 +#: cps/web.py:1631 cps/web.py:1656 msgid "Wrong Username or Password" msgstr "Mauvais nom d'utilisateur ou mot de passe" -#: cps/web.py:1560 +#: cps/web.py:1638 msgid "New Password was send to your email address" msgstr "Le nouveau mot de passe a été envoyé vers votre adresse de courriel" -#: cps/web.py:1566 +#: cps/web.py:1644 msgid "Please enter valid username to reset password" msgstr "Veuillez entrer un nom d'utilisateur valide pour réinitialiser le mot de passe" -#: cps/web.py:1573 +#: cps/web.py:1651 #, python-format msgid "You are now logged in as: '%(nickname)s'" msgstr "Vous êtes maintenant connecté en tant que : ‘%(nickname)s’" -#: cps/web.py:1639 cps/web.py:1688 +#: cps/web.py:1717 cps/web.py:1766 #, python-format msgid "%(name)s's profile" msgstr "Profil de %(name)s" -#: cps/web.py:1655 +#: cps/web.py:1733 msgid "Profile updated" msgstr "Profil mis à jour" @@ -1338,36 +1362,36 @@ msgstr "Profil mis à jour" msgid "Found no valid gmail.json file with OAuth information" msgstr "Aucun fichier gmail.json avec information OAuth valide trouvé" -#: cps/tasks/convert.py:137 +#: cps/tasks/convert.py:154 #, python-format msgid "Calibre ebook-convert %(tool)s not found" msgstr "ebook-convert calibre %(tool)s non trouvé" -#: cps/tasks/convert.py:163 +#: cps/tasks/convert.py:187 #, python-format msgid "%(format)s format not found on disk" msgstr "Format %(format)s non trouvé sur le disque" -#: cps/tasks/convert.py:167 +#: cps/tasks/convert.py:191 msgid "Ebook converter failed with unknown error" msgstr "Le convertisseur Ebook a échoué avec une erreur inconnue" -#: cps/tasks/convert.py:177 +#: cps/tasks/convert.py:201 #, python-format msgid "Kepubify-converter failed: %(error)s" msgstr "La commande Kepubify-converter a échouée : %(error)s" -#: cps/tasks/convert.py:199 +#: cps/tasks/convert.py:223 #, python-format msgid "Converted file not found or more than one file in folder %(folder)s" msgstr "Fichier converti non trouvé ou plus d'un fichier dans le chemin %(folder)s" -#: cps/tasks/convert.py:222 +#: cps/tasks/convert.py:246 #, python-format msgid "Ebook-converter failed: %(error)s" msgstr "La commande ebook-convert a échouée : %(error)s" -#: cps/tasks/convert.py:245 +#: cps/tasks/convert.py:269 #, python-format msgid "Calibre failed with error: %(error)s" msgstr "Calibre a échoué avec l’erreur : %(error)s" @@ -1422,7 +1446,7 @@ msgid "Edit" msgstr "Éditer" #: cps/templates/admin.html:25 cps/templates/book_edit.html:16 -#: cps/templates/book_table.html:97 cps/templates/modal_dialogs.html:63 +#: cps/templates/book_table.html:100 cps/templates/modal_dialogs.html:63 #: cps/templates/modal_dialogs.html:116 cps/templates/user_edit.html:67 #: cps/templates/user_table.html:149 msgid "Delete" @@ -1432,180 +1456,180 @@ msgstr "Supprimer" msgid "Public Shelf" msgstr "Étagère publique" -#: cps/templates/admin.html:51 +#: cps/templates/admin.html:53 msgid "Add New User" msgstr "Ajouter un nouvel utilisateur" -#: cps/templates/admin.html:53 +#: cps/templates/admin.html:55 msgid "Import LDAP Users" msgstr "Importer des utilisateurs LDAP" -#: cps/templates/admin.html:60 +#: cps/templates/admin.html:62 msgid "E-mail Server Settings" msgstr "Paramètres du serveur de courriels" -#: cps/templates/admin.html:65 cps/templates/email_edit.html:31 +#: cps/templates/admin.html:67 cps/templates/email_edit.html:31 msgid "SMTP Hostname" msgstr "Nom d'hôte du serveur SMTP" -#: cps/templates/admin.html:69 cps/templates/email_edit.html:35 +#: cps/templates/admin.html:71 cps/templates/email_edit.html:35 msgid "SMTP Port" msgstr "Port du serveur SMTP" -#: cps/templates/admin.html:73 cps/templates/email_edit.html:39 +#: cps/templates/admin.html:75 cps/templates/email_edit.html:39 msgid "Encryption" msgstr "Chiffrement" -#: cps/templates/admin.html:77 cps/templates/email_edit.html:47 +#: cps/templates/admin.html:79 cps/templates/email_edit.html:47 msgid "SMTP Login" msgstr "Compte utilisateur SMTP" -#: cps/templates/admin.html:81 cps/templates/admin.html:92 +#: cps/templates/admin.html:83 cps/templates/admin.html:94 #: cps/templates/email_edit.html:55 msgid "From E-mail" msgstr "Expéditeur des courriels" -#: cps/templates/admin.html:88 +#: cps/templates/admin.html:90 msgid "E-Mail Service" msgstr "Service courriel" -#: cps/templates/admin.html:89 +#: cps/templates/admin.html:91 msgid "Gmail via Oauth2" msgstr "Gmail via Oauth2" -#: cps/templates/admin.html:104 +#: cps/templates/admin.html:106 msgid "Configuration" msgstr "Configuration" -#: cps/templates/admin.html:107 +#: cps/templates/admin.html:109 msgid "Calibre Database Directory" msgstr "Répertoire de la base de données Calibre" -#: cps/templates/admin.html:111 cps/templates/config_edit.html:68 +#: cps/templates/admin.html:113 cps/templates/config_edit.html:68 msgid "Log Level" msgstr "Niveau de journalisation" -#: cps/templates/admin.html:115 +#: cps/templates/admin.html:117 msgid "Port" msgstr "Port" -#: cps/templates/admin.html:120 +#: cps/templates/admin.html:122 msgid "External Port" msgstr "Port exeterne" -#: cps/templates/admin.html:127 cps/templates/config_view_edit.html:28 +#: cps/templates/admin.html:129 cps/templates/config_view_edit.html:28 msgid "Books per Page" msgstr "Livres par page" -#: cps/templates/admin.html:131 +#: cps/templates/admin.html:133 msgid "Uploads" msgstr "Téléversements" -#: cps/templates/admin.html:135 +#: cps/templates/admin.html:137 msgid "Anonymous Browsing" msgstr "Navigation anonyme" -#: cps/templates/admin.html:139 +#: cps/templates/admin.html:141 msgid "Public Registration" msgstr "Inscription publique" -#: cps/templates/admin.html:143 +#: cps/templates/admin.html:145 msgid "Magic Link Remote Login" msgstr "Connexion à distance Magic Link" -#: cps/templates/admin.html:147 +#: cps/templates/admin.html:149 msgid "Reverse Proxy Login" msgstr "Compte du Reverse Proxy" -#: cps/templates/admin.html:152 cps/templates/config_edit.html:173 +#: cps/templates/admin.html:154 cps/templates/config_edit.html:173 msgid "Reverse Proxy Header Name" msgstr "Nom de l'en-tête du Reverse Proxy" -#: cps/templates/admin.html:157 +#: cps/templates/admin.html:159 #, fuzzy msgid "Edit Calibre Database Configuration" msgstr "Éditer la configuration de la base de données Calibre" -#: cps/templates/admin.html:158 +#: cps/templates/admin.html:160 msgid "Edit Basic Configuration" msgstr "Éditer la configuration principale" -#: cps/templates/admin.html:159 +#: cps/templates/admin.html:161 msgid "Edit UI Configuration" msgstr "Éditer la configuration de l’interface utilisateur" -#: cps/templates/admin.html:164 +#: cps/templates/admin.html:166 msgid "Administration" msgstr "Administration" -#: cps/templates/admin.html:165 +#: cps/templates/admin.html:167 msgid "Download Debug Package" msgstr "Télécharger le package de débogage" -#: cps/templates/admin.html:166 +#: cps/templates/admin.html:168 msgid "View Logs" msgstr "Afficher les fichiers journaux" -#: cps/templates/admin.html:169 +#: cps/templates/admin.html:171 msgid "Reconnect Calibre Database" msgstr "Reconnecter la base de données Calibre" -#: cps/templates/admin.html:170 +#: cps/templates/admin.html:172 msgid "Restart" msgstr "Redémarrer Calibre-Web" -#: cps/templates/admin.html:171 +#: cps/templates/admin.html:173 msgid "Shutdown" msgstr "Arrêter Calibre-Web" -#: cps/templates/admin.html:176 +#: cps/templates/admin.html:178 msgid "Update" msgstr "Mise à jour de Calibre-Web" -#: cps/templates/admin.html:180 +#: cps/templates/admin.html:182 msgid "Version" msgstr "Version" -#: cps/templates/admin.html:181 +#: cps/templates/admin.html:183 msgid "Details" msgstr "Détails" -#: cps/templates/admin.html:187 +#: cps/templates/admin.html:189 msgid "Current version" msgstr "Version actuelle" -#: cps/templates/admin.html:194 +#: cps/templates/admin.html:196 msgid "Check for Update" msgstr "Rechercher les mises à jour" -#: cps/templates/admin.html:195 +#: cps/templates/admin.html:197 msgid "Perform Update" msgstr "Effectuer la mise à jour" -#: cps/templates/admin.html:208 +#: cps/templates/admin.html:210 msgid "Are you sure you want to restart?" msgstr "Voulez-vous vraiment redémarrer Calibre-Web?" -#: cps/templates/admin.html:213 cps/templates/admin.html:227 -#: cps/templates/admin.html:247 cps/templates/config_db.html:70 +#: cps/templates/admin.html:215 cps/templates/admin.html:229 +#: cps/templates/admin.html:249 cps/templates/config_db.html:70 msgid "OK" msgstr "OK" -#: cps/templates/admin.html:214 cps/templates/admin.html:228 -#: cps/templates/book_edit.html:213 cps/templates/book_table.html:124 +#: cps/templates/admin.html:216 cps/templates/admin.html:230 +#: cps/templates/book_edit.html:213 cps/templates/book_table.html:127 #: cps/templates/config_db.html:54 cps/templates/config_edit.html:359 -#: cps/templates/config_view_edit.html:173 cps/templates/modal_dialogs.html:64 +#: cps/templates/config_view_edit.html:175 cps/templates/modal_dialogs.html:64 #: cps/templates/modal_dialogs.html:99 cps/templates/modal_dialogs.html:117 #: cps/templates/modal_dialogs.html:135 cps/templates/shelf_edit.html:27 #: cps/templates/user_edit.html:144 msgid "Cancel" msgstr "Annuler" -#: cps/templates/admin.html:226 +#: cps/templates/admin.html:228 msgid "Are you sure you want to shutdown?" msgstr "Voulez-vous vraiment arrêter Calibre-Web?" -#: cps/templates/admin.html:238 +#: cps/templates/admin.html:240 msgid "Updating, please do not reload this page" msgstr "Mise à jour en cours, ne pas rafraîchir la page" @@ -1617,44 +1641,43 @@ msgstr "via" msgid "In Library" msgstr "Dans la librairie" -#: cps/templates/author.html:26 cps/templates/index.html:72 -#: cps/templates/search.html:29 cps/templates/shelf.html:19 +#: cps/templates/author.html:26 cps/templates/index.html:73 +#: cps/templates/search.html:30 cps/templates/shelf.html:19 msgid "Sort according to book date, newest first" msgstr "Trier en fonction de la date du livre, le plus récent en premier" -#: cps/templates/author.html:27 cps/templates/index.html:73 -#: cps/templates/search.html:30 cps/templates/shelf.html:20 +#: cps/templates/author.html:27 cps/templates/index.html:74 +#: cps/templates/search.html:31 cps/templates/shelf.html:20 msgid "Sort according to book date, oldest first" msgstr "Trier en fonction de la date du livre, le plus ancien en premier" -#: cps/templates/author.html:28 cps/templates/index.html:74 -#: cps/templates/search.html:31 cps/templates/shelf.html:21 +#: cps/templates/author.html:28 cps/templates/index.html:75 +#: cps/templates/search.html:32 cps/templates/shelf.html:21 msgid "Sort title in alphabetical order" msgstr "Trier les titres dans l’ordre alphabétique" -#: cps/templates/author.html:29 cps/templates/index.html:75 -#: cps/templates/search.html:32 cps/templates/shelf.html:22 +#: cps/templates/author.html:29 cps/templates/index.html:76 +#: cps/templates/search.html:33 cps/templates/shelf.html:22 msgid "Sort title in reverse alphabetical order" msgstr "Trier le titre dans l’ordre alphabétique inverse" -#: cps/templates/author.html:30 cps/templates/index.html:78 -#: cps/templates/search.html:35 cps/templates/shelf.html:25 +#: cps/templates/author.html:30 cps/templates/index.html:79 +#: cps/templates/search.html:36 cps/templates/shelf.html:25 msgid "Sort according to publishing date, newest first" msgstr "Trier en fonction de la date de publication, le plus récent en premier" -#: cps/templates/author.html:31 cps/templates/index.html:79 -#: cps/templates/search.html:36 cps/templates/shelf.html:26 +#: cps/templates/author.html:31 cps/templates/index.html:80 +#: cps/templates/search.html:37 cps/templates/shelf.html:26 msgid "Sort according to publishing date, oldest first" msgstr "Trier en fonction de la date de publication, le plus ancien en premier" -#: cps/templates/author.html:57 cps/templates/author.html:117 -#: cps/templates/discover.html:30 cps/templates/index.html:29 -#: cps/templates/index.html:111 cps/templates/search.html:65 -#: cps/templates/shelf.html:54 +#: cps/templates/author.html:56 cps/templates/author.html:115 +#: cps/templates/index.html:29 cps/templates/index.html:112 +#: cps/templates/search.html:66 cps/templates/shelf.html:54 msgid "reduce" msgstr "réduire" -#: cps/templates/author.html:101 +#: cps/templates/author.html:99 msgid "More by" msgstr "Plus de" @@ -1779,7 +1802,7 @@ msgid "Fetch Metadata" msgstr "Obtenir les métadonnées" #: cps/templates/book_edit.html:212 cps/templates/config_db.html:53 -#: cps/templates/config_edit.html:358 cps/templates/config_view_edit.html:172 +#: cps/templates/config_edit.html:358 cps/templates/config_view_edit.html:174 #: cps/templates/email_edit.html:65 cps/templates/shelf_edit.html:25 #: cps/templates/shelf_order.html:41 cps/templates/user_edit.html:142 msgid "Save" @@ -1908,27 +1931,35 @@ msgstr "Saisir le nom du domaine" msgid "Comments" msgstr "Commentaires" -#: cps/templates/book_table.html:77 cps/templates/book_table.html:79 -#: cps/templates/book_table.html:81 cps/templates/book_table.html:83 -#: cps/templates/book_table.html:87 cps/templates/book_table.html:89 -#: cps/templates/book_table.html:91 cps/templates/book_table.html:93 +#: cps/templates/book_table.html:75 +msgid "Archiv Status" +msgstr "" + +#: cps/templates/book_table.html:77 cps/templates/search_form.html:42 +msgid "Read Status" +msgstr "Status de lecture" + +#: cps/templates/book_table.html:80 cps/templates/book_table.html:82 +#: cps/templates/book_table.html:84 cps/templates/book_table.html:86 +#: cps/templates/book_table.html:90 cps/templates/book_table.html:92 +#: cps/templates/book_table.html:96 #, fuzzy msgid "Enter " msgstr "Identifiants" -#: cps/templates/book_table.html:110 cps/templates/modal_dialogs.html:46 +#: cps/templates/book_table.html:113 cps/templates/modal_dialogs.html:46 msgid "Are you really sure?" msgstr "Êtes-vous vraiment sûr?" -#: cps/templates/book_table.html:114 +#: cps/templates/book_table.html:117 msgid "Books with Title will be merged from:" msgstr "Les livres avec titre vont être fusionnés depuis :" -#: cps/templates/book_table.html:118 +#: cps/templates/book_table.html:121 msgid "Into Book with Title:" msgstr "Dans le livre avec le titre :" -#: cps/templates/book_table.html:123 +#: cps/templates/book_table.html:126 msgid "Merge" msgstr "Fusionner" @@ -2105,11 +2136,6 @@ msgstr "Port du serveur LDAP" msgid "LDAP Encryption" msgstr "Chiffrement LDAP" -#: cps/templates/config_edit.html:204 cps/templates/config_view_edit.html:62 -#: cps/templates/email_edit.html:41 -msgid "None" -msgstr "Aucun" - #: cps/templates/config_edit.html:205 msgid "TLS" msgstr "TLS" @@ -2328,11 +2354,11 @@ msgstr "Mode de visualisation par défaut pour les nouveaux utilisateurs" msgid "Show Random Books in Detail View" msgstr "Montrer aléatoirement des livres dans la vue détaillée" -#: cps/templates/config_view_edit.html:165 cps/templates/user_edit.html:87 +#: cps/templates/config_view_edit.html:166 cps/templates/user_edit.html:87 msgid "Add Allowed/Denied Tags" msgstr "Ajouter les étiquettes autorisées/refusées" -#: cps/templates/config_view_edit.html:166 +#: cps/templates/config_view_edit.html:167 msgid "Add Allowed/Denied custom column values" msgstr "Ajouter les valeurs de colonnes autorisées/refusées" @@ -2381,13 +2407,13 @@ msgstr "Archivé" msgid "Description:" msgstr "Description :" -#: cps/templates/detail.html:256 cps/templates/search.html:14 +#: cps/templates/detail.html:256 cps/templates/search.html:15 msgid "Add to shelf" msgstr "Ajouter à l'étagère" #: cps/templates/detail.html:267 cps/templates/detail.html:284 #: cps/templates/feed.xml:79 cps/templates/layout.html:137 -#: cps/templates/search.html:20 +#: cps/templates/search.html:21 msgid "(Public)" msgstr "(Public)" @@ -2465,10 +2491,15 @@ msgstr "Domaines refusés (Liste noire)" msgid "Next" msgstr "Suivant" -#: cps/templates/generate_kobo_auth_url.html:5 +#: cps/templates/generate_kobo_auth_url.html:6 msgid "Open the .kobo/Kobo eReader.conf file in a text editor and add (or edit):" msgstr "Ouvrir le fichier .kobo/Kobo eReader.conf dans un éditeur de texte et ajouter (ou éditer):" +#: cps/templates/generate_kobo_auth_url.html:11 +#, fuzzy +msgid "Kobo Token:" +msgstr "Jeton de synchro Kobo" + #: cps/templates/http_error.html:31 #, fuzzy msgid "Calibre-Web Instance is unconfigured, please contact your administrator" @@ -2486,29 +2517,29 @@ msgstr "Retour à l’accueil" msgid "Logout User" msgstr "Déconnecter l’utilisateur" -#: cps/templates/index.html:69 +#: cps/templates/index.html:70 msgid "Sort ascending according to download count" msgstr "Trier de manière ascendante selon le nombre de téléchargements" -#: cps/templates/index.html:70 +#: cps/templates/index.html:71 msgid "Sort descending according to download count" msgstr "Trier de manière descendante selon le nombre de téléchargements" -#: cps/templates/index.html:76 cps/templates/search.html:33 +#: cps/templates/index.html:77 cps/templates/search.html:34 #: cps/templates/shelf.html:23 msgid "Sort authors in alphabetical order" msgstr "Trier les auteurs dans l’ordre alphabétique" -#: cps/templates/index.html:77 cps/templates/search.html:34 +#: cps/templates/index.html:78 cps/templates/search.html:35 #: cps/templates/shelf.html:24 msgid "Sort authors in reverse alphabetical order" msgstr "Trier les auteurs dans l’ordre alphabétique inverse" -#: cps/templates/index.html:81 +#: cps/templates/index.html:82 msgid "Sort ascending according to series index" msgstr "Trier par ordre croissant en fonction de l’index de série" -#: cps/templates/index.html:82 +#: cps/templates/index.html:83 msgid "Sort descending according to series index" msgstr "Trier par ordre décroissant en fonction de l’index de série" @@ -2944,10 +2975,6 @@ msgstr "Date de publication (depuis)" msgid "Published Date To" msgstr "Date de publication (jusqu’à)" -#: cps/templates/search_form.html:42 -msgid "Read Status" -msgstr "Status de lecture" - #: cps/templates/search_form.html:59 msgid "Exclude Tags" msgstr "Exclure les étiquettes" diff --git a/cps/translations/hu/LC_MESSAGES/messages.mo b/cps/translations/hu/LC_MESSAGES/messages.mo index fdf261a2..2faa8dc4 100644 Binary files a/cps/translations/hu/LC_MESSAGES/messages.mo and b/cps/translations/hu/LC_MESSAGES/messages.mo differ diff --git a/cps/translations/hu/LC_MESSAGES/messages.po b/cps/translations/hu/LC_MESSAGES/messages.po index 3cd5bb8d..4d4bd63b 100644 --- a/cps/translations/hu/LC_MESSAGES/messages.po +++ b/cps/translations/hu/LC_MESSAGES/messages.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2022-01-15 09:19+0100\n" +"POT-Creation-Date: 2022-04-18 20:01+0200\n" "PO-Revision-Date: 2019-04-06 23:36+0200\n" "Last-Translator: \n" "Language: hu\n" @@ -16,586 +16,589 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.9.0\n" +"Generated-By: Babel 2.9.1\n" -#: cps/about.py:34 cps/about.py:49 cps/about.py:65 cps/converter.py:31 -msgid "not installed" -msgstr "nincs telepítve" - -#: cps/about.py:47 cps/about.py:63 -msgid "installed" -msgstr "" - -#: cps/about.py:145 +#: cps/about.py:86 msgid "Statistics" msgstr "Statisztika" -#: cps/admin.py:144 +#: cps/admin.py:141 msgid "Server restarted, please reload page" msgstr "A kiszolgáló újraindult, tölts be újra az oldalt!" -#: cps/admin.py:146 +#: cps/admin.py:143 msgid "Performing shutdown of server, please close window" msgstr "A kiszolgáló leállítása folyamatban, zárd be ezt az ablakot" -#: cps/admin.py:154 +#: cps/admin.py:151 msgid "Reconnect successful" msgstr "" -#: cps/admin.py:157 +#: cps/admin.py:154 msgid "Unknown command" msgstr "" -#: cps/admin.py:167 cps/editbooks.py:707 cps/editbooks.py:721 -#: cps/editbooks.py:866 cps/editbooks.py:868 cps/editbooks.py:895 -#: cps/editbooks.py:911 cps/updater.py:584 cps/uploader.py:93 -#: cps/uploader.py:103 +#: cps/admin.py:176 cps/editbooks.py:713 cps/editbooks.py:892 +#: cps/editbooks.py:894 cps/editbooks.py:930 cps/editbooks.py:947 +#: cps/updater.py:608 cps/uploader.py:93 cps/uploader.py:103 msgid "Unknown" msgstr "Ismeretlen" -#: cps/admin.py:188 +#: cps/admin.py:197 msgid "Admin page" msgstr "Rendszergazda oldala" -#: cps/admin.py:207 +#: cps/admin.py:217 msgid "Basic Configuration" msgstr "Alapvető beállítások" -#: cps/admin.py:244 +#: cps/admin.py:255 msgid "UI Configuration" msgstr "Felhasználói felület beállításai" -#: cps/admin.py:277 cps/templates/admin.html:50 +#: cps/admin.py:289 cps/templates/admin.html:51 #, fuzzy msgid "Edit Users" msgstr "Rendszergazda felhasználó" -#: cps/admin.py:318 cps/opds.py:109 cps/opds.py:198 cps/opds.py:275 -#: cps/opds.py:327 cps/templates/grid.html:13 cps/templates/languages.html:9 +#: cps/admin.py:333 cps/opds.py:529 cps/templates/grid.html:13 #: cps/templates/list.html:13 msgid "All" msgstr "" -#: cps/admin.py:343 cps/admin.py:1615 +#: cps/admin.py:360 cps/admin.py:1648 msgid "User not found" msgstr "" -#: cps/admin.py:357 +#: cps/admin.py:374 msgid "{} users deleted successfully" msgstr "" -#: cps/admin.py:379 cps/templates/config_view_edit.html:133 +#: cps/admin.py:397 cps/templates/config_view_edit.html:133 #: cps/templates/user_edit.html:45 cps/templates/user_table.html:81 msgid "Show All" msgstr "Mindent mutass" -#: cps/admin.py:400 cps/admin.py:406 +#: cps/admin.py:418 cps/admin.py:424 msgid "Malformed request" msgstr "" -#: cps/admin.py:418 cps/admin.py:1493 +#: cps/admin.py:436 cps/admin.py:1526 msgid "Guest Name can't be changed" msgstr "" -#: cps/admin.py:430 +#: cps/admin.py:448 msgid "Guest can't have this role" msgstr "" -#: cps/admin.py:442 cps/admin.py:1451 +#: cps/admin.py:460 cps/admin.py:1484 msgid "No admin user remaining, can't remove admin role" msgstr "" -#: cps/admin.py:446 cps/admin.py:460 +#: cps/admin.py:464 cps/admin.py:478 msgid "Value has to be true or false" msgstr "" -#: cps/admin.py:448 +#: cps/admin.py:466 msgid "Invalid role" msgstr "" -#: cps/admin.py:452 +#: cps/admin.py:470 msgid "Guest can't have this view" msgstr "" -#: cps/admin.py:462 +#: cps/admin.py:480 msgid "Invalid view" msgstr "" -#: cps/admin.py:465 +#: cps/admin.py:483 msgid "Guest's Locale is determined automatically and can't be set" msgstr "" -#: cps/admin.py:469 +#: cps/admin.py:487 msgid "No Valid Locale Given" msgstr "" -#: cps/admin.py:480 +#: cps/admin.py:498 msgid "No Valid Book Language Given" msgstr "" -#: cps/admin.py:482 +#: cps/admin.py:500 cps/editbooks.py:1267 msgid "Parameter not found" msgstr "" -#: cps/admin.py:533 +#: cps/admin.py:553 msgid "Invalid Read Column" msgstr "" -#: cps/admin.py:539 +#: cps/admin.py:559 msgid "Invalid Restricted Column" msgstr "" -#: cps/admin.py:560 cps/admin.py:1323 +#: cps/admin.py:579 cps/admin.py:1355 msgid "Calibre-Web configuration updated" msgstr "A Calibre-Web konfigurációja frissítve." -#: cps/admin.py:572 +#: cps/admin.py:591 msgid "Do you really want to delete the Kobo Token?" msgstr "" -#: cps/admin.py:574 +#: cps/admin.py:593 msgid "Do you really want to delete this domain?" msgstr "" -#: cps/admin.py:576 +#: cps/admin.py:595 msgid "Do you really want to delete this user?" msgstr "" -#: cps/admin.py:578 +#: cps/admin.py:597 msgid "Are you sure you want to delete this shelf?" msgstr "Valóban törölni akarod a polcot?" -#: cps/admin.py:580 +#: cps/admin.py:599 #, fuzzy msgid "Are you sure you want to change locales of selected user(s)?" msgstr "Valóban törölni akarod a polcot?" -#: cps/admin.py:582 +#: cps/admin.py:601 msgid "Are you sure you want to change visible book languages for selected user(s)?" msgstr "" -#: cps/admin.py:584 +#: cps/admin.py:603 msgid "Are you sure you want to change the selected role for the selected user(s)?" msgstr "" -#: cps/admin.py:586 +#: cps/admin.py:605 #, fuzzy msgid "Are you sure you want to change the selected restrictions for the selected user(s)?" msgstr "Valóban törölni akarod a polcot?" -#: cps/admin.py:588 +#: cps/admin.py:607 msgid "Are you sure you want to change the selected visibility restrictions for the selected user(s)?" msgstr "" -#: cps/admin.py:590 +#: cps/admin.py:610 #, fuzzy msgid "Are you sure you want to change shelf sync behavior for the selected user(s)?" msgstr "Valóban törölni akarod a polcot?" -#: cps/admin.py:592 +#: cps/admin.py:612 #, fuzzy msgid "Are you sure you want to change Calibre library location?" msgstr "Valóban le akarod állítani a Calibre-Web-et?" -#: cps/admin.py:594 +#: cps/admin.py:614 msgid "Are you sure you want delete Calibre-Web's sync database to force a full sync with your Kobo Reader?" msgstr "" -#: cps/admin.py:743 +#: cps/admin.py:764 msgid "Tag not found" msgstr "" -#: cps/admin.py:755 +#: cps/admin.py:776 msgid "Invalid Action" msgstr "" -#: cps/admin.py:871 cps/admin.py:877 cps/admin.py:887 cps/admin.py:897 +#: cps/admin.py:893 cps/admin.py:899 cps/admin.py:909 cps/admin.py:919 #: cps/templates/modal_dialogs.html:29 cps/templates/user_table.html:41 #: cps/templates/user_table.html:58 msgid "Deny" msgstr "" -#: cps/admin.py:873 cps/admin.py:879 cps/admin.py:889 cps/admin.py:899 +#: cps/admin.py:895 cps/admin.py:901 cps/admin.py:911 cps/admin.py:921 #: cps/templates/modal_dialogs.html:28 cps/templates/user_table.html:44 #: cps/templates/user_table.html:61 msgid "Allow" msgstr "" -#: cps/admin.py:913 +#: cps/admin.py:936 msgid "{} sync entries deleted" msgstr "" -#: cps/admin.py:1036 +#: cps/admin.py:1059 msgid "client_secrets.json Is Not Configured For Web Application" msgstr "" -#: cps/admin.py:1081 +#: cps/admin.py:1104 msgid "Logfile Location is not Valid, Please Enter Correct Path" msgstr "" -#: cps/admin.py:1087 +#: cps/admin.py:1110 msgid "Access Logfile Location is not Valid, Please Enter Correct Path" msgstr "" -#: cps/admin.py:1117 +#: cps/admin.py:1140 msgid "Please Enter a LDAP Provider, Port, DN and User Object Identifier" msgstr "" -#: cps/admin.py:1123 +#: cps/admin.py:1146 msgid "Please Enter a LDAP Service Account and Password" msgstr "" -#: cps/admin.py:1126 +#: cps/admin.py:1149 msgid "Please Enter a LDAP Service Account" msgstr "" -#: cps/admin.py:1131 +#: cps/admin.py:1154 #, python-format msgid "LDAP Group Object Filter Needs to Have One \"%s\" Format Identifier" msgstr "" -#: cps/admin.py:1133 +#: cps/admin.py:1156 msgid "LDAP Group Object Filter Has Unmatched Parenthesis" msgstr "" -#: cps/admin.py:1137 +#: cps/admin.py:1160 #, python-format msgid "LDAP User Object Filter needs to Have One \"%s\" Format Identifier" msgstr "" -#: cps/admin.py:1139 +#: cps/admin.py:1162 msgid "LDAP User Object Filter Has Unmatched Parenthesis" msgstr "" -#: cps/admin.py:1146 +#: cps/admin.py:1169 #, python-format msgid "LDAP Member User Filter needs to Have One \"%s\" Format Identifier" msgstr "" -#: cps/admin.py:1148 +#: cps/admin.py:1171 msgid "LDAP Member User Filter Has Unmatched Parenthesis" msgstr "" -#: cps/admin.py:1155 +#: cps/admin.py:1178 msgid "LDAP CACertificate, Certificate or Key Location is not Valid, Please Enter Correct Path" msgstr "" -#: cps/admin.py:1197 cps/admin.py:1308 cps/admin.py:1405 cps/admin.py:1521 -#: cps/admin.py:1590 cps/shelf.py:100 cps/shelf.py:160 cps/shelf.py:203 -#: cps/shelf.py:279 cps/shelf.py:341 cps/shelf.py:376 cps/shelf.py:451 -msgid "Settings DB is not Writeable" -msgstr "" - -#: cps/admin.py:1208 -msgid "DB Location is not Valid, Please Enter Correct Path" -msgstr "" - -#: cps/admin.py:1223 -msgid "DB is not Writeable" -msgstr "" - -#: cps/admin.py:1235 -msgid "Keyfile Location is not Valid, Please Enter Correct Path" -msgstr "" - -#: cps/admin.py:1239 -msgid "Certfile Location is not Valid, Please Enter Correct Path" -msgstr "" - -#: cps/admin.py:1346 -#, fuzzy -msgid "Database Settings updated" -msgstr "Az e-mail kiszolgáló beállításai frissítve." - -#: cps/admin.py:1354 -#, fuzzy -msgid "Database Configuration" -msgstr "Funkciók beállítása" - -#: cps/admin.py:1370 cps/web.py:1479 -msgid "Please fill out all fields!" -msgstr "Az összes mezőt ki kell tölteni!" - -#: cps/admin.py:1378 -msgid "E-mail is not from valid domain" -msgstr "Az e-mail tartománya nem érvényes." - -#: cps/admin.py:1384 cps/admin.py:1543 -msgid "Add new user" -msgstr "Új felhasználó hozzáadása" - -#: cps/admin.py:1395 -#, python-format -msgid "User '%(user)s' created" -msgstr "A következő felhasználó létrehozva: %(user)s" - -#: cps/admin.py:1401 -#, fuzzy -msgid "Found an existing account for this e-mail address or name." -msgstr "Már létezik felhasználó ehhez az e-mail címhez vagy felhasználói névhez." - -#: cps/admin.py:1430 -#, python-format -msgid "User '%(nick)s' deleted" -msgstr "A felhasználó törölve: %(nick)s" - -#: cps/admin.py:1432 cps/admin.py:1433 -msgid "Can't delete Guest User" -msgstr "" - -#: cps/admin.py:1436 -msgid "No admin user remaining, can't delete user" -msgstr "" - -#: cps/admin.py:1509 cps/admin.py:1634 -#, python-format -msgid "Edit User %(nick)s" -msgstr " A felhasználó szerkesztése: %(nick)s" - -#: cps/admin.py:1513 -#, python-format -msgid "User '%(nick)s' updated" -msgstr "A felhasználó frissítve: %(nick)s" - -#: cps/admin.py:1517 cps/admin.py:1649 cps/web.py:1504 cps/web.py:1564 -msgid "An unknown error occurred. Please try again later." -msgstr "Ismeretlen hiba történt. Próbáld újra később!" - -#: cps/admin.py:1552 cps/templates/admin.html:98 -msgid "Edit E-mail Server Settings" -msgstr "SMTP beállítások változtatása" - -#: cps/admin.py:1571 -msgid "Gmail Account Verification Successful" -msgstr "" - -#: cps/admin.py:1597 -#, python-format -msgid "Test e-mail queued for sending to %(email)s, please check Tasks for result" -msgstr "" - -#: cps/admin.py:1600 -#, python-format -msgid "There was an error sending the Test e-mail: %(res)s" -msgstr "Hiba történt a teszt levél küldése során: %(res)s" - -#: cps/admin.py:1602 -msgid "Please configure your e-mail address first..." -msgstr "" - -#: cps/admin.py:1604 -msgid "E-mail server settings updated" -msgstr "Az e-mail kiszolgáló beállításai frissítve." - -#: cps/admin.py:1646 -#, python-format -msgid "Password for user %(user)s reset" -msgstr "A(z) %(user)s felhasználó jelszavának alaphelyzetbe állítása" - -#: cps/admin.py:1652 cps/web.py:1444 -msgid "Please configure the SMTP mail settings first..." -msgstr "Először be kell állítani az SMTP levelező beállításokat..." - -#: cps/admin.py:1663 -msgid "Logfile viewer" -msgstr "" - -#: cps/admin.py:1729 -msgid "Requesting update package" -msgstr "Frissítési csomag kérése" - -#: cps/admin.py:1730 -msgid "Downloading update package" -msgstr "Frissítési csomag letöltése" - -#: cps/admin.py:1731 -msgid "Unzipping update package" -msgstr "Frissítési csomag kitömörítése" - -#: cps/admin.py:1732 -msgid "Replacing files" -msgstr "Fájlok cserélése" - -#: cps/admin.py:1733 -msgid "Database connections are closed" -msgstr "Adatbázis kapcsolatok lezárva" - -#: cps/admin.py:1734 -msgid "Stopping server" -msgstr "Szerver leállítása" - -#: cps/admin.py:1735 -msgid "Update finished, please press okay and reload page" -msgstr "A frissítés települt, kattints az OK-ra és újra tölt az oldal" - -#: cps/admin.py:1736 cps/admin.py:1737 cps/admin.py:1738 cps/admin.py:1739 -#: cps/admin.py:1740 cps/admin.py:1741 -msgid "Update failed:" -msgstr "A frissítés nem sikerült:" - -#: cps/admin.py:1736 cps/updater.py:385 cps/updater.py:595 cps/updater.py:597 -msgid "HTTP Error" -msgstr "HTTP hiba" - -#: cps/admin.py:1737 cps/updater.py:387 cps/updater.py:599 -msgid "Connection error" -msgstr "Kapcsolódási hiba" - -#: cps/admin.py:1738 cps/updater.py:389 cps/updater.py:601 -msgid "Timeout while establishing connection" -msgstr "Időtúllépés a kapcsolódás során" - -#: cps/admin.py:1739 cps/updater.py:391 cps/updater.py:603 -msgid "General error" -msgstr "Általános hiba" - -#: cps/admin.py:1740 -msgid "Update file could not be saved in temp dir" -msgstr "" - -#: cps/admin.py:1741 -msgid "Files could not be replaced during update" -msgstr "" - -#: cps/admin.py:1765 -msgid "Failed to extract at least One LDAP User" -msgstr "" - -#: cps/admin.py:1810 -msgid "Failed to Create at Least One LDAP User" -msgstr "" - -#: cps/admin.py:1823 -#, python-format -msgid "Error: %(ldaperror)s" -msgstr "" - -#: cps/admin.py:1827 -msgid "Error: No user returned in response of LDAP server" -msgstr "" - -#: cps/admin.py:1860 -msgid "At Least One LDAP User Not Found in Database" -msgstr "" - -#: cps/admin.py:1862 -msgid "{} User Successfully Imported" -msgstr "" - -#: cps/converter.py:30 -msgid "not configured" -msgstr "" - -#: cps/converter.py:32 -msgid "Execution permissions missing" -msgstr "" - -#: cps/db.py:651 cps/web.py:667 cps/web.py:1155 -#, python-format -msgid "Custom Column No.%(column)d is not existing in calibre database" -msgstr "" - -#: cps/editbooks.py:300 cps/editbooks.py:302 -msgid "Book Format Successfully Deleted" -msgstr "" - -#: cps/editbooks.py:309 cps/editbooks.py:311 -msgid "Book Successfully Deleted" -msgstr "" - -#: cps/editbooks.py:361 -msgid "You are missing permissions to delete books" -msgstr "" - -#: cps/editbooks.py:376 cps/editbooks.py:763 cps/web.py:523 cps/web.py:1703 -#: cps/web.py:1744 cps/web.py:1811 -msgid "Oops! Selected book title is unavailable. File does not exist or is not accessible" -msgstr "Hiba történt az e-könyv megnyitásakor. A fájl nem létezik vagy nem érhető el:" - -#: cps/editbooks.py:410 -msgid "edit metadata" -msgstr "Metaadatok szerkesztése" - -#: cps/editbooks.py:458 -#, python-format -msgid "%(seriesindex)s is not a valid number, skipping" -msgstr "" - -#: cps/editbooks.py:494 cps/editbooks.py:958 -#, fuzzy, python-format -msgid "'%(langname)s' is not a valid language" -msgstr "A(z) %(langname)s nem érvényes nyelv" - -#: cps/editbooks.py:634 cps/editbooks.py:985 -#, python-format -msgid "File extension '%(ext)s' is not allowed to be uploaded to this server" -msgstr "A(z) \"%(ext)s\" kiterjesztésű fájlok feltöltése nincs engedélyezve ezen a szerveren." - -#: cps/editbooks.py:638 cps/editbooks.py:989 -msgid "File to be uploaded must have an extension" -msgstr "A feltöltendő fájlnak kiterjesztéssel kell rendelkeznie!" - -#: cps/editbooks.py:650 -#, python-format -msgid "Failed to create path %(path)s (Permission denied)." -msgstr "Nem sikerült létrehozni az elérési utat (engedély megtagadva): %(path)s." - -#: cps/editbooks.py:655 -#, python-format -msgid "Failed to store file %(file)s." -msgstr "Nem sikerült elmenteni a %(file)s fájlt." - -#: cps/editbooks.py:673 cps/editbooks.py:1076 cps/web.py:1664 +#: cps/admin.py:1223 cps/admin.py:1339 cps/admin.py:1437 cps/admin.py:1554 +#: cps/admin.py:1623 cps/editbooks.py:678 cps/editbooks.py:882 +#: cps/editbooks.py:1130 cps/shelf.py:100 cps/shelf.py:160 cps/shelf.py:203 +#: cps/shelf.py:278 cps/shelf.py:343 cps/shelf.py:380 cps/shelf.py:456 +#: cps/web.py:1742 #, python-format msgid "Database error: %(error)s." msgstr "" -#: cps/editbooks.py:678 +#: cps/admin.py:1235 +msgid "DB Location is not Valid, Please Enter Correct Path" +msgstr "" + +#: cps/admin.py:1253 +msgid "DB is not Writeable" +msgstr "" + +#: cps/admin.py:1266 +msgid "Keyfile Location is not Valid, Please Enter Correct Path" +msgstr "" + +#: cps/admin.py:1270 +msgid "Certfile Location is not Valid, Please Enter Correct Path" +msgstr "" + +#: cps/admin.py:1378 +#, fuzzy +msgid "Database Settings updated" +msgstr "Az e-mail kiszolgáló beállításai frissítve." + +#: cps/admin.py:1386 +#, fuzzy +msgid "Database Configuration" +msgstr "Funkciók beállítása" + +#: cps/admin.py:1402 cps/web.py:1557 +msgid "Please fill out all fields!" +msgstr "Az összes mezőt ki kell tölteni!" + +#: cps/admin.py:1410 +msgid "E-mail is not from valid domain" +msgstr "Az e-mail tartománya nem érvényes." + +#: cps/admin.py:1416 cps/admin.py:1576 +msgid "Add new user" +msgstr "Új felhasználó hozzáadása" + +#: cps/admin.py:1427 +#, python-format +msgid "User '%(user)s' created" +msgstr "A következő felhasználó létrehozva: %(user)s" + +#: cps/admin.py:1433 +#, fuzzy +msgid "Found an existing account for this e-mail address or name." +msgstr "Már létezik felhasználó ehhez az e-mail címhez vagy felhasználói névhez." + +#: cps/admin.py:1463 +#, python-format +msgid "User '%(nick)s' deleted" +msgstr "A felhasználó törölve: %(nick)s" + +#: cps/admin.py:1465 cps/admin.py:1466 +msgid "Can't delete Guest User" +msgstr "" + +#: cps/admin.py:1469 +msgid "No admin user remaining, can't delete user" +msgstr "" + +#: cps/admin.py:1542 cps/admin.py:1667 +#, python-format +msgid "Edit User %(nick)s" +msgstr " A felhasználó szerkesztése: %(nick)s" + +#: cps/admin.py:1546 +#, python-format +msgid "User '%(nick)s' updated" +msgstr "A felhasználó frissítve: %(nick)s" + +#: cps/admin.py:1550 cps/admin.py:1682 cps/web.py:1582 cps/web.py:1642 +msgid "An unknown error occurred. Please try again later." +msgstr "Ismeretlen hiba történt. Próbáld újra később!" + +#: cps/admin.py:1585 cps/templates/admin.html:100 +msgid "Edit E-mail Server Settings" +msgstr "SMTP beállítások változtatása" + +#: cps/admin.py:1604 +msgid "Gmail Account Verification Successful" +msgstr "" + +#: cps/admin.py:1630 +#, python-format +msgid "Test e-mail queued for sending to %(email)s, please check Tasks for result" +msgstr "" + +#: cps/admin.py:1633 +#, python-format +msgid "There was an error sending the Test e-mail: %(res)s" +msgstr "Hiba történt a teszt levél küldése során: %(res)s" + +#: cps/admin.py:1635 +msgid "Please configure your e-mail address first..." +msgstr "" + +#: cps/admin.py:1637 +msgid "E-mail server settings updated" +msgstr "Az e-mail kiszolgáló beállításai frissítve." + +#: cps/admin.py:1679 +#, python-format +msgid "Password for user %(user)s reset" +msgstr "A(z) %(user)s felhasználó jelszavának alaphelyzetbe állítása" + +#: cps/admin.py:1685 cps/web.py:1522 +msgid "Please configure the SMTP mail settings first..." +msgstr "Először be kell állítani az SMTP levelező beállításokat..." + +#: cps/admin.py:1696 +msgid "Logfile viewer" +msgstr "" + +#: cps/admin.py:1762 +msgid "Requesting update package" +msgstr "Frissítési csomag kérése" + +#: cps/admin.py:1763 +msgid "Downloading update package" +msgstr "Frissítési csomag letöltése" + +#: cps/admin.py:1764 +msgid "Unzipping update package" +msgstr "Frissítési csomag kitömörítése" + +#: cps/admin.py:1765 +msgid "Replacing files" +msgstr "Fájlok cserélése" + +#: cps/admin.py:1766 +msgid "Database connections are closed" +msgstr "Adatbázis kapcsolatok lezárva" + +#: cps/admin.py:1767 +msgid "Stopping server" +msgstr "Szerver leállítása" + +#: cps/admin.py:1768 +msgid "Update finished, please press okay and reload page" +msgstr "A frissítés települt, kattints az OK-ra és újra tölt az oldal" + +#: cps/admin.py:1769 cps/admin.py:1770 cps/admin.py:1771 cps/admin.py:1772 +#: cps/admin.py:1773 cps/admin.py:1774 +msgid "Update failed:" +msgstr "A frissítés nem sikerült:" + +#: cps/admin.py:1769 cps/updater.py:384 cps/updater.py:619 cps/updater.py:621 +msgid "HTTP Error" +msgstr "HTTP hiba" + +#: cps/admin.py:1770 cps/updater.py:386 cps/updater.py:623 +msgid "Connection error" +msgstr "Kapcsolódási hiba" + +#: cps/admin.py:1771 cps/updater.py:388 cps/updater.py:625 +msgid "Timeout while establishing connection" +msgstr "Időtúllépés a kapcsolódás során" + +#: cps/admin.py:1772 cps/updater.py:390 cps/updater.py:627 +msgid "General error" +msgstr "Általános hiba" + +#: cps/admin.py:1773 +msgid "Update file could not be saved in temp dir" +msgstr "" + +#: cps/admin.py:1774 +msgid "Files could not be replaced during update" +msgstr "" + +#: cps/admin.py:1798 +msgid "Failed to extract at least One LDAP User" +msgstr "" + +#: cps/admin.py:1843 +msgid "Failed to Create at Least One LDAP User" +msgstr "" + +#: cps/admin.py:1856 +#, python-format +msgid "Error: %(ldaperror)s" +msgstr "" + +#: cps/admin.py:1860 +msgid "Error: No user returned in response of LDAP server" +msgstr "" + +#: cps/admin.py:1893 +msgid "At Least One LDAP User Not Found in Database" +msgstr "" + +#: cps/admin.py:1895 +msgid "{} User Successfully Imported" +msgstr "" + +#: cps/converter.py:30 +msgid "not installed" +msgstr "nincs telepítve" + +#: cps/converter.py:31 +msgid "Execution permissions missing" +msgstr "" + +#: cps/db.py:674 cps/web.py:710 cps/web.py:1222 +#, python-format +msgid "Custom Column No.%(column)d is not existing in calibre database" +msgstr "" + +#: cps/db.py:917 cps/templates/config_edit.html:204 +#: cps/templates/config_view_edit.html:62 cps/templates/email_edit.html:41 +#: cps/web.py:551 cps/web.py:585 cps/web.py:646 cps/web.py:671 cps/web.py:1003 +#: cps/web.py:1032 cps/web.py:1066 cps/web.py:1093 cps/web.py:1132 +msgid "None" +msgstr "Nincs" + +#: cps/editbooks.py:295 cps/editbooks.py:297 +msgid "Book Format Successfully Deleted" +msgstr "" + +#: cps/editbooks.py:304 cps/editbooks.py:306 +msgid "Book Successfully Deleted" +msgstr "" + +#: cps/editbooks.py:358 +msgid "You are missing permissions to delete books" +msgstr "" + +#: cps/editbooks.py:373 cps/editbooks.py:765 cps/web.py:518 cps/web.py:1783 +#: cps/web.py:1825 cps/web.py:1870 +msgid "Oops! Selected book title is unavailable. File does not exist or is not accessible" +msgstr "Hiba történt az e-könyv megnyitásakor. A fájl nem létezik vagy nem érhető el:" + +#: cps/editbooks.py:408 +msgid "edit metadata" +msgstr "Metaadatok szerkesztése" + +#: cps/editbooks.py:457 +#, python-format +msgid "%(seriesindex)s is not a valid number, skipping" +msgstr "" + +#: cps/editbooks.py:493 cps/editbooks.py:1001 +#, fuzzy, python-format +msgid "'%(langname)s' is not a valid language" +msgstr "A(z) %(langname)s nem érvényes nyelv" + +#: cps/editbooks.py:634 +msgid "User has no rights to upload additional file formats" +msgstr "" + +#: cps/editbooks.py:639 cps/editbooks.py:1029 +#, python-format +msgid "File extension '%(ext)s' is not allowed to be uploaded to this server" +msgstr "A(z) \"%(ext)s\" kiterjesztésű fájlok feltöltése nincs engedélyezve ezen a szerveren." + +#: cps/editbooks.py:643 cps/editbooks.py:1033 +msgid "File to be uploaded must have an extension" +msgstr "A feltöltendő fájlnak kiterjesztéssel kell rendelkeznie!" + +#: cps/editbooks.py:655 +#, python-format +msgid "Failed to create path %(path)s (Permission denied)." +msgstr "Nem sikerült létrehozni az elérési utat (engedély megtagadva): %(path)s." + +#: cps/editbooks.py:660 +#, python-format +msgid "Failed to store file %(file)s." +msgstr "Nem sikerült elmenteni a %(file)s fájlt." + +#: cps/editbooks.py:683 #, python-format msgid "File format %(ext)s added to %(book)s" msgstr "A(z) %(ext)s fájlformátum hozzáadva a könyvhez: %(book)s." -#: cps/editbooks.py:814 +#: cps/editbooks.py:697 cps/editbooks.py:809 +msgid "User has no rights to upload cover" +msgstr "" + +#: cps/editbooks.py:828 msgid "Identifiers are not Case Sensitive, Overwriting Old Identifier" msgstr "" -#: cps/editbooks.py:848 +#: cps/editbooks.py:869 msgid "Metadata successfully updated" msgstr "A metaadatok sikeresen frissültek" -#: cps/editbooks.py:861 -msgid "Error editing book, please check logfile for details" -msgstr "Hiba a könyv szerkesztése során, további részletek a naplófájlban." +#: cps/editbooks.py:887 +msgid "Error editing book: {}" +msgstr "" -#: cps/editbooks.py:899 +#: cps/editbooks.py:951 msgid "Uploaded book probably exists in the library, consider to change before upload new: " msgstr "" -#: cps/editbooks.py:997 +#: cps/editbooks.py:1041 #, python-format msgid "File %(filename)s could not saved to temp dir" msgstr "" -#: cps/editbooks.py:1016 +#: cps/editbooks.py:1061 #, python-format msgid "Failed to Move Cover File %(file)s: %(error)s" msgstr "" -#: cps/editbooks.py:1063 +#: cps/editbooks.py:1117 #, python-format msgid "File %(file)s uploaded" msgstr "" -#: cps/editbooks.py:1088 +#: cps/editbooks.py:1143 msgid "Source or destination format for conversion missing" msgstr "Az átalakításhoz hiányzik a forrás- vagy a célformátum!" -#: cps/editbooks.py:1096 +#: cps/editbooks.py:1151 #, python-format msgid "Book successfully queued for converting to %(book_format)s" msgstr "A könyv sikeresen átalakításra lett jelölve a következő formátumra: %(book_format)s" -#: cps/editbooks.py:1100 +#: cps/editbooks.py:1155 #, python-format msgid "There was an error converting this book: %(res)s" msgstr "Hiba történt a könyv átalakításakor: %(res)s" @@ -608,175 +611,191 @@ msgstr "A Google Drive beállítása nem fejeződött be, próbáld kikapcsolni msgid "Callback domain is not verified, please follow steps to verify domain in google developer console" msgstr "A visszahívási tartomány nem ellenőrzött, kövesd az alábbi lépéseket a tartomány ellenőrzéséhez a Google Developer Console-ban:" -#: cps/helper.py:77 +#: cps/helper.py:81 #, python-format msgid "%(format)s format not found for book id: %(book)d" msgstr "A(z) %(format)s formátum nem található a következő könyvhöz: %(book)d" -#: cps/helper.py:83 cps/tasks/convert.py:73 +#: cps/helper.py:87 cps/tasks/convert.py:75 #, python-format msgid "%(format)s not found on Google Drive: %(fn)s" msgstr "%(format)s nem található a Google Drive-on: %(fn)s" -#: cps/helper.py:88 +#: cps/helper.py:92 #, python-format msgid "%(format)s not found: %(fn)s" msgstr "%(format)s nem található: %(fn)s" -#: cps/helper.py:93 cps/helper.py:217 cps/templates/detail.html:41 +#: cps/helper.py:97 cps/helper.py:221 cps/templates/detail.html:41 #: cps/templates/detail.html:45 msgid "Send to Kindle" msgstr "Küldés Kindle-re" -#: cps/helper.py:94 cps/helper.py:111 cps/helper.py:219 +#: cps/helper.py:98 cps/helper.py:115 cps/helper.py:223 msgid "This e-mail has been sent via Calibre-Web." msgstr "Ez az e-mail a Calibre-Web-en keresztül lett küldve." -#: cps/helper.py:109 +#: cps/helper.py:113 msgid "Calibre-Web test e-mail" msgstr "Calibre-Web teszt e-mail" -#: cps/helper.py:110 +#: cps/helper.py:114 msgid "Test e-mail" msgstr "Teszt e-mail" -#: cps/helper.py:127 +#: cps/helper.py:131 msgid "Get Started with Calibre-Web" msgstr "Kezdő lépések a Calibre-Web-bel" -#: cps/helper.py:132 +#: cps/helper.py:136 #, python-format msgid "Registration e-mail for user: %(name)s" msgstr "Regisztrációs e-mail a következő felhasználóhoz: %(name)s" -#: cps/helper.py:143 cps/helper.py:149 +#: cps/helper.py:147 cps/helper.py:153 #, python-format msgid "Convert %(orig)s to %(format)s and send to Kindle" msgstr "%(orig)s konvertálása %(format)s-ra és küldés Kindle-re" -#: cps/helper.py:168 cps/helper.py:172 cps/helper.py:176 +#: cps/helper.py:172 cps/helper.py:176 cps/helper.py:180 #, python-format msgid "Send %(format)s to Kindle" msgstr "%(format)s küldése Kindle-re" -#: cps/helper.py:216 cps/tasks/convert.py:90 +#: cps/helper.py:220 cps/tasks/convert.py:92 #, fuzzy, python-format msgid "%(book)s send to Kindle" msgstr "Küldés Kindle-re" -#: cps/helper.py:221 +#: cps/helper.py:225 msgid "The requested file could not be read. Maybe wrong permissions?" msgstr "A kért fájl nem olvasható. Esetleg jogosultsági probléma lenne?" -#: cps/helper.py:313 +#: cps/helper.py:353 +msgid "Read status could not set: {}" +msgstr "" + +#: cps/helper.py:376 #, python-format msgid "Deleting bookfolder for book %(id)s failed, path has subfolders: %(path)s" msgstr "" -#: cps/helper.py:319 +#: cps/helper.py:382 #, python-format msgid "Deleting book %(id)s failed: %(message)s" msgstr "" -#: cps/helper.py:330 +#: cps/helper.py:393 #, python-format msgid "Deleting book %(id)s from database only, book path in database not valid: %(path)s" msgstr "" -#: cps/helper.py:385 -#, python-format -msgid "Rename title from: '%(src)s' to '%(dest)s' failed with error: %(error)s" +#: cps/helper.py:458 +#, fuzzy, python-format +msgid "Rename author from: '%(src)s' to '%(dest)s' failed with error: %(error)s" msgstr "A cím átnevezése \"%(src)s\"-ról \"%(dest)s\"-ra nem sikerült a következő hiba miatt: %(error)s" -#: cps/helper.py:400 -#, python-format -msgid "Rename file in path '%(src)s' to '%(dest)s' failed with error: %(error)s" -msgstr "\"%(src)s\" fájl átnevezése \"%(dest)s\"-re nem sikerült a következő hiba miatt: %(error)s" - -#: cps/helper.py:425 cps/helper.py:435 cps/helper.py:443 +#: cps/helper.py:529 cps/helper.py:538 #, python-format msgid "File %(file)s not found on Google Drive" msgstr "A \"%(file)s\" fájl nem található a Google Drive-on" -#: cps/helper.py:464 +#: cps/helper.py:572 +#, python-format +msgid "Rename title from: '%(src)s' to '%(dest)s' failed with error: %(error)s" +msgstr "A cím átnevezése \"%(src)s\"-ról \"%(dest)s\"-ra nem sikerült a következő hiba miatt: %(error)s" + +#: cps/helper.py:592 +msgid "Error in rename file in path: {}" +msgstr "" + +#: cps/helper.py:610 #, python-format msgid "Book path %(path)s not found on Google Drive" msgstr "A könyv elérési útja (\"%(path)s\") nem található a Google Drive-on" -#: cps/helper.py:504 cps/web.py:1659 +#: cps/helper.py:651 cps/web.py:1737 #, fuzzy msgid "Found an existing account for this e-mail address" msgstr "Már létezik felhasználó ehhez az e-mail címhez." -#: cps/helper.py:512 +#: cps/helper.py:659 msgid "This username is already taken" msgstr "" -#: cps/helper.py:522 +#: cps/helper.py:669 msgid "Invalid e-mail address format" msgstr "" -#: cps/helper.py:595 +#: cps/helper.py:754 +msgid "Python modul 'advocate' is not installed but is needed for cover downloads" +msgstr "" + +#: cps/helper.py:767 msgid "Error Downloading Cover" msgstr "" -#: cps/helper.py:598 +#: cps/helper.py:770 msgid "Cover Format Error" msgstr "" -#: cps/helper.py:608 +#: cps/helper.py:773 +msgid "You are not allowed to access localhost or the local network for cover uploads" +msgstr "" + +#: cps/helper.py:783 msgid "Failed to create path for cover" msgstr "" -#: cps/helper.py:624 +#: cps/helper.py:799 msgid "Cover-file is not a valid image file, or could not be stored" msgstr "" -#: cps/helper.py:635 +#: cps/helper.py:810 msgid "Only jpg/jpeg/png/webp/bmp files are supported as coverfile" msgstr "" -#: cps/helper.py:648 +#: cps/helper.py:822 msgid "Invalid cover file content" msgstr "" -#: cps/helper.py:652 +#: cps/helper.py:826 msgid "Only jpg/jpeg files are supported as coverfile" msgstr "" -#: cps/helper.py:704 +#: cps/helper.py:878 msgid "Unrar binary file not found" msgstr "" -#: cps/helper.py:715 +#: cps/helper.py:889 msgid "Error excecuting UnRar" msgstr "" -#: cps/helper.py:763 +#: cps/helper.py:937 msgid "Waiting" msgstr "Várakozás" -#: cps/helper.py:765 +#: cps/helper.py:939 msgid "Failed" msgstr "Nem sikerült" -#: cps/helper.py:767 +#: cps/helper.py:941 msgid "Started" msgstr "Elindítva" -#: cps/helper.py:769 +#: cps/helper.py:943 msgid "Finished" msgstr "Végrehajtva" -#: cps/helper.py:771 +#: cps/helper.py:945 msgid "Unknown Status" msgstr "Ismeretlen állapot" -#: cps/kobo_auth.py:127 -msgid "PLease access calibre-web from non localhost to get valid api_endpoint for kobo device" +#: cps/kobo_auth.py:128 +msgid "Please access Calibre-Web from non localhost to get valid api_endpoint for kobo device" msgstr "" -#: cps/kobo_auth.py:130 cps/kobo_auth.py:158 +#: cps/kobo_auth.py:154 msgid "Kobo Setup" msgstr "" @@ -785,7 +804,7 @@ msgstr "" msgid "Register with %(provider)s" msgstr "" -#: cps/oauth_bb.py:138 cps/remotelogin.py:133 cps/web.py:1535 +#: cps/oauth_bb.py:138 cps/remotelogin.py:130 cps/web.py:1613 #, python-format msgid "you are now logged in as: '%(nickname)s'" msgstr "Be vagy jelentkezve mint: %(nickname)s" @@ -846,163 +865,163 @@ msgstr "" msgid "Google Oauth error: {}" msgstr "" -#: cps/opds.py:384 +#: cps/opds.py:298 msgid "{} Stars" msgstr "" -#: cps/remotelogin.py:65 cps/templates/layout.html:84 -#: cps/templates/login.html:4 cps/templates/login.html:21 cps/web.py:1584 +#: cps/remotelogin.py:62 cps/templates/layout.html:84 +#: cps/templates/login.html:4 cps/templates/login.html:21 cps/web.py:1662 msgid "Login" msgstr "Belépés" -#: cps/remotelogin.py:77 cps/remotelogin.py:111 +#: cps/remotelogin.py:74 cps/remotelogin.py:108 msgid "Token not found" msgstr "A token nem található." -#: cps/remotelogin.py:86 cps/remotelogin.py:119 +#: cps/remotelogin.py:83 cps/remotelogin.py:116 msgid "Token has expired" msgstr "A token érvényessége lejárt." -#: cps/remotelogin.py:95 +#: cps/remotelogin.py:92 msgid "Success! Please return to your device" msgstr "Sikerült! Újra használható az eszköz." -#: cps/render_template.py:39 cps/web.py:416 +#: cps/render_template.py:41 cps/web.py:407 msgid "Books" msgstr "" -#: cps/render_template.py:41 +#: cps/render_template.py:43 msgid "Show recent books" msgstr "Legutóbbi könyvek mutatása" -#: cps/render_template.py:42 cps/templates/index.xml:25 +#: cps/render_template.py:44 cps/templates/index.xml:25 msgid "Hot Books" msgstr "Kelendő könyvek" -#: cps/render_template.py:44 +#: cps/render_template.py:46 msgid "Show Hot Books" msgstr "Kelendő könyvek mutatása" -#: cps/render_template.py:46 cps/render_template.py:51 +#: cps/render_template.py:48 cps/render_template.py:53 msgid "Downloaded Books" msgstr "" -#: cps/render_template.py:48 cps/render_template.py:53 +#: cps/render_template.py:50 cps/render_template.py:55 #: cps/templates/user_table.html:167 msgid "Show Downloaded Books" msgstr "" -#: cps/render_template.py:56 cps/templates/index.xml:32 cps/web.py:430 +#: cps/render_template.py:58 cps/templates/index.xml:32 cps/web.py:422 msgid "Top Rated Books" msgstr "Legjobb könyvek" -#: cps/render_template.py:58 cps/templates/user_table.html:161 +#: cps/render_template.py:60 cps/templates/user_table.html:161 msgid "Show Top Rated Books" msgstr "Legjobbra értékelt könyvek mutatása" -#: cps/render_template.py:59 cps/templates/index.xml:54 -#: cps/templates/index.xml:58 cps/web.py:676 +#: cps/render_template.py:61 cps/templates/index.xml:54 +#: cps/templates/index.xml:58 cps/web.py:729 msgid "Read Books" msgstr "Olvasott könyvek" -#: cps/render_template.py:61 +#: cps/render_template.py:63 msgid "Show read and unread" msgstr "Mutassa az olvasva/olvasatlan állapotot" -#: cps/render_template.py:63 cps/templates/index.xml:61 -#: cps/templates/index.xml:65 cps/web.py:679 +#: cps/render_template.py:65 cps/templates/index.xml:61 +#: cps/templates/index.xml:65 cps/web.py:732 msgid "Unread Books" msgstr "Olvasatlan könyvek" -#: cps/render_template.py:65 +#: cps/render_template.py:67 msgid "Show unread" msgstr "" -#: cps/render_template.py:66 +#: cps/render_template.py:68 msgid "Discover" msgstr "Felfedezés" -#: cps/render_template.py:68 cps/templates/index.xml:50 +#: cps/render_template.py:70 cps/templates/index.xml:50 #: cps/templates/user_table.html:162 msgid "Show Random Books" msgstr "Mutass könyveket találomra" -#: cps/render_template.py:69 cps/templates/book_table.html:67 -#: cps/templates/index.xml:83 cps/web.py:1041 +#: cps/render_template.py:71 cps/templates/book_table.html:67 +#: cps/templates/index.xml:83 cps/web.py:1135 msgid "Categories" msgstr "Címkék" -#: cps/render_template.py:71 cps/templates/user_table.html:158 +#: cps/render_template.py:73 cps/templates/user_table.html:158 msgid "Show category selection" msgstr "Címke választó mutatása" -#: cps/render_template.py:72 cps/templates/book_edit.html:90 +#: cps/render_template.py:74 cps/templates/book_edit.html:90 #: cps/templates/book_table.html:68 cps/templates/index.xml:90 -#: cps/templates/search_form.html:69 cps/web.py:948 cps/web.py:959 +#: cps/templates/search_form.html:69 cps/web.py:1034 cps/web.py:1041 msgid "Series" msgstr "Sorozatok" -#: cps/render_template.py:74 cps/templates/user_table.html:157 +#: cps/render_template.py:76 cps/templates/user_table.html:157 msgid "Show series selection" msgstr "Sorozat választó mutatása" -#: cps/render_template.py:75 cps/templates/book_table.html:66 +#: cps/render_template.py:77 cps/templates/book_table.html:66 #: cps/templates/index.xml:69 msgid "Authors" msgstr "Szerzők" -#: cps/render_template.py:77 cps/templates/user_table.html:160 +#: cps/render_template.py:79 cps/templates/user_table.html:160 msgid "Show author selection" msgstr "Szerző választó mutatása" -#: cps/render_template.py:79 cps/templates/book_table.html:72 -#: cps/templates/index.xml:76 cps/web.py:925 +#: cps/render_template.py:81 cps/templates/book_table.html:72 +#: cps/templates/index.xml:76 cps/web.py:1006 msgid "Publishers" msgstr "Kiadók" -#: cps/render_template.py:81 cps/templates/user_table.html:163 +#: cps/render_template.py:83 cps/templates/user_table.html:163 msgid "Show publisher selection" msgstr "Kiadó választó mutatása" -#: cps/render_template.py:82 cps/templates/book_table.html:70 +#: cps/render_template.py:84 cps/templates/book_table.html:70 #: cps/templates/index.xml:97 cps/templates/search_form.html:107 -#: cps/web.py:1018 +#: cps/web.py:1108 msgid "Languages" msgstr "Nyelvek" -#: cps/render_template.py:85 cps/templates/user_table.html:155 +#: cps/render_template.py:87 cps/templates/user_table.html:155 msgid "Show language selection" msgstr "Nyelv választó mutatása" -#: cps/render_template.py:86 cps/templates/index.xml:104 +#: cps/render_template.py:88 cps/templates/index.xml:104 msgid "Ratings" msgstr "" -#: cps/render_template.py:88 cps/templates/user_table.html:164 +#: cps/render_template.py:90 cps/templates/user_table.html:164 msgid "Show ratings selection" msgstr "" -#: cps/render_template.py:89 cps/templates/index.xml:112 +#: cps/render_template.py:91 cps/templates/index.xml:112 msgid "File formats" msgstr "" -#: cps/render_template.py:91 cps/templates/user_table.html:165 +#: cps/render_template.py:93 cps/templates/user_table.html:165 msgid "Show file formats selection" msgstr "" -#: cps/render_template.py:93 cps/web.py:703 +#: cps/render_template.py:95 cps/web.py:755 msgid "Archived Books" msgstr "" -#: cps/render_template.py:95 cps/templates/user_table.html:166 +#: cps/render_template.py:97 cps/templates/user_table.html:166 msgid "Show archived books" msgstr "" -#: cps/render_template.py:97 cps/web.py:780 +#: cps/render_template.py:100 cps/web.py:837 msgid "Books List" msgstr "" -#: cps/render_template.py:99 cps/templates/user_table.html:168 +#: cps/render_template.py:102 cps/templates/user_table.html:168 msgid "Show Books List" msgstr "" @@ -1057,262 +1076,266 @@ msgstr "" msgid "Create a Shelf" msgstr "Polc készítése" -#: cps/shelf.py:237 +#: cps/shelf.py:236 #, fuzzy msgid "Sorry you are not allowed to edit this shelf" msgstr "Sajnálom, nincs jogosultságot eltávolítani könyvet erről a polcról: %(sname)s" -#: cps/shelf.py:239 +#: cps/shelf.py:238 msgid "Edit a shelf" msgstr "Polc szerkesztése" -#: cps/shelf.py:249 +#: cps/shelf.py:248 msgid "Sorry you are not allowed to create a public shelf" msgstr "" -#: cps/shelf.py:266 +#: cps/shelf.py:265 #, python-format msgid "Shelf %(title)s created" msgstr "A következő polc létre lett hozva: %(title)s" -#: cps/shelf.py:269 +#: cps/shelf.py:268 #, python-format msgid "Shelf %(title)s changed" msgstr "A következő polc megváltoztatva: %(title)s" -#: cps/shelf.py:283 +#: cps/shelf.py:282 msgid "There was an error" msgstr "Hiba történt" -#: cps/shelf.py:305 +#: cps/shelf.py:304 #, python-format msgid "A public shelf with the name '%(title)s' already exists." msgstr "" -#: cps/shelf.py:316 +#: cps/shelf.py:315 #, python-format msgid "A private shelf with the name '%(title)s' already exists." msgstr "" #: cps/shelf.py:337 +msgid "Error deleting Shelf" +msgstr "" + +#: cps/shelf.py:339 #, fuzzy msgid "Shelf successfully deleted" msgstr "A metaadatok sikeresen frissültek" -#: cps/shelf.py:386 +#: cps/shelf.py:389 #, python-format msgid "Change order of Shelf: '%(name)s'" msgstr "A következő polc átrendezése: %(name)s" -#: cps/shelf.py:456 +#: cps/shelf.py:461 #, python-format msgid "Shelf: '%(name)s'" msgstr "Polc: '%(name)s'" -#: cps/shelf.py:460 +#: cps/shelf.py:465 msgid "Error opening shelf. Shelf does not exist or is not accessible" msgstr "Hiba a polc megnyitásakor. A polc nem létezik vagy nem elérhető." -#: cps/updater.py:403 cps/updater.py:414 cps/updater.py:514 cps/updater.py:529 +#: cps/updater.py:426 cps/updater.py:437 cps/updater.py:538 cps/updater.py:553 msgid "Unexpected data while reading update information" msgstr "Ismeretlen adat a frissítési információk olvasásakor" -#: cps/updater.py:410 cps/updater.py:521 +#: cps/updater.py:433 cps/updater.py:545 msgid "No update available. You already have the latest version installed" msgstr "Nem érhető el újabb frissítés. Már a legújabb verzió van telepítve." -#: cps/updater.py:428 +#: cps/updater.py:451 msgid "A new update is available. Click on the button below to update to the latest version." msgstr "Egy új frissítés érhető el. Kattints a lenti gombra a legújabb verzió frissítésére" -#: cps/updater.py:446 +#: cps/updater.py:469 msgid "Could not fetch update information" msgstr "Nem lehetett begyűjteni a frissítési információkat" -#: cps/updater.py:456 +#: cps/updater.py:479 msgid "Click on the button below to update to the latest stable version." msgstr "" -#: cps/updater.py:465 cps/updater.py:479 cps/updater.py:490 +#: cps/updater.py:488 cps/updater.py:502 cps/updater.py:513 #, python-format msgid "A new update is available. Click on the button below to update to version: %(version)s" msgstr "Új frissítés érhető el. Kattints az alábbi gombra a frissítéshez a következő verzióra: %(version)s" -#: cps/updater.py:507 +#: cps/updater.py:531 msgid "No release information available" msgstr "Nincs információ a kiadásról." -#: cps/templates/index.html:5 cps/web.py:440 +#: cps/templates/index.html:5 cps/web.py:434 msgid "Discover (Random Books)" msgstr "Felfedezés (könyvek találomra)" -#: cps/web.py:471 +#: cps/web.py:470 msgid "Hot Books (Most Downloaded)" msgstr "Kelendő könyvek (legtöbbet letöltöttek)" -#: cps/web.py:507 +#: cps/web.py:501 #, python-format msgid "Downloaded books by %(user)s" msgstr "" -#: cps/web.py:539 +#: cps/web.py:534 #, python-format msgid "Author: %(name)s" msgstr "" -#: cps/web.py:554 +#: cps/web.py:570 #, python-format msgid "Publisher: %(name)s" msgstr "Kiadó: %(name)s" -#: cps/web.py:569 +#: cps/web.py:598 #, python-format msgid "Series: %(serie)s" msgstr "Sorozat: %(serie)s" -#: cps/web.py:582 +#: cps/web.py:610 #, python-format msgid "Rating: %(rating)s stars" msgstr "" -#: cps/web.py:597 +#: cps/web.py:626 #, python-format msgid "File format: %(format)s" msgstr "" -#: cps/web.py:615 +#: cps/web.py:663 #, python-format msgid "Category: %(name)s" msgstr "Címke: %(name)s" -#: cps/web.py:631 +#: cps/web.py:690 #, python-format msgid "Language: %(name)s" msgstr "Nyelv: %(name)s" -#: cps/templates/layout.html:56 cps/web.py:737 cps/web.py:1371 +#: cps/templates/layout.html:56 cps/web.py:789 cps/web.py:1444 msgid "Advanced Search" msgstr "Részletes keresés" #: cps/templates/book_edit.html:235 cps/templates/feed.xml:33 #: cps/templates/index.xml:11 cps/templates/layout.html:45 #: cps/templates/layout.html:48 cps/templates/search_form.html:226 -#: cps/web.py:750 cps/web.py:1077 +#: cps/web.py:807 cps/web.py:1164 msgid "Search" msgstr "Keresés" -#: cps/templates/admin.html:16 cps/web.py:903 +#: cps/templates/admin.html:16 cps/web.py:979 msgid "Downloads" msgstr "Letöltések" -#: cps/web.py:980 +#: cps/web.py:1068 msgid "Ratings list" msgstr "" -#: cps/web.py:1001 +#: cps/web.py:1095 msgid "File formats list" msgstr "" -#: cps/templates/layout.html:73 cps/templates/tasks.html:7 cps/web.py:1055 +#: cps/templates/layout.html:73 cps/templates/tasks.html:7 cps/web.py:1149 msgid "Tasks" msgstr "Feladatok" -#: cps/web.py:1215 +#: cps/web.py:1286 msgid "Published after " msgstr "Kiadva ezután: " -#: cps/web.py:1222 +#: cps/web.py:1293 msgid "Published before " msgstr "Kiadva ezelőtt: " -#: cps/web.py:1244 +#: cps/web.py:1315 #, python-format msgid "Rating <= %(rating)s" msgstr "Értékelés <= %(rating)s" -#: cps/web.py:1246 +#: cps/web.py:1317 #, python-format msgid "Rating >= %(rating)s" msgstr "Értékelés <= %(rating)s" -#: cps/web.py:1248 +#: cps/web.py:1319 #, python-format msgid "Read Status = %(status)s" msgstr "" -#: cps/web.py:1353 +#: cps/web.py:1425 msgid "Error on search for custom columns, please restart Calibre-Web" msgstr "" -#: cps/web.py:1449 +#: cps/web.py:1527 #, python-format msgid "Book successfully queued for sending to %(kindlemail)s" msgstr "A könyv sikeresen küldésre lett jelölve a következő címre: %(kindlemail)s" -#: cps/web.py:1453 +#: cps/web.py:1531 #, python-format msgid "Oops! There was an error sending this book: %(res)s" msgstr "Hiba történt a könyv küldésekor: %(res)s" -#: cps/web.py:1455 +#: cps/web.py:1533 msgid "Please update your profile with a valid Send to Kindle E-mail Address." msgstr "Először be kell állítani a kindle e-mail címet..." -#: cps/web.py:1472 +#: cps/web.py:1550 msgid "E-Mail server is not configured, please contact your administrator!" msgstr "" -#: cps/templates/layout.html:85 cps/templates/register.html:17 cps/web.py:1473 -#: cps/web.py:1480 cps/web.py:1486 cps/web.py:1505 cps/web.py:1509 -#: cps/web.py:1515 +#: cps/templates/layout.html:85 cps/templates/register.html:17 cps/web.py:1551 +#: cps/web.py:1558 cps/web.py:1564 cps/web.py:1583 cps/web.py:1587 +#: cps/web.py:1593 msgid "Register" msgstr "Regisztrálás" -#: cps/web.py:1507 +#: cps/web.py:1585 msgid "Your e-mail is not allowed to register" msgstr "Nem engedélyezett a megadott e-mail cím bejegyzése" -#: cps/web.py:1510 +#: cps/web.py:1588 msgid "Confirmation e-mail was send to your e-mail account." msgstr "Jóváhagyó levél elküldve az email címedre." -#: cps/web.py:1524 +#: cps/web.py:1602 msgid "Cannot activate LDAP authentication" msgstr "" -#: cps/web.py:1543 +#: cps/web.py:1621 #, python-format msgid "Fallback Login as: '%(nickname)s', LDAP Server not reachable, or user not known" msgstr "" -#: cps/web.py:1549 +#: cps/web.py:1627 #, python-format msgid "Could not login: %(message)s" msgstr "" -#: cps/web.py:1553 cps/web.py:1578 +#: cps/web.py:1631 cps/web.py:1656 msgid "Wrong Username or Password" msgstr "Rossz felhasználó név vagy jelszó!" -#: cps/web.py:1560 +#: cps/web.py:1638 msgid "New Password was send to your email address" msgstr "" -#: cps/web.py:1566 +#: cps/web.py:1644 msgid "Please enter valid username to reset password" msgstr "" -#: cps/web.py:1573 +#: cps/web.py:1651 #, python-format msgid "You are now logged in as: '%(nickname)s'" msgstr "" -#: cps/web.py:1639 cps/web.py:1688 +#: cps/web.py:1717 cps/web.py:1766 #, python-format msgid "%(name)s's profile" msgstr "%(name)s profilja" -#: cps/web.py:1655 +#: cps/web.py:1733 msgid "Profile updated" msgstr "A profil frissítve." @@ -1320,36 +1343,36 @@ msgstr "A profil frissítve." msgid "Found no valid gmail.json file with OAuth information" msgstr "" -#: cps/tasks/convert.py:137 +#: cps/tasks/convert.py:154 #, python-format msgid "Calibre ebook-convert %(tool)s not found" msgstr "" -#: cps/tasks/convert.py:163 +#: cps/tasks/convert.py:187 #, python-format msgid "%(format)s format not found on disk" msgstr "" -#: cps/tasks/convert.py:167 +#: cps/tasks/convert.py:191 msgid "Ebook converter failed with unknown error" msgstr "" -#: cps/tasks/convert.py:177 +#: cps/tasks/convert.py:201 #, python-format msgid "Kepubify-converter failed: %(error)s" msgstr "" -#: cps/tasks/convert.py:199 +#: cps/tasks/convert.py:223 #, python-format msgid "Converted file not found or more than one file in folder %(folder)s" msgstr "" -#: cps/tasks/convert.py:222 +#: cps/tasks/convert.py:246 #, python-format msgid "Ebook-converter failed: %(error)s" msgstr "Az e-könyv átalakítás nem sikerült: %(error)s" -#: cps/tasks/convert.py:245 +#: cps/tasks/convert.py:269 #, python-format msgid "Calibre failed with error: %(error)s" msgstr "" @@ -1404,7 +1427,7 @@ msgid "Edit" msgstr "Szerkesztés" #: cps/templates/admin.html:25 cps/templates/book_edit.html:16 -#: cps/templates/book_table.html:97 cps/templates/modal_dialogs.html:63 +#: cps/templates/book_table.html:100 cps/templates/modal_dialogs.html:63 #: cps/templates/modal_dialogs.html:116 cps/templates/user_edit.html:67 #: cps/templates/user_table.html:149 msgid "Delete" @@ -1414,180 +1437,180 @@ msgstr "Törlés" msgid "Public Shelf" msgstr "" -#: cps/templates/admin.html:51 +#: cps/templates/admin.html:53 msgid "Add New User" msgstr "" -#: cps/templates/admin.html:53 +#: cps/templates/admin.html:55 msgid "Import LDAP Users" msgstr "" -#: cps/templates/admin.html:60 +#: cps/templates/admin.html:62 msgid "E-mail Server Settings" msgstr "SMTP e-mail kiszolgáló beállítások" -#: cps/templates/admin.html:65 cps/templates/email_edit.html:31 +#: cps/templates/admin.html:67 cps/templates/email_edit.html:31 msgid "SMTP Hostname" msgstr "SMTP szervernév" -#: cps/templates/admin.html:69 cps/templates/email_edit.html:35 +#: cps/templates/admin.html:71 cps/templates/email_edit.html:35 msgid "SMTP Port" msgstr "SMTP port" -#: cps/templates/admin.html:73 cps/templates/email_edit.html:39 +#: cps/templates/admin.html:75 cps/templates/email_edit.html:39 msgid "Encryption" msgstr "SSL" -#: cps/templates/admin.html:77 cps/templates/email_edit.html:47 +#: cps/templates/admin.html:79 cps/templates/email_edit.html:47 msgid "SMTP Login" msgstr "SMTP felhasználó" -#: cps/templates/admin.html:81 cps/templates/admin.html:92 +#: cps/templates/admin.html:83 cps/templates/admin.html:94 #: cps/templates/email_edit.html:55 msgid "From E-mail" msgstr "Küldő e-mail cím" -#: cps/templates/admin.html:88 +#: cps/templates/admin.html:90 msgid "E-Mail Service" msgstr "" -#: cps/templates/admin.html:89 +#: cps/templates/admin.html:91 msgid "Gmail via Oauth2" msgstr "" -#: cps/templates/admin.html:104 +#: cps/templates/admin.html:106 msgid "Configuration" msgstr "Konfiguráció" -#: cps/templates/admin.html:107 +#: cps/templates/admin.html:109 msgid "Calibre Database Directory" msgstr "Calibre adatbázis mappája:" -#: cps/templates/admin.html:111 cps/templates/config_edit.html:68 +#: cps/templates/admin.html:113 cps/templates/config_edit.html:68 msgid "Log Level" msgstr "Naplózás szintje:" -#: cps/templates/admin.html:115 +#: cps/templates/admin.html:117 msgid "Port" msgstr "Port:" -#: cps/templates/admin.html:120 +#: cps/templates/admin.html:122 msgid "External Port" msgstr "" -#: cps/templates/admin.html:127 cps/templates/config_view_edit.html:28 +#: cps/templates/admin.html:129 cps/templates/config_view_edit.html:28 msgid "Books per Page" msgstr "Könyvek oldalanként:" -#: cps/templates/admin.html:131 +#: cps/templates/admin.html:133 msgid "Uploads" msgstr "Feltöltés:" -#: cps/templates/admin.html:135 +#: cps/templates/admin.html:137 msgid "Anonymous Browsing" msgstr "Böngészés bejelentkezés nélkül:" -#: cps/templates/admin.html:139 +#: cps/templates/admin.html:141 msgid "Public Registration" msgstr "Nyílvános regisztráció:" -#: cps/templates/admin.html:143 +#: cps/templates/admin.html:145 msgid "Magic Link Remote Login" msgstr "Távoli belépés:" -#: cps/templates/admin.html:147 +#: cps/templates/admin.html:149 msgid "Reverse Proxy Login" msgstr "" -#: cps/templates/admin.html:152 cps/templates/config_edit.html:173 +#: cps/templates/admin.html:154 cps/templates/config_edit.html:173 msgid "Reverse Proxy Header Name" msgstr "" -#: cps/templates/admin.html:157 +#: cps/templates/admin.html:159 #, fuzzy msgid "Edit Calibre Database Configuration" msgstr "Calibre adatbázis mappája:" -#: cps/templates/admin.html:158 +#: cps/templates/admin.html:160 msgid "Edit Basic Configuration" msgstr "" -#: cps/templates/admin.html:159 +#: cps/templates/admin.html:161 msgid "Edit UI Configuration" msgstr "" -#: cps/templates/admin.html:164 +#: cps/templates/admin.html:166 msgid "Administration" msgstr "Adminisztráció" -#: cps/templates/admin.html:165 +#: cps/templates/admin.html:167 msgid "Download Debug Package" msgstr "" -#: cps/templates/admin.html:166 +#: cps/templates/admin.html:168 msgid "View Logs" msgstr "" -#: cps/templates/admin.html:169 +#: cps/templates/admin.html:171 msgid "Reconnect Calibre Database" msgstr "Újracsatlakozás a Calibre adatbázishoz" -#: cps/templates/admin.html:170 +#: cps/templates/admin.html:172 msgid "Restart" msgstr "A Calibre adatbázis újraindítása" -#: cps/templates/admin.html:171 +#: cps/templates/admin.html:173 msgid "Shutdown" msgstr "A Calibre adatbázis leállítása" -#: cps/templates/admin.html:176 +#: cps/templates/admin.html:178 msgid "Update" msgstr "Frissítés" -#: cps/templates/admin.html:180 +#: cps/templates/admin.html:182 msgid "Version" msgstr "Verzió" -#: cps/templates/admin.html:181 +#: cps/templates/admin.html:183 msgid "Details" msgstr "Részletek" -#: cps/templates/admin.html:187 +#: cps/templates/admin.html:189 msgid "Current version" msgstr "Jelenlegi verzió" -#: cps/templates/admin.html:194 +#: cps/templates/admin.html:196 msgid "Check for Update" msgstr "Frissítés keresése" -#: cps/templates/admin.html:195 +#: cps/templates/admin.html:197 msgid "Perform Update" msgstr "Frissítés elkezdése" -#: cps/templates/admin.html:208 +#: cps/templates/admin.html:210 msgid "Are you sure you want to restart?" msgstr "Valóban újra akarod indítani a Calibre-Web-et?" -#: cps/templates/admin.html:213 cps/templates/admin.html:227 -#: cps/templates/admin.html:247 cps/templates/config_db.html:70 +#: cps/templates/admin.html:215 cps/templates/admin.html:229 +#: cps/templates/admin.html:249 cps/templates/config_db.html:70 msgid "OK" msgstr "OK" -#: cps/templates/admin.html:214 cps/templates/admin.html:228 -#: cps/templates/book_edit.html:213 cps/templates/book_table.html:124 +#: cps/templates/admin.html:216 cps/templates/admin.html:230 +#: cps/templates/book_edit.html:213 cps/templates/book_table.html:127 #: cps/templates/config_db.html:54 cps/templates/config_edit.html:359 -#: cps/templates/config_view_edit.html:173 cps/templates/modal_dialogs.html:64 +#: cps/templates/config_view_edit.html:175 cps/templates/modal_dialogs.html:64 #: cps/templates/modal_dialogs.html:99 cps/templates/modal_dialogs.html:117 #: cps/templates/modal_dialogs.html:135 cps/templates/shelf_edit.html:27 #: cps/templates/user_edit.html:144 msgid "Cancel" msgstr "" -#: cps/templates/admin.html:226 +#: cps/templates/admin.html:228 msgid "Are you sure you want to shutdown?" msgstr "Valóban le akarod állítani a Calibre-Web-et?" -#: cps/templates/admin.html:238 +#: cps/templates/admin.html:240 msgid "Updating, please do not reload this page" msgstr "Frissítés folyamatban, ne töltsd újra az oldalt" @@ -1599,44 +1622,43 @@ msgstr "keresztül" msgid "In Library" msgstr "Könyvtárban" -#: cps/templates/author.html:26 cps/templates/index.html:72 -#: cps/templates/search.html:29 cps/templates/shelf.html:19 +#: cps/templates/author.html:26 cps/templates/index.html:73 +#: cps/templates/search.html:30 cps/templates/shelf.html:19 msgid "Sort according to book date, newest first" msgstr "" -#: cps/templates/author.html:27 cps/templates/index.html:73 -#: cps/templates/search.html:30 cps/templates/shelf.html:20 +#: cps/templates/author.html:27 cps/templates/index.html:74 +#: cps/templates/search.html:31 cps/templates/shelf.html:20 msgid "Sort according to book date, oldest first" msgstr "" -#: cps/templates/author.html:28 cps/templates/index.html:74 -#: cps/templates/search.html:31 cps/templates/shelf.html:21 +#: cps/templates/author.html:28 cps/templates/index.html:75 +#: cps/templates/search.html:32 cps/templates/shelf.html:21 msgid "Sort title in alphabetical order" msgstr "" -#: cps/templates/author.html:29 cps/templates/index.html:75 -#: cps/templates/search.html:32 cps/templates/shelf.html:22 +#: cps/templates/author.html:29 cps/templates/index.html:76 +#: cps/templates/search.html:33 cps/templates/shelf.html:22 msgid "Sort title in reverse alphabetical order" msgstr "" -#: cps/templates/author.html:30 cps/templates/index.html:78 -#: cps/templates/search.html:35 cps/templates/shelf.html:25 +#: cps/templates/author.html:30 cps/templates/index.html:79 +#: cps/templates/search.html:36 cps/templates/shelf.html:25 msgid "Sort according to publishing date, newest first" msgstr "" -#: cps/templates/author.html:31 cps/templates/index.html:79 -#: cps/templates/search.html:36 cps/templates/shelf.html:26 +#: cps/templates/author.html:31 cps/templates/index.html:80 +#: cps/templates/search.html:37 cps/templates/shelf.html:26 msgid "Sort according to publishing date, oldest first" msgstr "" -#: cps/templates/author.html:57 cps/templates/author.html:117 -#: cps/templates/discover.html:30 cps/templates/index.html:29 -#: cps/templates/index.html:111 cps/templates/search.html:65 -#: cps/templates/shelf.html:54 +#: cps/templates/author.html:56 cps/templates/author.html:115 +#: cps/templates/index.html:29 cps/templates/index.html:112 +#: cps/templates/search.html:66 cps/templates/shelf.html:54 msgid "reduce" msgstr "csökkentsd" -#: cps/templates/author.html:101 +#: cps/templates/author.html:99 msgid "More by" msgstr "Több eszerint:" @@ -1761,7 +1783,7 @@ msgid "Fetch Metadata" msgstr "Metaadatok beszerzése" #: cps/templates/book_edit.html:212 cps/templates/config_db.html:53 -#: cps/templates/config_edit.html:358 cps/templates/config_view_edit.html:172 +#: cps/templates/config_edit.html:358 cps/templates/config_view_edit.html:174 #: cps/templates/email_edit.html:65 cps/templates/shelf_edit.html:25 #: cps/templates/shelf_order.html:41 cps/templates/user_edit.html:142 msgid "Save" @@ -1890,27 +1912,35 @@ msgstr "Tartomány megadása" msgid "Comments" msgstr "" -#: cps/templates/book_table.html:77 cps/templates/book_table.html:79 -#: cps/templates/book_table.html:81 cps/templates/book_table.html:83 -#: cps/templates/book_table.html:87 cps/templates/book_table.html:89 -#: cps/templates/book_table.html:91 cps/templates/book_table.html:93 +#: cps/templates/book_table.html:75 +msgid "Archiv Status" +msgstr "" + +#: cps/templates/book_table.html:77 cps/templates/search_form.html:42 +msgid "Read Status" +msgstr "" + +#: cps/templates/book_table.html:80 cps/templates/book_table.html:82 +#: cps/templates/book_table.html:84 cps/templates/book_table.html:86 +#: cps/templates/book_table.html:90 cps/templates/book_table.html:92 +#: cps/templates/book_table.html:96 #, fuzzy msgid "Enter " msgstr "Regisztrálás" -#: cps/templates/book_table.html:110 cps/templates/modal_dialogs.html:46 +#: cps/templates/book_table.html:113 cps/templates/modal_dialogs.html:46 msgid "Are you really sure?" msgstr "Biztosan?" -#: cps/templates/book_table.html:114 +#: cps/templates/book_table.html:117 msgid "Books with Title will be merged from:" msgstr "" -#: cps/templates/book_table.html:118 +#: cps/templates/book_table.html:121 msgid "Into Book with Title:" msgstr "" -#: cps/templates/book_table.html:123 +#: cps/templates/book_table.html:126 msgid "Merge" msgstr "" @@ -2086,11 +2116,6 @@ msgstr "" msgid "LDAP Encryption" msgstr "" -#: cps/templates/config_edit.html:204 cps/templates/config_view_edit.html:62 -#: cps/templates/email_edit.html:41 -msgid "None" -msgstr "Nincs" - #: cps/templates/config_edit.html:205 msgid "TLS" msgstr "" @@ -2309,11 +2334,11 @@ msgstr "Új felhasználók alapértelmezett látható elemei" msgid "Show Random Books in Detail View" msgstr "Mutasson könyveket találomra a részletes nézetben" -#: cps/templates/config_view_edit.html:165 cps/templates/user_edit.html:87 +#: cps/templates/config_view_edit.html:166 cps/templates/user_edit.html:87 msgid "Add Allowed/Denied Tags" msgstr "" -#: cps/templates/config_view_edit.html:166 +#: cps/templates/config_view_edit.html:167 msgid "Add Allowed/Denied custom column values" msgstr "" @@ -2362,13 +2387,13 @@ msgstr "" msgid "Description:" msgstr "Ismertető:" -#: cps/templates/detail.html:256 cps/templates/search.html:14 +#: cps/templates/detail.html:256 cps/templates/search.html:15 msgid "Add to shelf" msgstr "Hozzáadás polchoz" #: cps/templates/detail.html:267 cps/templates/detail.html:284 #: cps/templates/feed.xml:79 cps/templates/layout.html:137 -#: cps/templates/search.html:20 +#: cps/templates/search.html:21 msgid "(Public)" msgstr "" @@ -2446,10 +2471,14 @@ msgstr "" msgid "Next" msgstr "Következő" -#: cps/templates/generate_kobo_auth_url.html:5 +#: cps/templates/generate_kobo_auth_url.html:6 msgid "Open the .kobo/Kobo eReader.conf file in a text editor and add (or edit):" msgstr "" +#: cps/templates/generate_kobo_auth_url.html:11 +msgid "Kobo Token:" +msgstr "" + #: cps/templates/http_error.html:31 msgid "Calibre-Web Instance is unconfigured, please contact your administrator" msgstr "" @@ -2466,29 +2495,29 @@ msgstr "Vissza a kezdőlapra" msgid "Logout User" msgstr "" -#: cps/templates/index.html:69 +#: cps/templates/index.html:70 msgid "Sort ascending according to download count" msgstr "" -#: cps/templates/index.html:70 +#: cps/templates/index.html:71 msgid "Sort descending according to download count" msgstr "" -#: cps/templates/index.html:76 cps/templates/search.html:33 +#: cps/templates/index.html:77 cps/templates/search.html:34 #: cps/templates/shelf.html:23 msgid "Sort authors in alphabetical order" msgstr "" -#: cps/templates/index.html:77 cps/templates/search.html:34 +#: cps/templates/index.html:78 cps/templates/search.html:35 #: cps/templates/shelf.html:24 msgid "Sort authors in reverse alphabetical order" msgstr "" -#: cps/templates/index.html:81 +#: cps/templates/index.html:82 msgid "Sort ascending according to series index" msgstr "" -#: cps/templates/index.html:82 +#: cps/templates/index.html:83 msgid "Sort descending according to series index" msgstr "" @@ -2920,10 +2949,6 @@ msgstr "Kiadás éve ettől: " msgid "Published Date To" msgstr "Kiadás éve eddig: " -#: cps/templates/search_form.html:42 -msgid "Read Status" -msgstr "" - #: cps/templates/search_form.html:59 msgid "Exclude Tags" msgstr "Cimkék kizárása" diff --git a/cps/translations/it/LC_MESSAGES/messages.mo b/cps/translations/it/LC_MESSAGES/messages.mo index c0db83fd..c57e4071 100644 Binary files a/cps/translations/it/LC_MESSAGES/messages.mo and b/cps/translations/it/LC_MESSAGES/messages.mo differ diff --git a/cps/translations/it/LC_MESSAGES/messages.po b/cps/translations/it/LC_MESSAGES/messages.po index a5c2b4b3..e3096b31 100644 --- a/cps/translations/it/LC_MESSAGES/messages.po +++ b/cps/translations/it/LC_MESSAGES/messages.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: Calibre-Web\n" "Report-Msgid-Bugs-To: https://github.com/janeczku/Calibre-Web\n" -"POT-Creation-Date: 2022-01-15 09:19+0100\n" +"POT-Creation-Date: 2022-04-18 20:01+0200\n" "PO-Revision-Date: 2017-04-04 15:09+0200\n" "Last-Translator: ElQuimm \n" "Language: it\n" @@ -15,579 +15,582 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.9.0\n" +"Generated-By: Babel 2.9.1\n" -#: cps/about.py:34 cps/about.py:49 cps/about.py:65 cps/converter.py:31 -msgid "not installed" -msgstr "non installato" - -#: cps/about.py:47 cps/about.py:63 -msgid "installed" -msgstr "installato" - -#: cps/about.py:145 +#: cps/about.py:86 msgid "Statistics" msgstr "Statistiche" -#: cps/admin.py:144 +#: cps/admin.py:141 msgid "Server restarted, please reload page" msgstr "Server riavviato, per favore ricarica la pagina" -#: cps/admin.py:146 +#: cps/admin.py:143 msgid "Performing shutdown of server, please close window" msgstr "Eseguo l'arresto del server, per favore chiudi la finestra" -#: cps/admin.py:154 +#: cps/admin.py:151 msgid "Reconnect successful" msgstr "Ricollegato con successo" -#: cps/admin.py:157 +#: cps/admin.py:154 msgid "Unknown command" msgstr "Comando sconosciuto" -#: cps/admin.py:167 cps/editbooks.py:707 cps/editbooks.py:721 -#: cps/editbooks.py:866 cps/editbooks.py:868 cps/editbooks.py:895 -#: cps/editbooks.py:911 cps/updater.py:584 cps/uploader.py:93 -#: cps/uploader.py:103 +#: cps/admin.py:176 cps/editbooks.py:713 cps/editbooks.py:892 +#: cps/editbooks.py:894 cps/editbooks.py:930 cps/editbooks.py:947 +#: cps/updater.py:608 cps/uploader.py:93 cps/uploader.py:103 msgid "Unknown" msgstr "Sconosciuto" -#: cps/admin.py:188 +#: cps/admin.py:197 msgid "Admin page" msgstr "Pagina di amministrazione" -#: cps/admin.py:207 +#: cps/admin.py:217 msgid "Basic Configuration" msgstr "Configurazione di base" -#: cps/admin.py:244 +#: cps/admin.py:255 msgid "UI Configuration" msgstr "Configurazione dell'interfaccia utente" -#: cps/admin.py:277 cps/templates/admin.html:50 +#: cps/admin.py:289 cps/templates/admin.html:51 msgid "Edit Users" msgstr "Modifica gli utenti" -#: cps/admin.py:318 cps/opds.py:109 cps/opds.py:198 cps/opds.py:275 -#: cps/opds.py:327 cps/templates/grid.html:13 cps/templates/languages.html:9 +#: cps/admin.py:333 cps/opds.py:529 cps/templates/grid.html:13 #: cps/templates/list.html:13 msgid "All" msgstr "Tutti" -#: cps/admin.py:343 cps/admin.py:1615 +#: cps/admin.py:360 cps/admin.py:1648 msgid "User not found" msgstr "Utente non trovato" -#: cps/admin.py:357 +#: cps/admin.py:374 msgid "{} users deleted successfully" msgstr "{} utente eliminato con successo" -#: cps/admin.py:379 cps/templates/config_view_edit.html:133 +#: cps/admin.py:397 cps/templates/config_view_edit.html:133 #: cps/templates/user_edit.html:45 cps/templates/user_table.html:81 msgid "Show All" msgstr "tutte le lingue presenti" -#: cps/admin.py:400 cps/admin.py:406 +#: cps/admin.py:418 cps/admin.py:424 msgid "Malformed request" msgstr "Richiesta non formulata correttamente" -#: cps/admin.py:418 cps/admin.py:1493 +#: cps/admin.py:436 cps/admin.py:1526 msgid "Guest Name can't be changed" msgstr "Il nome dell'utente Guest (ospite) non può essere modificato" -#: cps/admin.py:430 +#: cps/admin.py:448 msgid "Guest can't have this role" msgstr "L'utente Guest (ospite) non può avere questo ruolo" -#: cps/admin.py:442 cps/admin.py:1451 +#: cps/admin.py:460 cps/admin.py:1484 msgid "No admin user remaining, can't remove admin role" msgstr "Non rimarrebbe nessun utente amministratore, non posso rimuovere il ruolo di amministratore" -#: cps/admin.py:446 cps/admin.py:460 +#: cps/admin.py:464 cps/admin.py:478 msgid "Value has to be true or false" msgstr "Il valore deve essere o vero o flaso" -#: cps/admin.py:448 +#: cps/admin.py:466 msgid "Invalid role" msgstr "Ruolo non valido" -#: cps/admin.py:452 +#: cps/admin.py:470 msgid "Guest can't have this view" msgstr "L'utente Guest (ospite) non può avere questa schermata" -#: cps/admin.py:462 +#: cps/admin.py:480 msgid "Invalid view" msgstr "Visualizzazione invalida" -#: cps/admin.py:465 +#: cps/admin.py:483 msgid "Guest's Locale is determined automatically and can't be set" msgstr "Le impostazioni locali dell'utente Guest (ospite) sono determinate automaticamente e non possono essere configurate" -#: cps/admin.py:469 +#: cps/admin.py:487 msgid "No Valid Locale Given" msgstr "Nessuna lingua valida indicata" -#: cps/admin.py:480 +#: cps/admin.py:498 msgid "No Valid Book Language Given" msgstr "Nessuna lingua valida per il libro" -#: cps/admin.py:482 +#: cps/admin.py:500 cps/editbooks.py:1267 msgid "Parameter not found" msgstr "Parametro non trovato" -#: cps/admin.py:533 +#: cps/admin.py:553 msgid "Invalid Read Column" msgstr "Colonna di lettura non valida" -#: cps/admin.py:539 +#: cps/admin.py:559 msgid "Invalid Restricted Column" msgstr "Colonna con restrizioni non valida" -#: cps/admin.py:560 cps/admin.py:1323 +#: cps/admin.py:579 cps/admin.py:1355 msgid "Calibre-Web configuration updated" msgstr "La configurazione di Calibre-Web è stata aggiornata" -#: cps/admin.py:572 +#: cps/admin.py:591 msgid "Do you really want to delete the Kobo Token?" msgstr "Vuoi veramente eliminare il token di Kobo?" -#: cps/admin.py:574 +#: cps/admin.py:593 msgid "Do you really want to delete this domain?" msgstr "Vuoi veramente eliminare questo dominio?" -#: cps/admin.py:576 +#: cps/admin.py:595 msgid "Do you really want to delete this user?" msgstr "Vuoi veramente eliminare questo utente?" -#: cps/admin.py:578 +#: cps/admin.py:597 msgid "Are you sure you want to delete this shelf?" msgstr "Vuoi veramente eliminare questo scaffale?" -#: cps/admin.py:580 +#: cps/admin.py:599 msgid "Are you sure you want to change locales of selected user(s)?" msgstr "Sei sicuro di voler modificare le impostazioni locali dell'/degli utente/i selezionato/i?" -#: cps/admin.py:582 +#: cps/admin.py:601 msgid "Are you sure you want to change visible book languages for selected user(s)?" msgstr "Sei sicuro di voler modificare le impostazioni delle lingue visualizzabili dell'/degli utente/i selezionato/i?" -#: cps/admin.py:584 +#: cps/admin.py:603 msgid "Are you sure you want to change the selected role for the selected user(s)?" msgstr "Sei sicuro di voler modificare il ruolo evidenziato dell'/degli utente/i selezionato/i?" -#: cps/admin.py:586 +#: cps/admin.py:605 #, fuzzy msgid "Are you sure you want to change the selected restrictions for the selected user(s)?" msgstr "Sei sicuro di voler modificare le impostazioni delle restrizioni di visualizzazione dell'/degli utente/i selezionato/i?" -#: cps/admin.py:588 +#: cps/admin.py:607 msgid "Are you sure you want to change the selected visibility restrictions for the selected user(s)?" msgstr "Sei sicuro di voler modificare le impostazioni delle restrizioni di visualizzazione dell'/degli utente/i selezionato/i?" -#: cps/admin.py:590 +#: cps/admin.py:610 msgid "Are you sure you want to change shelf sync behavior for the selected user(s)?" msgstr "Sei sicuro di voler modificare il comportamento di sincronizzazione dello scaffale per l'/gli utente/i selezionato/i?" -#: cps/admin.py:592 +#: cps/admin.py:612 msgid "Are you sure you want to change Calibre library location?" msgstr "Sei sicuro di voler modificare la posizione della libreria di Calibre?" -#: cps/admin.py:594 +#: cps/admin.py:614 msgid "Are you sure you want delete Calibre-Web's sync database to force a full sync with your Kobo Reader?" msgstr "" -#: cps/admin.py:743 +#: cps/admin.py:764 msgid "Tag not found" msgstr "Etichetta non trovata" -#: cps/admin.py:755 +#: cps/admin.py:776 msgid "Invalid Action" msgstr "Azione non valida" -#: cps/admin.py:871 cps/admin.py:877 cps/admin.py:887 cps/admin.py:897 +#: cps/admin.py:893 cps/admin.py:899 cps/admin.py:909 cps/admin.py:919 #: cps/templates/modal_dialogs.html:29 cps/templates/user_table.html:41 #: cps/templates/user_table.html:58 msgid "Deny" msgstr "Nega" -#: cps/admin.py:873 cps/admin.py:879 cps/admin.py:889 cps/admin.py:899 +#: cps/admin.py:895 cps/admin.py:901 cps/admin.py:911 cps/admin.py:921 #: cps/templates/modal_dialogs.html:28 cps/templates/user_table.html:44 #: cps/templates/user_table.html:61 msgid "Allow" msgstr "Permetti" -#: cps/admin.py:913 +#: cps/admin.py:936 msgid "{} sync entries deleted" msgstr "" -#: cps/admin.py:1036 +#: cps/admin.py:1059 msgid "client_secrets.json Is Not Configured For Web Application" msgstr "client_secrets.json non è configurato per Web Application" -#: cps/admin.py:1081 +#: cps/admin.py:1104 msgid "Logfile Location is not Valid, Please Enter Correct Path" msgstr "La posizione del Logfile non è valida, per favore indica il percorso corretto" -#: cps/admin.py:1087 +#: cps/admin.py:1110 msgid "Access Logfile Location is not Valid, Please Enter Correct Path" msgstr "La posizione dell'Access Logfile non è valida, per favore indica il percorso corretto" -#: cps/admin.py:1117 +#: cps/admin.py:1140 msgid "Please Enter a LDAP Provider, Port, DN and User Object Identifier" msgstr "Per favore digita un Provider LDAP, porta, DN e User Object Identifier" -#: cps/admin.py:1123 +#: cps/admin.py:1146 msgid "Please Enter a LDAP Service Account and Password" msgstr "Per favore digita nome di utente e password del servizio LDAP" -#: cps/admin.py:1126 +#: cps/admin.py:1149 msgid "Please Enter a LDAP Service Account" msgstr "Per favore indica un account di servizio LDAP" -#: cps/admin.py:1131 +#: cps/admin.py:1154 #, python-format msgid "LDAP Group Object Filter Needs to Have One \"%s\" Format Identifier" msgstr "LDAP Group Object Filter deve avere un \"%s\" Format Identifier" -#: cps/admin.py:1133 +#: cps/admin.py:1156 msgid "LDAP Group Object Filter Has Unmatched Parenthesis" msgstr "LDAP Group Object Filter contiene una parentesi senza la corrispettiva" -#: cps/admin.py:1137 +#: cps/admin.py:1160 #, python-format msgid "LDAP User Object Filter needs to Have One \"%s\" Format Identifier" msgstr "LDAP User Object Filter deve avere un \"%s\" Format Identifier" -#: cps/admin.py:1139 +#: cps/admin.py:1162 msgid "LDAP User Object Filter Has Unmatched Parenthesis" msgstr "LDAP User Object Filter contiene una parentesi senza la corrispettiva" -#: cps/admin.py:1146 +#: cps/admin.py:1169 #, python-format msgid "LDAP Member User Filter needs to Have One \"%s\" Format Identifier" msgstr "LDAP Member User Filter deve avere un \"%s\" Format Identifier" -#: cps/admin.py:1148 +#: cps/admin.py:1171 msgid "LDAP Member User Filter Has Unmatched Parenthesis" msgstr "LDAP Member User Filter contiene una parentesi senza la corrispettiva" -#: cps/admin.py:1155 +#: cps/admin.py:1178 msgid "LDAP CACertificate, Certificate or Key Location is not Valid, Please Enter Correct Path" msgstr "LDAP CACertificate, il certificato o la posizione della chiave non sono corretti, per favore indica il percorso corretto" -#: cps/admin.py:1197 cps/admin.py:1308 cps/admin.py:1405 cps/admin.py:1521 -#: cps/admin.py:1590 cps/shelf.py:100 cps/shelf.py:160 cps/shelf.py:203 -#: cps/shelf.py:279 cps/shelf.py:341 cps/shelf.py:376 cps/shelf.py:451 -msgid "Settings DB is not Writeable" -msgstr "I parametri del DB non sono scrivibili" - -#: cps/admin.py:1208 -msgid "DB Location is not Valid, Please Enter Correct Path" -msgstr "La posizione del DB non è valida, per favore indica il percorso corretto" - -#: cps/admin.py:1223 -msgid "DB is not Writeable" -msgstr "Il DB non è scrivibile" - -#: cps/admin.py:1235 -msgid "Keyfile Location is not Valid, Please Enter Correct Path" -msgstr "La posizione del Keyfile non è valida, per favore indica il percorso corretto" - -#: cps/admin.py:1239 -msgid "Certfile Location is not Valid, Please Enter Correct Path" -msgstr "La posizione del Certfile non è valida, per favore indica il percorso corretto" - -#: cps/admin.py:1346 -msgid "Database Settings updated" -msgstr "Configurazione del Database aggiornata" - -#: cps/admin.py:1354 -msgid "Database Configuration" -msgstr "Configurazione del Database" - -#: cps/admin.py:1370 cps/web.py:1479 -msgid "Please fill out all fields!" -msgstr "Per favore compila tutti i campi!" - -#: cps/admin.py:1378 -msgid "E-mail is not from valid domain" -msgstr "L'e-mail non proviene da un dominio valido" - -#: cps/admin.py:1384 cps/admin.py:1543 -msgid "Add new user" -msgstr "Aggiungi un nuovo utente" - -#: cps/admin.py:1395 -#, python-format -msgid "User '%(user)s' created" -msgstr "L'utente '%(user)s' è stato creato" - -#: cps/admin.py:1401 -msgid "Found an existing account for this e-mail address or name." -msgstr "Trovato un account esistente con questo e-mail o nome di utente" - -#: cps/admin.py:1430 -#, python-format -msgid "User '%(nick)s' deleted" -msgstr "L'utente '%(nick)s' è stato eliminato" - -#: cps/admin.py:1432 cps/admin.py:1433 -msgid "Can't delete Guest User" -msgstr "Non posso eliminare l'utente Guest (ospite)" - -#: cps/admin.py:1436 -msgid "No admin user remaining, can't delete user" -msgstr "Non rimarrebbe nessun utente amministratore, non posso eliminare l'utente" - -#: cps/admin.py:1509 cps/admin.py:1634 -#, python-format -msgid "Edit User %(nick)s" -msgstr "Modifica l'utente %(nick)s" - -#: cps/admin.py:1513 -#, python-format -msgid "User '%(nick)s' updated" -msgstr "L'utente '%(nick)s' è stato aggiornato" - -#: cps/admin.py:1517 cps/admin.py:1649 cps/web.py:1504 cps/web.py:1564 -msgid "An unknown error occurred. Please try again later." -msgstr "Si è verificato un errore sconosciuto: per favore riprova." - -#: cps/admin.py:1552 cps/templates/admin.html:98 -msgid "Edit E-mail Server Settings" -msgstr "Modifica le impostazioni del server e-mail" - -#: cps/admin.py:1571 -msgid "Gmail Account Verification Successful" -msgstr "L'account Gmail è stato verificato con successo" - -#: cps/admin.py:1597 -#, python-format -msgid "Test e-mail queued for sending to %(email)s, please check Tasks for result" -msgstr "L'e-mail di test è stato accodato con successo per essere spedito a %(email)s, per favore verifica tramite il pulsante 'Compito' il risultato" - -#: cps/admin.py:1600 -#, python-format -msgid "There was an error sending the Test e-mail: %(res)s" -msgstr "Si è verificato un errore nell'invio dell'e-mail di test: %(res)s" - -#: cps/admin.py:1602 -msgid "Please configure your e-mail address first..." -msgstr "Per favore prima configura il tuo indirizzo e-mail..." - -#: cps/admin.py:1604 -msgid "E-mail server settings updated" -msgstr "Configurazione del server e-mail aggiornata" - -#: cps/admin.py:1646 -#, python-format -msgid "Password for user %(user)s reset" -msgstr "La password dell'utente %(user)s è stata resettata" - -#: cps/admin.py:1652 cps/web.py:1444 -msgid "Please configure the SMTP mail settings first..." -msgstr "Configura dapprima le impostazioni del server SMTP..." - -#: cps/admin.py:1663 -msgid "Logfile viewer" -msgstr "Visualizzatore del Logfile" - -#: cps/admin.py:1729 -msgid "Requesting update package" -msgstr "Richiedo il pacchetto di aggiornamento" - -#: cps/admin.py:1730 -msgid "Downloading update package" -msgstr "Scarico il pacchetto di aggiornamento" - -#: cps/admin.py:1731 -msgid "Unzipping update package" -msgstr "Decomprimo il pacchetto di aggiornamento" - -#: cps/admin.py:1732 -msgid "Replacing files" -msgstr "Sostituisco i file" - -#: cps/admin.py:1733 -msgid "Database connections are closed" -msgstr "Le connessioni al database sono chiuse" - -#: cps/admin.py:1734 -msgid "Stopping server" -msgstr "Arresto il server" - -#: cps/admin.py:1735 -msgid "Update finished, please press okay and reload page" -msgstr "Aggiornamento completato, per favore premi ok e ricarica la pagina" - -#: cps/admin.py:1736 cps/admin.py:1737 cps/admin.py:1738 cps/admin.py:1739 -#: cps/admin.py:1740 cps/admin.py:1741 -msgid "Update failed:" -msgstr "Aggiornamento non riuscito:" - -#: cps/admin.py:1736 cps/updater.py:385 cps/updater.py:595 cps/updater.py:597 -msgid "HTTP Error" -msgstr "Errore HTTP" - -#: cps/admin.py:1737 cps/updater.py:387 cps/updater.py:599 -msgid "Connection error" -msgstr "Errore di connessione" - -#: cps/admin.py:1738 cps/updater.py:389 cps/updater.py:601 -msgid "Timeout while establishing connection" -msgstr "Tempo scaduto nello stabilire la connessione" - -#: cps/admin.py:1739 cps/updater.py:391 cps/updater.py:603 -msgid "General error" -msgstr "Errore generale" - -#: cps/admin.py:1740 -msgid "Update file could not be saved in temp dir" -msgstr "Il file di aggiornamento non può essere salvato nella cartella temporanea" - -#: cps/admin.py:1741 -msgid "Files could not be replaced during update" -msgstr "Durante l'aggiornamento non è stato possibile sostituire alcuni file" - -#: cps/admin.py:1765 -msgid "Failed to extract at least One LDAP User" -msgstr "Fallita l'estrazione di almeno un utente LDAP" - -#: cps/admin.py:1810 -msgid "Failed to Create at Least One LDAP User" -msgstr "Fallita la creazione di almeno un utente LDAP" - -#: cps/admin.py:1823 -#, python-format -msgid "Error: %(ldaperror)s" -msgstr "Errore: %(ldaperror)s" - -#: cps/admin.py:1827 -msgid "Error: No user returned in response of LDAP server" -msgstr "Errore: nessun utente restituito in risposta dal server LDAP" - -#: cps/admin.py:1860 -msgid "At Least One LDAP User Not Found in Database" -msgstr "Almeno un utente LDAP non è stato trovato nel database" - -#: cps/admin.py:1862 -msgid "{} User Successfully Imported" -msgstr "{} utente importato con successo" - -#: cps/converter.py:30 -msgid "not configured" -msgstr "non configurato" - -#: cps/converter.py:32 -msgid "Execution permissions missing" -msgstr "Mancano i permessi di esecuzione" - -#: cps/db.py:651 cps/web.py:667 cps/web.py:1155 -#, python-format -msgid "Custom Column No.%(column)d is not existing in calibre database" -msgstr "La colonna personale no.%(column)d non esiste nel database di Calibre" - -#: cps/editbooks.py:300 cps/editbooks.py:302 -msgid "Book Format Successfully Deleted" -msgstr "Il formato del libro è stato eliminato con successo" - -#: cps/editbooks.py:309 cps/editbooks.py:311 -msgid "Book Successfully Deleted" -msgstr "Il libro é stato eliminato con successo" - -#: cps/editbooks.py:361 -msgid "You are missing permissions to delete books" -msgstr "" - -#: cps/editbooks.py:376 cps/editbooks.py:763 cps/web.py:523 cps/web.py:1703 -#: cps/web.py:1744 cps/web.py:1811 -msgid "Oops! Selected book title is unavailable. File does not exist or is not accessible" -msgstr "Errore durante l'apertura del libro selezionato. Il file non esiste o il file non è accessibile" - -#: cps/editbooks.py:410 -msgid "edit metadata" -msgstr "modifica i metadati" - -#: cps/editbooks.py:458 -#, python-format -msgid "%(seriesindex)s is not a valid number, skipping" -msgstr "%(seriesindex)s non è un numero valido, proseguo" - -#: cps/editbooks.py:494 cps/editbooks.py:958 -#, fuzzy, python-format -msgid "'%(langname)s' is not a valid language" -msgstr "%(langname)s non è una lingua valida" - -#: cps/editbooks.py:634 cps/editbooks.py:985 -#, python-format -msgid "File extension '%(ext)s' is not allowed to be uploaded to this server" -msgstr "Non è consentito caricare file con l'estensione '%(ext)s' su questo server" - -#: cps/editbooks.py:638 cps/editbooks.py:989 -msgid "File to be uploaded must have an extension" -msgstr "Il file da caricare deve avere un'estensione" - -#: cps/editbooks.py:650 -#, python-format -msgid "Failed to create path %(path)s (Permission denied)." -msgstr "Impossibile creare la cartella %(path)s (autorizzazione negata)." - -#: cps/editbooks.py:655 -#, python-format -msgid "Failed to store file %(file)s." -msgstr "Il salvataggio del file %(file)s non è riuscito." - -#: cps/editbooks.py:673 cps/editbooks.py:1076 cps/web.py:1664 +#: cps/admin.py:1223 cps/admin.py:1339 cps/admin.py:1437 cps/admin.py:1554 +#: cps/admin.py:1623 cps/editbooks.py:678 cps/editbooks.py:882 +#: cps/editbooks.py:1130 cps/shelf.py:100 cps/shelf.py:160 cps/shelf.py:203 +#: cps/shelf.py:278 cps/shelf.py:343 cps/shelf.py:380 cps/shelf.py:456 +#: cps/web.py:1742 #, python-format msgid "Database error: %(error)s." msgstr "Errore nel database: %(error)s." -#: cps/editbooks.py:678 +#: cps/admin.py:1235 +msgid "DB Location is not Valid, Please Enter Correct Path" +msgstr "La posizione del DB non è valida, per favore indica il percorso corretto" + +#: cps/admin.py:1253 +msgid "DB is not Writeable" +msgstr "Il DB non è scrivibile" + +#: cps/admin.py:1266 +msgid "Keyfile Location is not Valid, Please Enter Correct Path" +msgstr "La posizione del Keyfile non è valida, per favore indica il percorso corretto" + +#: cps/admin.py:1270 +msgid "Certfile Location is not Valid, Please Enter Correct Path" +msgstr "La posizione del Certfile non è valida, per favore indica il percorso corretto" + +#: cps/admin.py:1378 +msgid "Database Settings updated" +msgstr "Configurazione del Database aggiornata" + +#: cps/admin.py:1386 +msgid "Database Configuration" +msgstr "Configurazione del Database" + +#: cps/admin.py:1402 cps/web.py:1557 +msgid "Please fill out all fields!" +msgstr "Per favore compila tutti i campi!" + +#: cps/admin.py:1410 +msgid "E-mail is not from valid domain" +msgstr "L'e-mail non proviene da un dominio valido" + +#: cps/admin.py:1416 cps/admin.py:1576 +msgid "Add new user" +msgstr "Aggiungi un nuovo utente" + +#: cps/admin.py:1427 +#, python-format +msgid "User '%(user)s' created" +msgstr "L'utente '%(user)s' è stato creato" + +#: cps/admin.py:1433 +msgid "Found an existing account for this e-mail address or name." +msgstr "Trovato un account esistente con questo e-mail o nome di utente" + +#: cps/admin.py:1463 +#, python-format +msgid "User '%(nick)s' deleted" +msgstr "L'utente '%(nick)s' è stato eliminato" + +#: cps/admin.py:1465 cps/admin.py:1466 +msgid "Can't delete Guest User" +msgstr "Non posso eliminare l'utente Guest (ospite)" + +#: cps/admin.py:1469 +msgid "No admin user remaining, can't delete user" +msgstr "Non rimarrebbe nessun utente amministratore, non posso eliminare l'utente" + +#: cps/admin.py:1542 cps/admin.py:1667 +#, python-format +msgid "Edit User %(nick)s" +msgstr "Modifica l'utente %(nick)s" + +#: cps/admin.py:1546 +#, python-format +msgid "User '%(nick)s' updated" +msgstr "L'utente '%(nick)s' è stato aggiornato" + +#: cps/admin.py:1550 cps/admin.py:1682 cps/web.py:1582 cps/web.py:1642 +msgid "An unknown error occurred. Please try again later." +msgstr "Si è verificato un errore sconosciuto: per favore riprova." + +#: cps/admin.py:1585 cps/templates/admin.html:100 +msgid "Edit E-mail Server Settings" +msgstr "Modifica le impostazioni del server e-mail" + +#: cps/admin.py:1604 +msgid "Gmail Account Verification Successful" +msgstr "L'account Gmail è stato verificato con successo" + +#: cps/admin.py:1630 +#, python-format +msgid "Test e-mail queued for sending to %(email)s, please check Tasks for result" +msgstr "L'e-mail di test è stato accodato con successo per essere spedito a %(email)s, per favore verifica tramite il pulsante 'Compito' il risultato" + +#: cps/admin.py:1633 +#, python-format +msgid "There was an error sending the Test e-mail: %(res)s" +msgstr "Si è verificato un errore nell'invio dell'e-mail di test: %(res)s" + +#: cps/admin.py:1635 +msgid "Please configure your e-mail address first..." +msgstr "Per favore prima configura il tuo indirizzo e-mail..." + +#: cps/admin.py:1637 +msgid "E-mail server settings updated" +msgstr "Configurazione del server e-mail aggiornata" + +#: cps/admin.py:1679 +#, python-format +msgid "Password for user %(user)s reset" +msgstr "La password dell'utente %(user)s è stata resettata" + +#: cps/admin.py:1685 cps/web.py:1522 +msgid "Please configure the SMTP mail settings first..." +msgstr "Configura dapprima le impostazioni del server SMTP..." + +#: cps/admin.py:1696 +msgid "Logfile viewer" +msgstr "Visualizzatore del Logfile" + +#: cps/admin.py:1762 +msgid "Requesting update package" +msgstr "Richiedo il pacchetto di aggiornamento" + +#: cps/admin.py:1763 +msgid "Downloading update package" +msgstr "Scarico il pacchetto di aggiornamento" + +#: cps/admin.py:1764 +msgid "Unzipping update package" +msgstr "Decomprimo il pacchetto di aggiornamento" + +#: cps/admin.py:1765 +msgid "Replacing files" +msgstr "Sostituisco i file" + +#: cps/admin.py:1766 +msgid "Database connections are closed" +msgstr "Le connessioni al database sono chiuse" + +#: cps/admin.py:1767 +msgid "Stopping server" +msgstr "Arresto il server" + +#: cps/admin.py:1768 +msgid "Update finished, please press okay and reload page" +msgstr "Aggiornamento completato, per favore premi ok e ricarica la pagina" + +#: cps/admin.py:1769 cps/admin.py:1770 cps/admin.py:1771 cps/admin.py:1772 +#: cps/admin.py:1773 cps/admin.py:1774 +msgid "Update failed:" +msgstr "Aggiornamento non riuscito:" + +#: cps/admin.py:1769 cps/updater.py:384 cps/updater.py:619 cps/updater.py:621 +msgid "HTTP Error" +msgstr "Errore HTTP" + +#: cps/admin.py:1770 cps/updater.py:386 cps/updater.py:623 +msgid "Connection error" +msgstr "Errore di connessione" + +#: cps/admin.py:1771 cps/updater.py:388 cps/updater.py:625 +msgid "Timeout while establishing connection" +msgstr "Tempo scaduto nello stabilire la connessione" + +#: cps/admin.py:1772 cps/updater.py:390 cps/updater.py:627 +msgid "General error" +msgstr "Errore generale" + +#: cps/admin.py:1773 +msgid "Update file could not be saved in temp dir" +msgstr "Il file di aggiornamento non può essere salvato nella cartella temporanea" + +#: cps/admin.py:1774 +msgid "Files could not be replaced during update" +msgstr "Durante l'aggiornamento non è stato possibile sostituire alcuni file" + +#: cps/admin.py:1798 +msgid "Failed to extract at least One LDAP User" +msgstr "Fallita l'estrazione di almeno un utente LDAP" + +#: cps/admin.py:1843 +msgid "Failed to Create at Least One LDAP User" +msgstr "Fallita la creazione di almeno un utente LDAP" + +#: cps/admin.py:1856 +#, python-format +msgid "Error: %(ldaperror)s" +msgstr "Errore: %(ldaperror)s" + +#: cps/admin.py:1860 +msgid "Error: No user returned in response of LDAP server" +msgstr "Errore: nessun utente restituito in risposta dal server LDAP" + +#: cps/admin.py:1893 +msgid "At Least One LDAP User Not Found in Database" +msgstr "Almeno un utente LDAP non è stato trovato nel database" + +#: cps/admin.py:1895 +msgid "{} User Successfully Imported" +msgstr "{} utente importato con successo" + +#: cps/converter.py:30 +msgid "not installed" +msgstr "non installato" + +#: cps/converter.py:31 +msgid "Execution permissions missing" +msgstr "Mancano i permessi di esecuzione" + +#: cps/db.py:674 cps/web.py:710 cps/web.py:1222 +#, python-format +msgid "Custom Column No.%(column)d is not existing in calibre database" +msgstr "La colonna personale no.%(column)d non esiste nel database di Calibre" + +#: cps/db.py:917 cps/templates/config_edit.html:204 +#: cps/templates/config_view_edit.html:62 cps/templates/email_edit.html:41 +#: cps/web.py:551 cps/web.py:585 cps/web.py:646 cps/web.py:671 cps/web.py:1003 +#: cps/web.py:1032 cps/web.py:1066 cps/web.py:1093 cps/web.py:1132 +msgid "None" +msgstr "Nessuna" + +#: cps/editbooks.py:295 cps/editbooks.py:297 +msgid "Book Format Successfully Deleted" +msgstr "Il formato del libro è stato eliminato con successo" + +#: cps/editbooks.py:304 cps/editbooks.py:306 +msgid "Book Successfully Deleted" +msgstr "Il libro é stato eliminato con successo" + +#: cps/editbooks.py:358 +msgid "You are missing permissions to delete books" +msgstr "" + +#: cps/editbooks.py:373 cps/editbooks.py:765 cps/web.py:518 cps/web.py:1783 +#: cps/web.py:1825 cps/web.py:1870 +msgid "Oops! Selected book title is unavailable. File does not exist or is not accessible" +msgstr "Errore durante l'apertura del libro selezionato. Il file non esiste o il file non è accessibile" + +#: cps/editbooks.py:408 +msgid "edit metadata" +msgstr "modifica i metadati" + +#: cps/editbooks.py:457 +#, python-format +msgid "%(seriesindex)s is not a valid number, skipping" +msgstr "%(seriesindex)s non è un numero valido, proseguo" + +#: cps/editbooks.py:493 cps/editbooks.py:1001 +#, fuzzy, python-format +msgid "'%(langname)s' is not a valid language" +msgstr "%(langname)s non è una lingua valida" + +#: cps/editbooks.py:634 +msgid "User has no rights to upload additional file formats" +msgstr "" + +#: cps/editbooks.py:639 cps/editbooks.py:1029 +#, python-format +msgid "File extension '%(ext)s' is not allowed to be uploaded to this server" +msgstr "Non è consentito caricare file con l'estensione '%(ext)s' su questo server" + +#: cps/editbooks.py:643 cps/editbooks.py:1033 +msgid "File to be uploaded must have an extension" +msgstr "Il file da caricare deve avere un'estensione" + +#: cps/editbooks.py:655 +#, python-format +msgid "Failed to create path %(path)s (Permission denied)." +msgstr "Impossibile creare la cartella %(path)s (autorizzazione negata)." + +#: cps/editbooks.py:660 +#, python-format +msgid "Failed to store file %(file)s." +msgstr "Il salvataggio del file %(file)s non è riuscito." + +#: cps/editbooks.py:683 #, python-format msgid "File format %(ext)s added to %(book)s" msgstr "Ho aggiunto il formato %(ext)s al libro %(book)s" -#: cps/editbooks.py:814 +#: cps/editbooks.py:697 cps/editbooks.py:809 +msgid "User has no rights to upload cover" +msgstr "" + +#: cps/editbooks.py:828 msgid "Identifiers are not Case Sensitive, Overwriting Old Identifier" msgstr "Gli identificatori non tengono conto delle lettere maiuscole o minuscole, sovrascrivo l'identificatore precedente" -#: cps/editbooks.py:848 +#: cps/editbooks.py:869 msgid "Metadata successfully updated" msgstr "I metadati sono stati aggiornati con successo" -#: cps/editbooks.py:861 -msgid "Error editing book, please check logfile for details" -msgstr "Errore nella modifica del libro. Per favore verifica i dettagli nel file di registro (logfile)" +#: cps/editbooks.py:887 +msgid "Error editing book: {}" +msgstr "" -#: cps/editbooks.py:899 +#: cps/editbooks.py:951 msgid "Uploaded book probably exists in the library, consider to change before upload new: " msgstr "Probabilmente il libro caricato esiste già nella libreria; considera di cambiare prima di sottoporlo nuovamente: " -#: cps/editbooks.py:997 +#: cps/editbooks.py:1041 #, python-format msgid "File %(filename)s could not saved to temp dir" msgstr "Il file %(filename)s non può essere salvato nella cartella temporanea" -#: cps/editbooks.py:1016 +#: cps/editbooks.py:1061 #, python-format msgid "Failed to Move Cover File %(file)s: %(error)s" msgstr "Impossibile spostare il file della copertina %(file)s: %(error)s" -#: cps/editbooks.py:1063 +#: cps/editbooks.py:1117 #, python-format msgid "File %(file)s uploaded" msgstr "Il file %(file)s è stato caricato" -#: cps/editbooks.py:1088 +#: cps/editbooks.py:1143 msgid "Source or destination format for conversion missing" msgstr "Mancano o il formato sorgente o quello di destinazione, entrambi necessari alla conversione" -#: cps/editbooks.py:1096 +#: cps/editbooks.py:1151 #, python-format msgid "Book successfully queued for converting to %(book_format)s" msgstr "Libro accodato con successo per essere convertito in %(book_format)s" -#: cps/editbooks.py:1100 +#: cps/editbooks.py:1155 #, python-format msgid "There was an error converting this book: %(res)s" msgstr "Si è verificato un errore durante la conversione del libro: %(res)s" @@ -600,174 +603,191 @@ msgstr "La configurazione di Google Drive non è stata completata correttamente. msgid "Callback domain is not verified, please follow steps to verify domain in google developer console" msgstr "Callback domain non è stato verificato. Per favore intraprendi il necessario per verificare il dominio nella developer console di Google" -#: cps/helper.py:77 +#: cps/helper.py:81 #, python-format msgid "%(format)s format not found for book id: %(book)d" msgstr "Formato %(format)s non trovato per il libro: %(book)d" -#: cps/helper.py:83 cps/tasks/convert.py:73 +#: cps/helper.py:87 cps/tasks/convert.py:75 #, python-format msgid "%(format)s not found on Google Drive: %(fn)s" msgstr "%(format)s non trovato su Google Drive: %(fn)s" -#: cps/helper.py:88 +#: cps/helper.py:92 #, python-format msgid "%(format)s not found: %(fn)s" msgstr "%(format)s non trovato: %(fn)s" -#: cps/helper.py:93 cps/helper.py:217 cps/templates/detail.html:41 +#: cps/helper.py:97 cps/helper.py:221 cps/templates/detail.html:41 #: cps/templates/detail.html:45 msgid "Send to Kindle" msgstr "Invia a Kindle" -#: cps/helper.py:94 cps/helper.py:111 cps/helper.py:219 +#: cps/helper.py:98 cps/helper.py:115 cps/helper.py:223 msgid "This e-mail has been sent via Calibre-Web." msgstr "Questo e-mail è stato spedito tramite Calibre-Web." -#: cps/helper.py:109 +#: cps/helper.py:113 msgid "Calibre-Web test e-mail" msgstr "E-mail di test da Calibre-Web" -#: cps/helper.py:110 +#: cps/helper.py:114 msgid "Test e-mail" msgstr "E-mail di test" -#: cps/helper.py:127 +#: cps/helper.py:131 msgid "Get Started with Calibre-Web" msgstr "Inizia con Calibre-Web" -#: cps/helper.py:132 +#: cps/helper.py:136 #, python-format msgid "Registration e-mail for user: %(name)s" msgstr "E-mail di registrazione dell'utente: %(name)s" -#: cps/helper.py:143 cps/helper.py:149 +#: cps/helper.py:147 cps/helper.py:153 #, python-format msgid "Convert %(orig)s to %(format)s and send to Kindle" msgstr "Converti %(orig)s in %(format)s e spedisci a Kindle" -#: cps/helper.py:168 cps/helper.py:172 cps/helper.py:176 +#: cps/helper.py:172 cps/helper.py:176 cps/helper.py:180 #, python-format msgid "Send %(format)s to Kindle" msgstr "Invia %(format)s a Kindle" -#: cps/helper.py:216 cps/tasks/convert.py:90 +#: cps/helper.py:220 cps/tasks/convert.py:92 #, python-format msgid "%(book)s send to Kindle" msgstr "%(book)s inviato a Kindle" -#: cps/helper.py:221 +#: cps/helper.py:225 msgid "The requested file could not be read. Maybe wrong permissions?" msgstr "Il file richiesto non può essere letto. I permessi sono corretti?" -#: cps/helper.py:313 +#: cps/helper.py:353 +msgid "Read status could not set: {}" +msgstr "" + +#: cps/helper.py:376 #, python-format msgid "Deleting bookfolder for book %(id)s failed, path has subfolders: %(path)s" msgstr "L'eliminazione della cartella del libro %(id)s non è riuscita, il percorso ha sottocartelle: %(path)s" -#: cps/helper.py:319 +#: cps/helper.py:382 #, python-format msgid "Deleting book %(id)s failed: %(message)s" msgstr "L'eliminazione del libro %(id)s non è riuscita: %(message)s" -#: cps/helper.py:330 +#: cps/helper.py:393 #, python-format msgid "Deleting book %(id)s from database only, book path in database not valid: %(path)s" msgstr "Eliminazione del libro %(id)s unicamente dal database. Il percorso del libro nel database non è valido: %(path)s" -#: cps/helper.py:385 -#, python-format -msgid "Rename title from: '%(src)s' to '%(dest)s' failed with error: %(error)s" +#: cps/helper.py:458 +#, fuzzy, python-format +msgid "Rename author from: '%(src)s' to '%(dest)s' failed with error: %(error)s" msgstr "La modifica del titolo da '%(src)s' a '%(dest)s' è terminata con l'errore: %(error)s" -#: cps/helper.py:400 -#, python-format -msgid "Rename file in path '%(src)s' to '%(dest)s' failed with error: %(error)s" -msgstr "La modifica del file nella cartella da '%(src)s' a '%(dest)s' è terminata con l'errore: %(error)s" - -#: cps/helper.py:425 cps/helper.py:435 cps/helper.py:443 +#: cps/helper.py:529 cps/helper.py:538 #, python-format msgid "File %(file)s not found on Google Drive" msgstr "File %(file)s non trovato su Google Drive" -#: cps/helper.py:464 +#: cps/helper.py:572 +#, python-format +msgid "Rename title from: '%(src)s' to '%(dest)s' failed with error: %(error)s" +msgstr "La modifica del titolo da '%(src)s' a '%(dest)s' è terminata con l'errore: %(error)s" + +#: cps/helper.py:592 +msgid "Error in rename file in path: {}" +msgstr "" + +#: cps/helper.py:610 #, python-format msgid "Book path %(path)s not found on Google Drive" msgstr "Non ho trovato la cartella %(path)s del libro su Google Drive" -#: cps/helper.py:504 cps/web.py:1659 +#: cps/helper.py:651 cps/web.py:1737 msgid "Found an existing account for this e-mail address" msgstr "Ho trovato un account creato in precedenza con questo indirizzo e-mail." -#: cps/helper.py:512 +#: cps/helper.py:659 msgid "This username is already taken" msgstr "Questo nome di utente è già utilizzato" -#: cps/helper.py:522 +#: cps/helper.py:669 msgid "Invalid e-mail address format" msgstr "L'e-mail non è scritto in un formato valido" -#: cps/helper.py:595 +#: cps/helper.py:754 +msgid "Python modul 'advocate' is not installed but is needed for cover downloads" +msgstr "" + +#: cps/helper.py:767 msgid "Error Downloading Cover" msgstr "Errore nello scaricare la copertina" -#: cps/helper.py:598 +#: cps/helper.py:770 msgid "Cover Format Error" msgstr "Errore di formato della copertina" -#: cps/helper.py:608 +#: cps/helper.py:773 +msgid "You are not allowed to access localhost or the local network for cover uploads" +msgstr "" + +#: cps/helper.py:783 msgid "Failed to create path for cover" msgstr "Errore nel creare la cartella per la copertina" -#: cps/helper.py:624 +#: cps/helper.py:799 msgid "Cover-file is not a valid image file, or could not be stored" msgstr "Il file della copertina non è in un formato immagine valido o non può essere salvato" -#: cps/helper.py:635 +#: cps/helper.py:810 msgid "Only jpg/jpeg/png/webp/bmp files are supported as coverfile" msgstr "Solamente i file nei formati jpg/jpeg/png/webp/bmp sono supportati per le copertine" -#: cps/helper.py:648 +#: cps/helper.py:822 msgid "Invalid cover file content" msgstr "" -#: cps/helper.py:652 +#: cps/helper.py:826 msgid "Only jpg/jpeg files are supported as coverfile" msgstr "Solamente i file nei formati jpg/jpeg sono supportati per le copertine" -#: cps/helper.py:704 +#: cps/helper.py:878 msgid "Unrar binary file not found" msgstr "Non ho trovato il file binario di UnRar" -#: cps/helper.py:715 +#: cps/helper.py:889 msgid "Error excecuting UnRar" msgstr "Errore nell'eseguire UnRar" -#: cps/helper.py:763 +#: cps/helper.py:937 msgid "Waiting" msgstr "Attendi" -#: cps/helper.py:765 +#: cps/helper.py:939 msgid "Failed" msgstr "Non riuscito" -#: cps/helper.py:767 +#: cps/helper.py:941 msgid "Started" msgstr "Avviato" -#: cps/helper.py:769 +#: cps/helper.py:943 msgid "Finished" msgstr "Terminato" -#: cps/helper.py:771 +#: cps/helper.py:945 msgid "Unknown Status" msgstr "Stato sconosciuto" -#: cps/kobo_auth.py:127 -msgid "PLease access calibre-web from non localhost to get valid api_endpoint for kobo device" +#: cps/kobo_auth.py:128 +#, fuzzy +msgid "Please access Calibre-Web from non localhost to get valid api_endpoint for kobo device" msgstr "Per favore accedi a calibe-web non da localhost per ottenere un api-endpoint valido per il lettore kobo" -#: cps/kobo_auth.py:130 cps/kobo_auth.py:158 +#: cps/kobo_auth.py:154 msgid "Kobo Setup" msgstr "Configurazione di Kobo" @@ -776,7 +796,7 @@ msgstr "Configurazione di Kobo" msgid "Register with %(provider)s" msgstr "Registra con %(provider)s" -#: cps/oauth_bb.py:138 cps/remotelogin.py:133 cps/web.py:1535 +#: cps/oauth_bb.py:138 cps/remotelogin.py:130 cps/web.py:1613 #, python-format msgid "you are now logged in as: '%(nickname)s'" msgstr "ora sei connesso come: '%(nickname)s'" @@ -837,163 +857,163 @@ msgstr "Google, errore Oauth: per favore riprova più tardi." msgid "Google Oauth error: {}" msgstr "Google, errore Oauth: {}" -#: cps/opds.py:384 +#: cps/opds.py:298 msgid "{} Stars" msgstr "{} Stelle" -#: cps/remotelogin.py:65 cps/templates/layout.html:84 -#: cps/templates/login.html:4 cps/templates/login.html:21 cps/web.py:1584 +#: cps/remotelogin.py:62 cps/templates/layout.html:84 +#: cps/templates/login.html:4 cps/templates/login.html:21 cps/web.py:1662 msgid "Login" msgstr "Accesso" -#: cps/remotelogin.py:77 cps/remotelogin.py:111 +#: cps/remotelogin.py:74 cps/remotelogin.py:108 msgid "Token not found" msgstr "Token non trovato" -#: cps/remotelogin.py:86 cps/remotelogin.py:119 +#: cps/remotelogin.py:83 cps/remotelogin.py:116 msgid "Token has expired" msgstr "Il token è scaduto" -#: cps/remotelogin.py:95 +#: cps/remotelogin.py:92 msgid "Success! Please return to your device" msgstr "Riuscito! Torna al tuo dispositivo" -#: cps/render_template.py:39 cps/web.py:416 +#: cps/render_template.py:41 cps/web.py:407 msgid "Books" msgstr "Libri" -#: cps/render_template.py:41 +#: cps/render_template.py:43 msgid "Show recent books" msgstr "Mostra l'opzione per la selezione dei libri più recenti" -#: cps/render_template.py:42 cps/templates/index.xml:25 +#: cps/render_template.py:44 cps/templates/index.xml:25 msgid "Hot Books" msgstr "Libri popolari" -#: cps/render_template.py:44 +#: cps/render_template.py:46 msgid "Show Hot Books" msgstr "Mostra l'opzione per la selezione dei libri più popolari" -#: cps/render_template.py:46 cps/render_template.py:51 +#: cps/render_template.py:48 cps/render_template.py:53 msgid "Downloaded Books" msgstr "Libri scaricati" -#: cps/render_template.py:48 cps/render_template.py:53 +#: cps/render_template.py:50 cps/render_template.py:55 #: cps/templates/user_table.html:167 msgid "Show Downloaded Books" msgstr "Mostra l'opzione per la visualizzazione dei libri scaricati" -#: cps/render_template.py:56 cps/templates/index.xml:32 cps/web.py:430 +#: cps/render_template.py:58 cps/templates/index.xml:32 cps/web.py:422 msgid "Top Rated Books" msgstr "Libri meglio valutati" -#: cps/render_template.py:58 cps/templates/user_table.html:161 +#: cps/render_template.py:60 cps/templates/user_table.html:161 msgid "Show Top Rated Books" msgstr "Mostra l'opzione per la selezione dei libri meglio valutati" -#: cps/render_template.py:59 cps/templates/index.xml:54 -#: cps/templates/index.xml:58 cps/web.py:676 +#: cps/render_template.py:61 cps/templates/index.xml:54 +#: cps/templates/index.xml:58 cps/web.py:729 msgid "Read Books" msgstr "Libri letti" -#: cps/render_template.py:61 +#: cps/render_template.py:63 msgid "Show read and unread" msgstr "Mostra l'opzione per la selezione letto e non letto" -#: cps/render_template.py:63 cps/templates/index.xml:61 -#: cps/templates/index.xml:65 cps/web.py:679 +#: cps/render_template.py:65 cps/templates/index.xml:61 +#: cps/templates/index.xml:65 cps/web.py:732 msgid "Unread Books" msgstr "Libri non letti" -#: cps/render_template.py:65 +#: cps/render_template.py:67 msgid "Show unread" msgstr "Mostra l'opzione per la selezione dei libri non letti" -#: cps/render_template.py:66 +#: cps/render_template.py:68 msgid "Discover" msgstr "Per scoprire" -#: cps/render_template.py:68 cps/templates/index.xml:50 +#: cps/render_template.py:70 cps/templates/index.xml:50 #: cps/templates/user_table.html:162 msgid "Show Random Books" msgstr "Mostra libri casualmente" -#: cps/render_template.py:69 cps/templates/book_table.html:67 -#: cps/templates/index.xml:83 cps/web.py:1041 +#: cps/render_template.py:71 cps/templates/book_table.html:67 +#: cps/templates/index.xml:83 cps/web.py:1135 msgid "Categories" msgstr "Categorie" -#: cps/render_template.py:71 cps/templates/user_table.html:158 +#: cps/render_template.py:73 cps/templates/user_table.html:158 msgid "Show category selection" msgstr "Mostra l'opzione per la selezione delle categorie" -#: cps/render_template.py:72 cps/templates/book_edit.html:90 +#: cps/render_template.py:74 cps/templates/book_edit.html:90 #: cps/templates/book_table.html:68 cps/templates/index.xml:90 -#: cps/templates/search_form.html:69 cps/web.py:948 cps/web.py:959 +#: cps/templates/search_form.html:69 cps/web.py:1034 cps/web.py:1041 msgid "Series" msgstr "Serie" -#: cps/render_template.py:74 cps/templates/user_table.html:157 +#: cps/render_template.py:76 cps/templates/user_table.html:157 msgid "Show series selection" msgstr "Mostra l'opzione per la selezione delle serie" -#: cps/render_template.py:75 cps/templates/book_table.html:66 +#: cps/render_template.py:77 cps/templates/book_table.html:66 #: cps/templates/index.xml:69 msgid "Authors" msgstr "Autori" -#: cps/render_template.py:77 cps/templates/user_table.html:160 +#: cps/render_template.py:79 cps/templates/user_table.html:160 msgid "Show author selection" msgstr "Mostra l'opzione per la selezione degli autori" -#: cps/render_template.py:79 cps/templates/book_table.html:72 -#: cps/templates/index.xml:76 cps/web.py:925 +#: cps/render_template.py:81 cps/templates/book_table.html:72 +#: cps/templates/index.xml:76 cps/web.py:1006 msgid "Publishers" msgstr "Editori" -#: cps/render_template.py:81 cps/templates/user_table.html:163 +#: cps/render_template.py:83 cps/templates/user_table.html:163 msgid "Show publisher selection" msgstr "Mostra l'opzione per la selezione degli editori" -#: cps/render_template.py:82 cps/templates/book_table.html:70 +#: cps/render_template.py:84 cps/templates/book_table.html:70 #: cps/templates/index.xml:97 cps/templates/search_form.html:107 -#: cps/web.py:1018 +#: cps/web.py:1108 msgid "Languages" msgstr "Lingue" -#: cps/render_template.py:85 cps/templates/user_table.html:155 +#: cps/render_template.py:87 cps/templates/user_table.html:155 msgid "Show language selection" msgstr "Mostra l'opzione per la selezione delle lingue" -#: cps/render_template.py:86 cps/templates/index.xml:104 +#: cps/render_template.py:88 cps/templates/index.xml:104 msgid "Ratings" msgstr "Valutazioni" -#: cps/render_template.py:88 cps/templates/user_table.html:164 +#: cps/render_template.py:90 cps/templates/user_table.html:164 msgid "Show ratings selection" msgstr "Mostra l'opzione per la selezione delle valutazioni" -#: cps/render_template.py:89 cps/templates/index.xml:112 +#: cps/render_template.py:91 cps/templates/index.xml:112 msgid "File formats" msgstr "Formati file" -#: cps/render_template.py:91 cps/templates/user_table.html:165 +#: cps/render_template.py:93 cps/templates/user_table.html:165 msgid "Show file formats selection" msgstr "Mostra l'opzione per la selezione del formato dei file" -#: cps/render_template.py:93 cps/web.py:703 +#: cps/render_template.py:95 cps/web.py:755 msgid "Archived Books" msgstr "Libri archiviati" -#: cps/render_template.py:95 cps/templates/user_table.html:166 +#: cps/render_template.py:97 cps/templates/user_table.html:166 msgid "Show archived books" msgstr "Mostra l'opzione per la selezione dei libri archiviati" -#: cps/render_template.py:97 cps/web.py:780 +#: cps/render_template.py:100 cps/web.py:837 msgid "Books List" msgstr "Elenco libri" -#: cps/render_template.py:99 cps/templates/user_table.html:168 +#: cps/render_template.py:102 cps/templates/user_table.html:168 msgid "Show Books List" msgstr "Mostra l'opzione per visualizzare i libri sottoforma di elenco" @@ -1048,261 +1068,265 @@ msgstr "" msgid "Create a Shelf" msgstr "Crea uno scaffale" -#: cps/shelf.py:237 +#: cps/shelf.py:236 msgid "Sorry you are not allowed to edit this shelf" msgstr "Spiacente, non sei autorizzato a modificare questo scaffale" -#: cps/shelf.py:239 +#: cps/shelf.py:238 msgid "Edit a shelf" msgstr "Modifica uno scaffale" -#: cps/shelf.py:249 +#: cps/shelf.py:248 msgid "Sorry you are not allowed to create a public shelf" msgstr "" -#: cps/shelf.py:266 +#: cps/shelf.py:265 #, python-format msgid "Shelf %(title)s created" msgstr "Lo scaffale %(title)s è stato creato" -#: cps/shelf.py:269 +#: cps/shelf.py:268 #, python-format msgid "Shelf %(title)s changed" msgstr "Lo scaffale %(title)s è stato modificato" -#: cps/shelf.py:283 +#: cps/shelf.py:282 msgid "There was an error" msgstr "C'era un errore" -#: cps/shelf.py:305 +#: cps/shelf.py:304 #, python-format msgid "A public shelf with the name '%(title)s' already exists." msgstr "Esiste già uno scaffale pubblico denominato '%(title)s'." -#: cps/shelf.py:316 +#: cps/shelf.py:315 #, python-format msgid "A private shelf with the name '%(title)s' already exists." msgstr "Esiste già uno scaffale privato denominato '%(title)s'." #: cps/shelf.py:337 +msgid "Error deleting Shelf" +msgstr "" + +#: cps/shelf.py:339 #, fuzzy msgid "Shelf successfully deleted" msgstr "Il libro é stato eliminato con successo" -#: cps/shelf.py:386 +#: cps/shelf.py:389 #, python-format msgid "Change order of Shelf: '%(name)s'" msgstr "Modifica l'ordine dello scaffale: '%(name)s'" -#: cps/shelf.py:456 +#: cps/shelf.py:461 #, python-format msgid "Shelf: '%(name)s'" msgstr "Scaffale: '%(name)s'" -#: cps/shelf.py:460 +#: cps/shelf.py:465 msgid "Error opening shelf. Shelf does not exist or is not accessible" msgstr "Errore durante l'apertura dello scaffale. Lo scaffale non esiste o non è accessibile" -#: cps/updater.py:403 cps/updater.py:414 cps/updater.py:514 cps/updater.py:529 +#: cps/updater.py:426 cps/updater.py:437 cps/updater.py:538 cps/updater.py:553 msgid "Unexpected data while reading update information" msgstr "Dati inattesi durante il processo di aggiornamento" -#: cps/updater.py:410 cps/updater.py:521 +#: cps/updater.py:433 cps/updater.py:545 msgid "No update available. You already have the latest version installed" msgstr "Nessun aggiornamento disponibile. Hai già installata l'ultima versione" -#: cps/updater.py:428 +#: cps/updater.py:451 msgid "A new update is available. Click on the button below to update to the latest version." msgstr "Nuovo aggiornamento disponibile. Clicca sul pulsante sottostante per aggiornare all'ultima versione." -#: cps/updater.py:446 +#: cps/updater.py:469 msgid "Could not fetch update information" msgstr "Impossibile recuperare le informazioni di aggiornamento" -#: cps/updater.py:456 +#: cps/updater.py:479 msgid "Click on the button below to update to the latest stable version." msgstr "Clicca sul pulsante per aggiornare all'ultima versione stabile." -#: cps/updater.py:465 cps/updater.py:479 cps/updater.py:490 +#: cps/updater.py:488 cps/updater.py:502 cps/updater.py:513 #, python-format msgid "A new update is available. Click on the button below to update to version: %(version)s" msgstr "Nuovo aggiornamento disponibile. Clicca sul pulsante sottostante per aggiornare alla versione: %(version)s" -#: cps/updater.py:507 +#: cps/updater.py:531 msgid "No release information available" msgstr "Non sono disponibili informazioni sulla versione" -#: cps/templates/index.html:5 cps/web.py:440 +#: cps/templates/index.html:5 cps/web.py:434 msgid "Discover (Random Books)" msgstr "Scopri (libri casuali)" -#: cps/web.py:471 +#: cps/web.py:470 msgid "Hot Books (Most Downloaded)" msgstr "I libri più richiesti" -#: cps/web.py:507 +#: cps/web.py:501 #, python-format msgid "Downloaded books by %(user)s" msgstr "I libri scaricati da %(user)s" -#: cps/web.py:539 +#: cps/web.py:534 #, python-format msgid "Author: %(name)s" msgstr "Autore: %(name)s" -#: cps/web.py:554 +#: cps/web.py:570 #, python-format msgid "Publisher: %(name)s" msgstr "Editore: %(name)s" -#: cps/web.py:569 +#: cps/web.py:598 #, python-format msgid "Series: %(serie)s" msgstr "Serie: %(serie)s" -#: cps/web.py:582 +#: cps/web.py:610 #, python-format msgid "Rating: %(rating)s stars" msgstr "Valutazione: %(rating)s stelle" -#: cps/web.py:597 +#: cps/web.py:626 #, python-format msgid "File format: %(format)s" msgstr "Formato del file: %(format)s" -#: cps/web.py:615 +#: cps/web.py:663 #, python-format msgid "Category: %(name)s" msgstr "Categoria: %(name)s" -#: cps/web.py:631 +#: cps/web.py:690 #, python-format msgid "Language: %(name)s" msgstr "Lingua: %(name)s" -#: cps/templates/layout.html:56 cps/web.py:737 cps/web.py:1371 +#: cps/templates/layout.html:56 cps/web.py:789 cps/web.py:1444 msgid "Advanced Search" msgstr "Ricerca avanzata" #: cps/templates/book_edit.html:235 cps/templates/feed.xml:33 #: cps/templates/index.xml:11 cps/templates/layout.html:45 #: cps/templates/layout.html:48 cps/templates/search_form.html:226 -#: cps/web.py:750 cps/web.py:1077 +#: cps/web.py:807 cps/web.py:1164 msgid "Search" msgstr "Cerca" -#: cps/templates/admin.html:16 cps/web.py:903 +#: cps/templates/admin.html:16 cps/web.py:979 msgid "Downloads" msgstr "Downloads" -#: cps/web.py:980 +#: cps/web.py:1068 msgid "Ratings list" msgstr "Elenco delle valutazioni" -#: cps/web.py:1001 +#: cps/web.py:1095 msgid "File formats list" msgstr "Elenco dei formati" -#: cps/templates/layout.html:73 cps/templates/tasks.html:7 cps/web.py:1055 +#: cps/templates/layout.html:73 cps/templates/tasks.html:7 cps/web.py:1149 msgid "Tasks" msgstr "Compito" -#: cps/web.py:1215 +#: cps/web.py:1286 msgid "Published after " msgstr "Pubblicato dopo il " -#: cps/web.py:1222 +#: cps/web.py:1293 msgid "Published before " msgstr "Pubblicato prima del " -#: cps/web.py:1244 +#: cps/web.py:1315 #, python-format msgid "Rating <= %(rating)s" msgstr "Valutazione <= %(rating)s" -#: cps/web.py:1246 +#: cps/web.py:1317 #, python-format msgid "Rating >= %(rating)s" msgstr "Valutazione >= %(rating)s" -#: cps/web.py:1248 +#: cps/web.py:1319 #, python-format msgid "Read Status = %(status)s" msgstr "Stato di lettura = %(status)s" -#: cps/web.py:1353 +#: cps/web.py:1425 msgid "Error on search for custom columns, please restart Calibre-Web" msgstr "Errore di ricerca nelle colonne personalizzate. Per favore riavvia Calibre-Web" -#: cps/web.py:1449 +#: cps/web.py:1527 #, python-format msgid "Book successfully queued for sending to %(kindlemail)s" msgstr "Libro accodato con successo per essere spedito a %(kindlemail)s" -#: cps/web.py:1453 +#: cps/web.py:1531 #, python-format msgid "Oops! There was an error sending this book: %(res)s" msgstr "Oops! Si è verificato un errore durante l'invio di questo libro: %(res)s" -#: cps/web.py:1455 +#: cps/web.py:1533 msgid "Please update your profile with a valid Send to Kindle E-mail Address." msgstr "Per favore aggiorna il tuo profilo con un indirizzo e-mail Kindle a cui inviare i libri." -#: cps/web.py:1472 +#: cps/web.py:1550 msgid "E-Mail server is not configured, please contact your administrator!" msgstr "Il server e-mail non è configurato, per favore contatta l'amministratore" -#: cps/templates/layout.html:85 cps/templates/register.html:17 cps/web.py:1473 -#: cps/web.py:1480 cps/web.py:1486 cps/web.py:1505 cps/web.py:1509 -#: cps/web.py:1515 +#: cps/templates/layout.html:85 cps/templates/register.html:17 cps/web.py:1551 +#: cps/web.py:1558 cps/web.py:1564 cps/web.py:1583 cps/web.py:1587 +#: cps/web.py:1593 msgid "Register" msgstr "Registra" -#: cps/web.py:1507 +#: cps/web.py:1585 msgid "Your e-mail is not allowed to register" msgstr "Il tuo e-mail non è autorizzato alla registrazione" -#: cps/web.py:1510 +#: cps/web.py:1588 msgid "Confirmation e-mail was send to your e-mail account." msgstr "Un messaggio di conferma è stato inviato al tuo recapito e-mail." -#: cps/web.py:1524 +#: cps/web.py:1602 msgid "Cannot activate LDAP authentication" msgstr "Non posso attivare l'autenticazione LDAP" -#: cps/web.py:1543 +#: cps/web.py:1621 #, python-format msgid "Fallback Login as: '%(nickname)s', LDAP Server not reachable, or user not known" msgstr "Fallback login come: '%(nickname)s', il server LDAP non è raggiungibile o l'utente è sconosciuto" -#: cps/web.py:1549 +#: cps/web.py:1627 #, python-format msgid "Could not login: %(message)s" msgstr "Non posso accedere: %(message)s" -#: cps/web.py:1553 cps/web.py:1578 +#: cps/web.py:1631 cps/web.py:1656 msgid "Wrong Username or Password" msgstr "Nome utente o password errati" -#: cps/web.py:1560 +#: cps/web.py:1638 msgid "New Password was send to your email address" msgstr "Una nuova password è stata inviata al tuo recapito e-mail" -#: cps/web.py:1566 +#: cps/web.py:1644 msgid "Please enter valid username to reset password" msgstr "Per favore digita un nome di utente valido per resettare la password" -#: cps/web.py:1573 +#: cps/web.py:1651 #, python-format msgid "You are now logged in as: '%(nickname)s'" msgstr "Ora sei connesso come '%(nickname)s'" -#: cps/web.py:1639 cps/web.py:1688 +#: cps/web.py:1717 cps/web.py:1766 #, python-format msgid "%(name)s's profile" msgstr "Profilo di %(name)s" -#: cps/web.py:1655 +#: cps/web.py:1733 msgid "Profile updated" msgstr "Profilo aggiornato" @@ -1310,36 +1334,36 @@ msgstr "Profilo aggiornato" msgid "Found no valid gmail.json file with OAuth information" msgstr "Ho trovato un gmail.json file senza informazione OAuth" -#: cps/tasks/convert.py:137 +#: cps/tasks/convert.py:154 #, python-format msgid "Calibre ebook-convert %(tool)s not found" msgstr "Non ho trovato il convertitore %(tool)s di libri di Calibre" -#: cps/tasks/convert.py:163 +#: cps/tasks/convert.py:187 #, python-format msgid "%(format)s format not found on disk" msgstr "Non ho trovato il formato %(format)s nel disco" -#: cps/tasks/convert.py:167 +#: cps/tasks/convert.py:191 msgid "Ebook converter failed with unknown error" msgstr "La conversione del libro è terminata con un errore sconosciuto" -#: cps/tasks/convert.py:177 +#: cps/tasks/convert.py:201 #, python-format msgid "Kepubify-converter failed: %(error)s" msgstr "Si è verificato un errore con il convertitore Kepubify: %(error)s" -#: cps/tasks/convert.py:199 +#: cps/tasks/convert.py:223 #, python-format msgid "Converted file not found or more than one file in folder %(folder)s" msgstr "Non ho trovato il file convertito o ci sono più di un file nella cartella %(folder)s" -#: cps/tasks/convert.py:222 +#: cps/tasks/convert.py:246 #, python-format msgid "Ebook-converter failed: %(error)s" msgstr "Errore nel convertitore: %(error)s" -#: cps/tasks/convert.py:245 +#: cps/tasks/convert.py:269 #, python-format msgid "Calibre failed with error: %(error)s" msgstr "Si è verificato un errore con Calibre: %(error)s" @@ -1394,7 +1418,7 @@ msgid "Edit" msgstr "Modifica" #: cps/templates/admin.html:25 cps/templates/book_edit.html:16 -#: cps/templates/book_table.html:97 cps/templates/modal_dialogs.html:63 +#: cps/templates/book_table.html:100 cps/templates/modal_dialogs.html:63 #: cps/templates/modal_dialogs.html:116 cps/templates/user_edit.html:67 #: cps/templates/user_table.html:149 msgid "Delete" @@ -1404,179 +1428,179 @@ msgstr "Elimina" msgid "Public Shelf" msgstr "Scaffale pubblico" -#: cps/templates/admin.html:51 +#: cps/templates/admin.html:53 msgid "Add New User" msgstr "Aggiungi un nuovo utente" -#: cps/templates/admin.html:53 +#: cps/templates/admin.html:55 msgid "Import LDAP Users" msgstr "Importa gli utenti LDAP" -#: cps/templates/admin.html:60 +#: cps/templates/admin.html:62 msgid "E-mail Server Settings" msgstr "Configurazione server e-mail" -#: cps/templates/admin.html:65 cps/templates/email_edit.html:31 +#: cps/templates/admin.html:67 cps/templates/email_edit.html:31 msgid "SMTP Hostname" msgstr "Indirizzo server SMTP" -#: cps/templates/admin.html:69 cps/templates/email_edit.html:35 +#: cps/templates/admin.html:71 cps/templates/email_edit.html:35 msgid "SMTP Port" msgstr "Porta SMTP" -#: cps/templates/admin.html:73 cps/templates/email_edit.html:39 +#: cps/templates/admin.html:75 cps/templates/email_edit.html:39 msgid "Encryption" msgstr "Crittografia" -#: cps/templates/admin.html:77 cps/templates/email_edit.html:47 +#: cps/templates/admin.html:79 cps/templates/email_edit.html:47 msgid "SMTP Login" msgstr "Login SMTP" -#: cps/templates/admin.html:81 cps/templates/admin.html:92 +#: cps/templates/admin.html:83 cps/templates/admin.html:94 #: cps/templates/email_edit.html:55 msgid "From E-mail" msgstr "E-mail da" -#: cps/templates/admin.html:88 +#: cps/templates/admin.html:90 msgid "E-Mail Service" msgstr "Servizio e-mail" -#: cps/templates/admin.html:89 +#: cps/templates/admin.html:91 msgid "Gmail via Oauth2" msgstr "Gmail via Oauth2" -#: cps/templates/admin.html:104 +#: cps/templates/admin.html:106 msgid "Configuration" msgstr "Configurazione" -#: cps/templates/admin.html:107 +#: cps/templates/admin.html:109 msgid "Calibre Database Directory" msgstr "Cartella del database di Calibre" -#: cps/templates/admin.html:111 cps/templates/config_edit.html:68 +#: cps/templates/admin.html:113 cps/templates/config_edit.html:68 msgid "Log Level" msgstr "Livello di log" -#: cps/templates/admin.html:115 +#: cps/templates/admin.html:117 msgid "Port" msgstr "Porta" -#: cps/templates/admin.html:120 +#: cps/templates/admin.html:122 msgid "External Port" msgstr "Porta esterna" -#: cps/templates/admin.html:127 cps/templates/config_view_edit.html:28 +#: cps/templates/admin.html:129 cps/templates/config_view_edit.html:28 msgid "Books per Page" msgstr "Libri per pagina" -#: cps/templates/admin.html:131 +#: cps/templates/admin.html:133 msgid "Uploads" msgstr "Uploads" -#: cps/templates/admin.html:135 +#: cps/templates/admin.html:137 msgid "Anonymous Browsing" msgstr "Navigazione anonima" -#: cps/templates/admin.html:139 +#: cps/templates/admin.html:141 msgid "Public Registration" msgstr "Registrazione pubblica" -#: cps/templates/admin.html:143 +#: cps/templates/admin.html:145 msgid "Magic Link Remote Login" msgstr "Magic Link Login remoto" -#: cps/templates/admin.html:147 +#: cps/templates/admin.html:149 msgid "Reverse Proxy Login" msgstr "Login reverse proxy" -#: cps/templates/admin.html:152 cps/templates/config_edit.html:173 +#: cps/templates/admin.html:154 cps/templates/config_edit.html:173 msgid "Reverse Proxy Header Name" msgstr "Nome dell'intestazione Reverse Proxy" -#: cps/templates/admin.html:157 +#: cps/templates/admin.html:159 msgid "Edit Calibre Database Configuration" msgstr "Modifica la configurazione del Database di Calibre" -#: cps/templates/admin.html:158 +#: cps/templates/admin.html:160 msgid "Edit Basic Configuration" msgstr "Modifica la configurazione di base" -#: cps/templates/admin.html:159 +#: cps/templates/admin.html:161 msgid "Edit UI Configuration" msgstr "Modifica la configurazione dell'interfaccia utente" -#: cps/templates/admin.html:164 +#: cps/templates/admin.html:166 msgid "Administration" msgstr "Amministrazione" -#: cps/templates/admin.html:165 +#: cps/templates/admin.html:167 msgid "Download Debug Package" msgstr "Scarica Debug Package" -#: cps/templates/admin.html:166 +#: cps/templates/admin.html:168 msgid "View Logs" msgstr "Visualizza Logfile" -#: cps/templates/admin.html:169 +#: cps/templates/admin.html:171 msgid "Reconnect Calibre Database" msgstr "Ricollega il database di Calibre" -#: cps/templates/admin.html:170 +#: cps/templates/admin.html:172 msgid "Restart" msgstr "Riavvia Calibre-Web" -#: cps/templates/admin.html:171 +#: cps/templates/admin.html:173 msgid "Shutdown" msgstr "Arresta Calibre-Web" -#: cps/templates/admin.html:176 +#: cps/templates/admin.html:178 msgid "Update" msgstr "Aggiornamento" -#: cps/templates/admin.html:180 +#: cps/templates/admin.html:182 msgid "Version" msgstr "Versione" -#: cps/templates/admin.html:181 +#: cps/templates/admin.html:183 msgid "Details" msgstr "Dettagli" -#: cps/templates/admin.html:187 +#: cps/templates/admin.html:189 msgid "Current version" msgstr "Versione attuale" -#: cps/templates/admin.html:194 +#: cps/templates/admin.html:196 msgid "Check for Update" msgstr "Ricerca aggiornamenti" -#: cps/templates/admin.html:195 +#: cps/templates/admin.html:197 msgid "Perform Update" msgstr "Esegui l'aggiornamento" -#: cps/templates/admin.html:208 +#: cps/templates/admin.html:210 msgid "Are you sure you want to restart?" msgstr "Vuoi veramente riavviare Calibre-Web?" -#: cps/templates/admin.html:213 cps/templates/admin.html:227 -#: cps/templates/admin.html:247 cps/templates/config_db.html:70 +#: cps/templates/admin.html:215 cps/templates/admin.html:229 +#: cps/templates/admin.html:249 cps/templates/config_db.html:70 msgid "OK" msgstr "Ok" -#: cps/templates/admin.html:214 cps/templates/admin.html:228 -#: cps/templates/book_edit.html:213 cps/templates/book_table.html:124 +#: cps/templates/admin.html:216 cps/templates/admin.html:230 +#: cps/templates/book_edit.html:213 cps/templates/book_table.html:127 #: cps/templates/config_db.html:54 cps/templates/config_edit.html:359 -#: cps/templates/config_view_edit.html:173 cps/templates/modal_dialogs.html:64 +#: cps/templates/config_view_edit.html:175 cps/templates/modal_dialogs.html:64 #: cps/templates/modal_dialogs.html:99 cps/templates/modal_dialogs.html:117 #: cps/templates/modal_dialogs.html:135 cps/templates/shelf_edit.html:27 #: cps/templates/user_edit.html:144 msgid "Cancel" msgstr "Annulla" -#: cps/templates/admin.html:226 +#: cps/templates/admin.html:228 msgid "Are you sure you want to shutdown?" msgstr "Vuoi veramente arrestare Calibre-Web?" -#: cps/templates/admin.html:238 +#: cps/templates/admin.html:240 msgid "Updating, please do not reload this page" msgstr "Aggiornamento, non ricaricare la pagina." @@ -1588,44 +1612,43 @@ msgstr "via" msgid "In Library" msgstr "Nella libreria" -#: cps/templates/author.html:26 cps/templates/index.html:72 -#: cps/templates/search.html:29 cps/templates/shelf.html:19 +#: cps/templates/author.html:26 cps/templates/index.html:73 +#: cps/templates/search.html:30 cps/templates/shelf.html:19 msgid "Sort according to book date, newest first" msgstr "Ordina secondo la data dei libri, prima i più recenti" -#: cps/templates/author.html:27 cps/templates/index.html:73 -#: cps/templates/search.html:30 cps/templates/shelf.html:20 +#: cps/templates/author.html:27 cps/templates/index.html:74 +#: cps/templates/search.html:31 cps/templates/shelf.html:20 msgid "Sort according to book date, oldest first" msgstr "Ordina secondo la data dei libri, prima i più vecchi" -#: cps/templates/author.html:28 cps/templates/index.html:74 -#: cps/templates/search.html:31 cps/templates/shelf.html:21 +#: cps/templates/author.html:28 cps/templates/index.html:75 +#: cps/templates/search.html:32 cps/templates/shelf.html:21 msgid "Sort title in alphabetical order" msgstr "Ordina i titoli in ordine alfabetico" -#: cps/templates/author.html:29 cps/templates/index.html:75 -#: cps/templates/search.html:32 cps/templates/shelf.html:22 +#: cps/templates/author.html:29 cps/templates/index.html:76 +#: cps/templates/search.html:33 cps/templates/shelf.html:22 msgid "Sort title in reverse alphabetical order" msgstr "Ordina i titoli in ordine alfabetico inverso" -#: cps/templates/author.html:30 cps/templates/index.html:78 -#: cps/templates/search.html:35 cps/templates/shelf.html:25 +#: cps/templates/author.html:30 cps/templates/index.html:79 +#: cps/templates/search.html:36 cps/templates/shelf.html:25 msgid "Sort according to publishing date, newest first" msgstr "Ordina secondo la data di pubblicazione, prima i più recenti" -#: cps/templates/author.html:31 cps/templates/index.html:79 -#: cps/templates/search.html:36 cps/templates/shelf.html:26 +#: cps/templates/author.html:31 cps/templates/index.html:80 +#: cps/templates/search.html:37 cps/templates/shelf.html:26 msgid "Sort according to publishing date, oldest first" msgstr "Ordina secondo la data di pubblicazione, prima i più vecchi" -#: cps/templates/author.html:57 cps/templates/author.html:117 -#: cps/templates/discover.html:30 cps/templates/index.html:29 -#: cps/templates/index.html:111 cps/templates/search.html:65 -#: cps/templates/shelf.html:54 +#: cps/templates/author.html:56 cps/templates/author.html:115 +#: cps/templates/index.html:29 cps/templates/index.html:112 +#: cps/templates/search.html:66 cps/templates/shelf.html:54 msgid "reduce" msgstr "riduci" -#: cps/templates/author.html:101 +#: cps/templates/author.html:99 msgid "More by" msgstr "Altro da" @@ -1750,7 +1773,7 @@ msgid "Fetch Metadata" msgstr "Ottieni metadati" #: cps/templates/book_edit.html:212 cps/templates/config_db.html:53 -#: cps/templates/config_edit.html:358 cps/templates/config_view_edit.html:172 +#: cps/templates/config_edit.html:358 cps/templates/config_view_edit.html:174 #: cps/templates/email_edit.html:65 cps/templates/shelf_edit.html:25 #: cps/templates/shelf_order.html:41 cps/templates/user_edit.html:142 msgid "Save" @@ -1878,26 +1901,34 @@ msgstr "Digita il nome di dominio" msgid "Comments" msgstr "" -#: cps/templates/book_table.html:77 cps/templates/book_table.html:79 -#: cps/templates/book_table.html:81 cps/templates/book_table.html:83 -#: cps/templates/book_table.html:87 cps/templates/book_table.html:89 -#: cps/templates/book_table.html:91 cps/templates/book_table.html:93 +#: cps/templates/book_table.html:75 +msgid "Archiv Status" +msgstr "" + +#: cps/templates/book_table.html:77 cps/templates/search_form.html:42 +msgid "Read Status" +msgstr "Stato di lettura" + +#: cps/templates/book_table.html:80 cps/templates/book_table.html:82 +#: cps/templates/book_table.html:84 cps/templates/book_table.html:86 +#: cps/templates/book_table.html:90 cps/templates/book_table.html:92 +#: cps/templates/book_table.html:96 msgid "Enter " msgstr "Conferma " -#: cps/templates/book_table.html:110 cps/templates/modal_dialogs.html:46 +#: cps/templates/book_table.html:113 cps/templates/modal_dialogs.html:46 msgid "Are you really sure?" msgstr "Sei veramente sicuro?" -#: cps/templates/book_table.html:114 +#: cps/templates/book_table.html:117 msgid "Books with Title will be merged from:" msgstr "I libri con il titolo vengono uniti da:" -#: cps/templates/book_table.html:118 +#: cps/templates/book_table.html:121 msgid "Into Book with Title:" msgstr "Nel libro con il titolo:" -#: cps/templates/book_table.html:123 +#: cps/templates/book_table.html:126 msgid "Merge" msgstr "Unisci" @@ -2073,11 +2104,6 @@ msgstr "Porta del server LDAP" msgid "LDAP Encryption" msgstr "Crittografia LDAP" -#: cps/templates/config_edit.html:204 cps/templates/config_view_edit.html:62 -#: cps/templates/email_edit.html:41 -msgid "None" -msgstr "Nessuna" - #: cps/templates/config_edit.html:205 msgid "TLS" msgstr "TLS" @@ -2294,11 +2320,11 @@ msgstr "Visibilità predefinita per i nuovi utenti" msgid "Show Random Books in Detail View" msgstr "Mostra libri scelti aleatoriamente nella vista dettagliata" -#: cps/templates/config_view_edit.html:165 cps/templates/user_edit.html:87 +#: cps/templates/config_view_edit.html:166 cps/templates/user_edit.html:87 msgid "Add Allowed/Denied Tags" msgstr "Aggiungi categorie permesse/negate" -#: cps/templates/config_view_edit.html:166 +#: cps/templates/config_view_edit.html:167 msgid "Add Allowed/Denied custom column values" msgstr "Aggiungi valori personali permetti/nega nelle colonne" @@ -2347,13 +2373,13 @@ msgstr "Archiviato" msgid "Description:" msgstr "Descrizione:" -#: cps/templates/detail.html:256 cps/templates/search.html:14 +#: cps/templates/detail.html:256 cps/templates/search.html:15 msgid "Add to shelf" msgstr "Aggiungi allo scaffale" #: cps/templates/detail.html:267 cps/templates/detail.html:284 #: cps/templates/feed.xml:79 cps/templates/layout.html:137 -#: cps/templates/search.html:20 +#: cps/templates/search.html:21 msgid "(Public)" msgstr "(Pubblico)" @@ -2431,10 +2457,15 @@ msgstr "Dominii bloccati per la registrazione (Blacklist)" msgid "Next" msgstr "Prossimo" -#: cps/templates/generate_kobo_auth_url.html:5 +#: cps/templates/generate_kobo_auth_url.html:6 msgid "Open the .kobo/Kobo eReader.conf file in a text editor and add (or edit):" msgstr "Apri il file .kobo/Kobo eReader.conf in un editore di testi e aggiungi (o edita):" +#: cps/templates/generate_kobo_auth_url.html:11 +#, fuzzy +msgid "Kobo Token:" +msgstr "Token Kobo Sync" + #: cps/templates/http_error.html:31 msgid "Calibre-Web Instance is unconfigured, please contact your administrator" msgstr "L'istanza Calibre-Web non è configurata, per favore contatta l'amministratore" @@ -2451,29 +2482,29 @@ msgstr "Ritorna alla pagina principale" msgid "Logout User" msgstr "Disconnetti l'utente" -#: cps/templates/index.html:69 +#: cps/templates/index.html:70 msgid "Sort ascending according to download count" msgstr "" -#: cps/templates/index.html:70 +#: cps/templates/index.html:71 msgid "Sort descending according to download count" msgstr "" -#: cps/templates/index.html:76 cps/templates/search.html:33 +#: cps/templates/index.html:77 cps/templates/search.html:34 #: cps/templates/shelf.html:23 msgid "Sort authors in alphabetical order" msgstr "Ordina gli autori in ordine alfabetico" -#: cps/templates/index.html:77 cps/templates/search.html:34 +#: cps/templates/index.html:78 cps/templates/search.html:35 #: cps/templates/shelf.html:24 msgid "Sort authors in reverse alphabetical order" msgstr "Ordina gli autori in ordine alfabetico inverso" -#: cps/templates/index.html:81 +#: cps/templates/index.html:82 msgid "Sort ascending according to series index" msgstr "Ordina in ordine ascendente secondo l'indice della serie" -#: cps/templates/index.html:82 +#: cps/templates/index.html:83 msgid "Sort descending according to series index" msgstr "Ordina in ordine discendente secondo l'indice della serie" @@ -2903,10 +2934,6 @@ msgstr "Data di pubblicazione da" msgid "Published Date To" msgstr "Data di pubblicazione fino a" -#: cps/templates/search_form.html:42 -msgid "Read Status" -msgstr "Stato di lettura" - #: cps/templates/search_form.html:59 msgid "Exclude Tags" msgstr "Escludi categorie" diff --git a/cps/translations/ja/LC_MESSAGES/messages.mo b/cps/translations/ja/LC_MESSAGES/messages.mo index 92ccc439..2c3247e1 100644 Binary files a/cps/translations/ja/LC_MESSAGES/messages.mo and b/cps/translations/ja/LC_MESSAGES/messages.mo differ diff --git a/cps/translations/ja/LC_MESSAGES/messages.po b/cps/translations/ja/LC_MESSAGES/messages.po index 5c2aa042..ddadb332 100644 --- a/cps/translations/ja/LC_MESSAGES/messages.po +++ b/cps/translations/ja/LC_MESSAGES/messages.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Calibre-Web\n" "Report-Msgid-Bugs-To: https://github.com/janeczku/Calibre-Web\n" -"POT-Creation-Date: 2022-01-15 09:19+0100\n" +"POT-Creation-Date: 2022-04-18 20:01+0200\n" "PO-Revision-Date: 2018-02-07 02:20-0500\n" "Last-Translator: white \n" "Language: ja\n" @@ -16,581 +16,584 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.9.0\n" +"Generated-By: Babel 2.9.1\n" -#: cps/about.py:34 cps/about.py:49 cps/about.py:65 cps/converter.py:31 -msgid "not installed" -msgstr "インストールされていません" - -#: cps/about.py:47 cps/about.py:63 -msgid "installed" -msgstr "" - -#: cps/about.py:145 +#: cps/about.py:86 msgid "Statistics" msgstr "統計" -#: cps/admin.py:144 +#: cps/admin.py:141 msgid "Server restarted, please reload page" msgstr "サーバを再起動しました。ページを再読み込みしてください" -#: cps/admin.py:146 +#: cps/admin.py:143 msgid "Performing shutdown of server, please close window" msgstr "サーバをシャットダウンしています。ページを閉じてください" -#: cps/admin.py:154 +#: cps/admin.py:151 msgid "Reconnect successful" msgstr "" -#: cps/admin.py:157 +#: cps/admin.py:154 msgid "Unknown command" msgstr "" -#: cps/admin.py:167 cps/editbooks.py:707 cps/editbooks.py:721 -#: cps/editbooks.py:866 cps/editbooks.py:868 cps/editbooks.py:895 -#: cps/editbooks.py:911 cps/updater.py:584 cps/uploader.py:93 -#: cps/uploader.py:103 +#: cps/admin.py:176 cps/editbooks.py:713 cps/editbooks.py:892 +#: cps/editbooks.py:894 cps/editbooks.py:930 cps/editbooks.py:947 +#: cps/updater.py:608 cps/uploader.py:93 cps/uploader.py:103 msgid "Unknown" msgstr "不明" -#: cps/admin.py:188 +#: cps/admin.py:197 msgid "Admin page" msgstr "管理者ページ" -#: cps/admin.py:207 +#: cps/admin.py:217 msgid "Basic Configuration" msgstr "基本設定" -#: cps/admin.py:244 +#: cps/admin.py:255 msgid "UI Configuration" msgstr "UI設定" -#: cps/admin.py:277 cps/templates/admin.html:50 +#: cps/admin.py:289 cps/templates/admin.html:51 msgid "Edit Users" msgstr "" -#: cps/admin.py:318 cps/opds.py:109 cps/opds.py:198 cps/opds.py:275 -#: cps/opds.py:327 cps/templates/grid.html:13 cps/templates/languages.html:9 +#: cps/admin.py:333 cps/opds.py:529 cps/templates/grid.html:13 #: cps/templates/list.html:13 msgid "All" msgstr "" -#: cps/admin.py:343 cps/admin.py:1615 +#: cps/admin.py:360 cps/admin.py:1648 msgid "User not found" msgstr "" -#: cps/admin.py:357 +#: cps/admin.py:374 msgid "{} users deleted successfully" msgstr "" -#: cps/admin.py:379 cps/templates/config_view_edit.html:133 +#: cps/admin.py:397 cps/templates/config_view_edit.html:133 #: cps/templates/user_edit.html:45 cps/templates/user_table.html:81 msgid "Show All" msgstr "" -#: cps/admin.py:400 cps/admin.py:406 +#: cps/admin.py:418 cps/admin.py:424 msgid "Malformed request" msgstr "" -#: cps/admin.py:418 cps/admin.py:1493 +#: cps/admin.py:436 cps/admin.py:1526 msgid "Guest Name can't be changed" msgstr "" -#: cps/admin.py:430 +#: cps/admin.py:448 msgid "Guest can't have this role" msgstr "" -#: cps/admin.py:442 cps/admin.py:1451 +#: cps/admin.py:460 cps/admin.py:1484 msgid "No admin user remaining, can't remove admin role" msgstr "" -#: cps/admin.py:446 cps/admin.py:460 +#: cps/admin.py:464 cps/admin.py:478 msgid "Value has to be true or false" msgstr "" -#: cps/admin.py:448 +#: cps/admin.py:466 msgid "Invalid role" msgstr "" -#: cps/admin.py:452 +#: cps/admin.py:470 msgid "Guest can't have this view" msgstr "" -#: cps/admin.py:462 +#: cps/admin.py:480 msgid "Invalid view" msgstr "" -#: cps/admin.py:465 +#: cps/admin.py:483 msgid "Guest's Locale is determined automatically and can't be set" msgstr "" -#: cps/admin.py:469 +#: cps/admin.py:487 msgid "No Valid Locale Given" msgstr "" -#: cps/admin.py:480 +#: cps/admin.py:498 msgid "No Valid Book Language Given" msgstr "" -#: cps/admin.py:482 +#: cps/admin.py:500 cps/editbooks.py:1267 msgid "Parameter not found" msgstr "" -#: cps/admin.py:533 +#: cps/admin.py:553 msgid "Invalid Read Column" msgstr "" -#: cps/admin.py:539 +#: cps/admin.py:559 msgid "Invalid Restricted Column" msgstr "" -#: cps/admin.py:560 cps/admin.py:1323 +#: cps/admin.py:579 cps/admin.py:1355 msgid "Calibre-Web configuration updated" msgstr "Calibre-Web の設定を更新しました" -#: cps/admin.py:572 +#: cps/admin.py:591 msgid "Do you really want to delete the Kobo Token?" msgstr "" -#: cps/admin.py:574 +#: cps/admin.py:593 msgid "Do you really want to delete this domain?" msgstr "" -#: cps/admin.py:576 +#: cps/admin.py:595 msgid "Do you really want to delete this user?" msgstr "" -#: cps/admin.py:578 +#: cps/admin.py:597 msgid "Are you sure you want to delete this shelf?" msgstr "" -#: cps/admin.py:580 +#: cps/admin.py:599 msgid "Are you sure you want to change locales of selected user(s)?" msgstr "" -#: cps/admin.py:582 +#: cps/admin.py:601 msgid "Are you sure you want to change visible book languages for selected user(s)?" msgstr "" -#: cps/admin.py:584 +#: cps/admin.py:603 msgid "Are you sure you want to change the selected role for the selected user(s)?" msgstr "" -#: cps/admin.py:586 +#: cps/admin.py:605 msgid "Are you sure you want to change the selected restrictions for the selected user(s)?" msgstr "" -#: cps/admin.py:588 +#: cps/admin.py:607 msgid "Are you sure you want to change the selected visibility restrictions for the selected user(s)?" msgstr "" -#: cps/admin.py:590 +#: cps/admin.py:610 msgid "Are you sure you want to change shelf sync behavior for the selected user(s)?" msgstr "" -#: cps/admin.py:592 +#: cps/admin.py:612 msgid "Are you sure you want to change Calibre library location?" msgstr "" -#: cps/admin.py:594 +#: cps/admin.py:614 msgid "Are you sure you want delete Calibre-Web's sync database to force a full sync with your Kobo Reader?" msgstr "" -#: cps/admin.py:743 +#: cps/admin.py:764 msgid "Tag not found" msgstr "" -#: cps/admin.py:755 +#: cps/admin.py:776 msgid "Invalid Action" msgstr "" -#: cps/admin.py:871 cps/admin.py:877 cps/admin.py:887 cps/admin.py:897 +#: cps/admin.py:893 cps/admin.py:899 cps/admin.py:909 cps/admin.py:919 #: cps/templates/modal_dialogs.html:29 cps/templates/user_table.html:41 #: cps/templates/user_table.html:58 msgid "Deny" msgstr "" -#: cps/admin.py:873 cps/admin.py:879 cps/admin.py:889 cps/admin.py:899 +#: cps/admin.py:895 cps/admin.py:901 cps/admin.py:911 cps/admin.py:921 #: cps/templates/modal_dialogs.html:28 cps/templates/user_table.html:44 #: cps/templates/user_table.html:61 msgid "Allow" msgstr "" -#: cps/admin.py:913 +#: cps/admin.py:936 msgid "{} sync entries deleted" msgstr "" -#: cps/admin.py:1036 +#: cps/admin.py:1059 msgid "client_secrets.json Is Not Configured For Web Application" msgstr "" -#: cps/admin.py:1081 +#: cps/admin.py:1104 msgid "Logfile Location is not Valid, Please Enter Correct Path" msgstr "" -#: cps/admin.py:1087 +#: cps/admin.py:1110 msgid "Access Logfile Location is not Valid, Please Enter Correct Path" msgstr "" -#: cps/admin.py:1117 +#: cps/admin.py:1140 msgid "Please Enter a LDAP Provider, Port, DN and User Object Identifier" msgstr "" -#: cps/admin.py:1123 +#: cps/admin.py:1146 msgid "Please Enter a LDAP Service Account and Password" msgstr "" -#: cps/admin.py:1126 +#: cps/admin.py:1149 msgid "Please Enter a LDAP Service Account" msgstr "" -#: cps/admin.py:1131 +#: cps/admin.py:1154 #, python-format msgid "LDAP Group Object Filter Needs to Have One \"%s\" Format Identifier" msgstr "" -#: cps/admin.py:1133 +#: cps/admin.py:1156 msgid "LDAP Group Object Filter Has Unmatched Parenthesis" msgstr "" -#: cps/admin.py:1137 +#: cps/admin.py:1160 #, python-format msgid "LDAP User Object Filter needs to Have One \"%s\" Format Identifier" msgstr "" -#: cps/admin.py:1139 +#: cps/admin.py:1162 msgid "LDAP User Object Filter Has Unmatched Parenthesis" msgstr "" -#: cps/admin.py:1146 +#: cps/admin.py:1169 #, python-format msgid "LDAP Member User Filter needs to Have One \"%s\" Format Identifier" msgstr "" -#: cps/admin.py:1148 +#: cps/admin.py:1171 msgid "LDAP Member User Filter Has Unmatched Parenthesis" msgstr "" -#: cps/admin.py:1155 +#: cps/admin.py:1178 msgid "LDAP CACertificate, Certificate or Key Location is not Valid, Please Enter Correct Path" msgstr "" -#: cps/admin.py:1197 cps/admin.py:1308 cps/admin.py:1405 cps/admin.py:1521 -#: cps/admin.py:1590 cps/shelf.py:100 cps/shelf.py:160 cps/shelf.py:203 -#: cps/shelf.py:279 cps/shelf.py:341 cps/shelf.py:376 cps/shelf.py:451 -msgid "Settings DB is not Writeable" -msgstr "" - -#: cps/admin.py:1208 -msgid "DB Location is not Valid, Please Enter Correct Path" -msgstr "" - -#: cps/admin.py:1223 -msgid "DB is not Writeable" -msgstr "" - -#: cps/admin.py:1235 -msgid "Keyfile Location is not Valid, Please Enter Correct Path" -msgstr "" - -#: cps/admin.py:1239 -msgid "Certfile Location is not Valid, Please Enter Correct Path" -msgstr "" - -#: cps/admin.py:1346 -#, fuzzy -msgid "Database Settings updated" -msgstr "メールサーバの設定を更新しました" - -#: cps/admin.py:1354 -#, fuzzy -msgid "Database Configuration" -msgstr "機能設定" - -#: cps/admin.py:1370 cps/web.py:1479 -msgid "Please fill out all fields!" -msgstr "全ての項目を入力してください" - -#: cps/admin.py:1378 -msgid "E-mail is not from valid domain" -msgstr "このメールは有効なドメインからのものではありません" - -#: cps/admin.py:1384 cps/admin.py:1543 -msgid "Add new user" -msgstr "新規ユーザ追加" - -#: cps/admin.py:1395 -#, python-format -msgid "User '%(user)s' created" -msgstr "ユーザ '%(user)s' を作成しました" - -#: cps/admin.py:1401 -#, fuzzy -msgid "Found an existing account for this e-mail address or name." -msgstr "このメールアドレスかニックネームで登録されたアカウントが見つかりました" - -#: cps/admin.py:1430 -#, python-format -msgid "User '%(nick)s' deleted" -msgstr "ユーザ '%(nick)s' を削除しました" - -#: cps/admin.py:1432 cps/admin.py:1433 -msgid "Can't delete Guest User" -msgstr "" - -#: cps/admin.py:1436 -msgid "No admin user remaining, can't delete user" -msgstr "" - -#: cps/admin.py:1509 cps/admin.py:1634 -#, python-format -msgid "Edit User %(nick)s" -msgstr "%(nick)s を編集" - -#: cps/admin.py:1513 -#, python-format -msgid "User '%(nick)s' updated" -msgstr "ユーザ '%(nick)s' を更新しました" - -#: cps/admin.py:1517 cps/admin.py:1649 cps/web.py:1504 cps/web.py:1564 -msgid "An unknown error occurred. Please try again later." -msgstr "不明なエラーが発生しました。あとで再試行してください。" - -#: cps/admin.py:1552 cps/templates/admin.html:98 -msgid "Edit E-mail Server Settings" -msgstr "SMTP設定を変更" - -#: cps/admin.py:1571 -msgid "Gmail Account Verification Successful" -msgstr "" - -#: cps/admin.py:1597 -#, python-format -msgid "Test e-mail queued for sending to %(email)s, please check Tasks for result" -msgstr "" - -#: cps/admin.py:1600 -#, python-format -msgid "There was an error sending the Test e-mail: %(res)s" -msgstr "テストメールを %(res)s に送信中にエラーが発生しました" - -#: cps/admin.py:1602 -msgid "Please configure your e-mail address first..." -msgstr "" - -#: cps/admin.py:1604 -msgid "E-mail server settings updated" -msgstr "メールサーバの設定を更新しました" - -#: cps/admin.py:1646 -#, python-format -msgid "Password for user %(user)s reset" -msgstr "%(user)s 用のパスワードをリセット" - -#: cps/admin.py:1652 cps/web.py:1444 -msgid "Please configure the SMTP mail settings first..." -msgstr "初めにSMTPメールの設定をしてください" - -#: cps/admin.py:1663 -msgid "Logfile viewer" -msgstr "" - -#: cps/admin.py:1729 -msgid "Requesting update package" -msgstr "更新データを要求中" - -#: cps/admin.py:1730 -msgid "Downloading update package" -msgstr "更新データをダウンロード中" - -#: cps/admin.py:1731 -msgid "Unzipping update package" -msgstr "更新データを展開中" - -#: cps/admin.py:1732 -msgid "Replacing files" -msgstr "ファイルを置換中" - -#: cps/admin.py:1733 -msgid "Database connections are closed" -msgstr "データベースの接続を切断完了" - -#: cps/admin.py:1734 -msgid "Stopping server" -msgstr "サーバ停止中" - -#: cps/admin.py:1735 -msgid "Update finished, please press okay and reload page" -msgstr "アップデート完了、OKを押してページをリロードしてください" - -#: cps/admin.py:1736 cps/admin.py:1737 cps/admin.py:1738 cps/admin.py:1739 -#: cps/admin.py:1740 cps/admin.py:1741 -msgid "Update failed:" -msgstr "アップデート失敗:" - -#: cps/admin.py:1736 cps/updater.py:385 cps/updater.py:595 cps/updater.py:597 -msgid "HTTP Error" -msgstr "HTTPエラー" - -#: cps/admin.py:1737 cps/updater.py:387 cps/updater.py:599 -msgid "Connection error" -msgstr "接続エラー" - -#: cps/admin.py:1738 cps/updater.py:389 cps/updater.py:601 -msgid "Timeout while establishing connection" -msgstr "接続を確立中にタイムアウトしました" - -#: cps/admin.py:1739 cps/updater.py:391 cps/updater.py:603 -msgid "General error" -msgstr "エラー発生" - -#: cps/admin.py:1740 -msgid "Update file could not be saved in temp dir" -msgstr "" - -#: cps/admin.py:1741 -msgid "Files could not be replaced during update" -msgstr "" - -#: cps/admin.py:1765 -msgid "Failed to extract at least One LDAP User" -msgstr "" - -#: cps/admin.py:1810 -msgid "Failed to Create at Least One LDAP User" -msgstr "" - -#: cps/admin.py:1823 -#, python-format -msgid "Error: %(ldaperror)s" -msgstr "" - -#: cps/admin.py:1827 -msgid "Error: No user returned in response of LDAP server" -msgstr "" - -#: cps/admin.py:1860 -msgid "At Least One LDAP User Not Found in Database" -msgstr "" - -#: cps/admin.py:1862 -msgid "{} User Successfully Imported" -msgstr "" - -#: cps/converter.py:30 -msgid "not configured" -msgstr "" - -#: cps/converter.py:32 -msgid "Execution permissions missing" -msgstr "" - -#: cps/db.py:651 cps/web.py:667 cps/web.py:1155 -#, python-format -msgid "Custom Column No.%(column)d is not existing in calibre database" -msgstr "" - -#: cps/editbooks.py:300 cps/editbooks.py:302 -msgid "Book Format Successfully Deleted" -msgstr "" - -#: cps/editbooks.py:309 cps/editbooks.py:311 -msgid "Book Successfully Deleted" -msgstr "" - -#: cps/editbooks.py:361 -msgid "You are missing permissions to delete books" -msgstr "" - -#: cps/editbooks.py:376 cps/editbooks.py:763 cps/web.py:523 cps/web.py:1703 -#: cps/web.py:1744 cps/web.py:1811 -msgid "Oops! Selected book title is unavailable. File does not exist or is not accessible" -msgstr "" - -#: cps/editbooks.py:410 -msgid "edit metadata" -msgstr "メタデータを編集" - -#: cps/editbooks.py:458 -#, python-format -msgid "%(seriesindex)s is not a valid number, skipping" -msgstr "" - -#: cps/editbooks.py:494 cps/editbooks.py:958 -#, fuzzy, python-format -msgid "'%(langname)s' is not a valid language" -msgstr "%(langname)s は有効な言語ではありません" - -#: cps/editbooks.py:634 cps/editbooks.py:985 -#, python-format -msgid "File extension '%(ext)s' is not allowed to be uploaded to this server" -msgstr "ファイル拡張子 '%(ext)s' をこのサーバにアップロードすることは許可されていません" - -#: cps/editbooks.py:638 cps/editbooks.py:989 -msgid "File to be uploaded must have an extension" -msgstr "アップロードするファイルには拡張子が必要です" - -#: cps/editbooks.py:650 -#, python-format -msgid "Failed to create path %(path)s (Permission denied)." -msgstr "%(path)s の作成に失敗しました (Permission denied)。" - -#: cps/editbooks.py:655 -#, python-format -msgid "Failed to store file %(file)s." -msgstr "%(file)s を保存できません。" - -#: cps/editbooks.py:673 cps/editbooks.py:1076 cps/web.py:1664 +#: cps/admin.py:1223 cps/admin.py:1339 cps/admin.py:1437 cps/admin.py:1554 +#: cps/admin.py:1623 cps/editbooks.py:678 cps/editbooks.py:882 +#: cps/editbooks.py:1130 cps/shelf.py:100 cps/shelf.py:160 cps/shelf.py:203 +#: cps/shelf.py:278 cps/shelf.py:343 cps/shelf.py:380 cps/shelf.py:456 +#: cps/web.py:1742 #, python-format msgid "Database error: %(error)s." msgstr "" -#: cps/editbooks.py:678 +#: cps/admin.py:1235 +msgid "DB Location is not Valid, Please Enter Correct Path" +msgstr "" + +#: cps/admin.py:1253 +msgid "DB is not Writeable" +msgstr "" + +#: cps/admin.py:1266 +msgid "Keyfile Location is not Valid, Please Enter Correct Path" +msgstr "" + +#: cps/admin.py:1270 +msgid "Certfile Location is not Valid, Please Enter Correct Path" +msgstr "" + +#: cps/admin.py:1378 +#, fuzzy +msgid "Database Settings updated" +msgstr "メールサーバの設定を更新しました" + +#: cps/admin.py:1386 +#, fuzzy +msgid "Database Configuration" +msgstr "機能設定" + +#: cps/admin.py:1402 cps/web.py:1557 +msgid "Please fill out all fields!" +msgstr "全ての項目を入力してください" + +#: cps/admin.py:1410 +msgid "E-mail is not from valid domain" +msgstr "このメールは有効なドメインからのものではありません" + +#: cps/admin.py:1416 cps/admin.py:1576 +msgid "Add new user" +msgstr "新規ユーザ追加" + +#: cps/admin.py:1427 +#, python-format +msgid "User '%(user)s' created" +msgstr "ユーザ '%(user)s' を作成しました" + +#: cps/admin.py:1433 +#, fuzzy +msgid "Found an existing account for this e-mail address or name." +msgstr "このメールアドレスかニックネームで登録されたアカウントが見つかりました" + +#: cps/admin.py:1463 +#, python-format +msgid "User '%(nick)s' deleted" +msgstr "ユーザ '%(nick)s' を削除しました" + +#: cps/admin.py:1465 cps/admin.py:1466 +msgid "Can't delete Guest User" +msgstr "" + +#: cps/admin.py:1469 +msgid "No admin user remaining, can't delete user" +msgstr "" + +#: cps/admin.py:1542 cps/admin.py:1667 +#, python-format +msgid "Edit User %(nick)s" +msgstr "%(nick)s を編集" + +#: cps/admin.py:1546 +#, python-format +msgid "User '%(nick)s' updated" +msgstr "ユーザ '%(nick)s' を更新しました" + +#: cps/admin.py:1550 cps/admin.py:1682 cps/web.py:1582 cps/web.py:1642 +msgid "An unknown error occurred. Please try again later." +msgstr "不明なエラーが発生しました。あとで再試行してください。" + +#: cps/admin.py:1585 cps/templates/admin.html:100 +msgid "Edit E-mail Server Settings" +msgstr "SMTP設定を変更" + +#: cps/admin.py:1604 +msgid "Gmail Account Verification Successful" +msgstr "" + +#: cps/admin.py:1630 +#, python-format +msgid "Test e-mail queued for sending to %(email)s, please check Tasks for result" +msgstr "" + +#: cps/admin.py:1633 +#, python-format +msgid "There was an error sending the Test e-mail: %(res)s" +msgstr "テストメールを %(res)s に送信中にエラーが発生しました" + +#: cps/admin.py:1635 +msgid "Please configure your e-mail address first..." +msgstr "" + +#: cps/admin.py:1637 +msgid "E-mail server settings updated" +msgstr "メールサーバの設定を更新しました" + +#: cps/admin.py:1679 +#, python-format +msgid "Password for user %(user)s reset" +msgstr "%(user)s 用のパスワードをリセット" + +#: cps/admin.py:1685 cps/web.py:1522 +msgid "Please configure the SMTP mail settings first..." +msgstr "初めにSMTPメールの設定をしてください" + +#: cps/admin.py:1696 +msgid "Logfile viewer" +msgstr "" + +#: cps/admin.py:1762 +msgid "Requesting update package" +msgstr "更新データを要求中" + +#: cps/admin.py:1763 +msgid "Downloading update package" +msgstr "更新データをダウンロード中" + +#: cps/admin.py:1764 +msgid "Unzipping update package" +msgstr "更新データを展開中" + +#: cps/admin.py:1765 +msgid "Replacing files" +msgstr "ファイルを置換中" + +#: cps/admin.py:1766 +msgid "Database connections are closed" +msgstr "データベースの接続を切断完了" + +#: cps/admin.py:1767 +msgid "Stopping server" +msgstr "サーバ停止中" + +#: cps/admin.py:1768 +msgid "Update finished, please press okay and reload page" +msgstr "アップデート完了、OKを押してページをリロードしてください" + +#: cps/admin.py:1769 cps/admin.py:1770 cps/admin.py:1771 cps/admin.py:1772 +#: cps/admin.py:1773 cps/admin.py:1774 +msgid "Update failed:" +msgstr "アップデート失敗:" + +#: cps/admin.py:1769 cps/updater.py:384 cps/updater.py:619 cps/updater.py:621 +msgid "HTTP Error" +msgstr "HTTPエラー" + +#: cps/admin.py:1770 cps/updater.py:386 cps/updater.py:623 +msgid "Connection error" +msgstr "接続エラー" + +#: cps/admin.py:1771 cps/updater.py:388 cps/updater.py:625 +msgid "Timeout while establishing connection" +msgstr "接続を確立中にタイムアウトしました" + +#: cps/admin.py:1772 cps/updater.py:390 cps/updater.py:627 +msgid "General error" +msgstr "エラー発生" + +#: cps/admin.py:1773 +msgid "Update file could not be saved in temp dir" +msgstr "" + +#: cps/admin.py:1774 +msgid "Files could not be replaced during update" +msgstr "" + +#: cps/admin.py:1798 +msgid "Failed to extract at least One LDAP User" +msgstr "" + +#: cps/admin.py:1843 +msgid "Failed to Create at Least One LDAP User" +msgstr "" + +#: cps/admin.py:1856 +#, python-format +msgid "Error: %(ldaperror)s" +msgstr "" + +#: cps/admin.py:1860 +msgid "Error: No user returned in response of LDAP server" +msgstr "" + +#: cps/admin.py:1893 +msgid "At Least One LDAP User Not Found in Database" +msgstr "" + +#: cps/admin.py:1895 +msgid "{} User Successfully Imported" +msgstr "" + +#: cps/converter.py:30 +msgid "not installed" +msgstr "インストールされていません" + +#: cps/converter.py:31 +msgid "Execution permissions missing" +msgstr "" + +#: cps/db.py:674 cps/web.py:710 cps/web.py:1222 +#, python-format +msgid "Custom Column No.%(column)d is not existing in calibre database" +msgstr "" + +#: cps/db.py:917 cps/templates/config_edit.html:204 +#: cps/templates/config_view_edit.html:62 cps/templates/email_edit.html:41 +#: cps/web.py:551 cps/web.py:585 cps/web.py:646 cps/web.py:671 cps/web.py:1003 +#: cps/web.py:1032 cps/web.py:1066 cps/web.py:1093 cps/web.py:1132 +msgid "None" +msgstr "なし" + +#: cps/editbooks.py:295 cps/editbooks.py:297 +msgid "Book Format Successfully Deleted" +msgstr "" + +#: cps/editbooks.py:304 cps/editbooks.py:306 +msgid "Book Successfully Deleted" +msgstr "" + +#: cps/editbooks.py:358 +msgid "You are missing permissions to delete books" +msgstr "" + +#: cps/editbooks.py:373 cps/editbooks.py:765 cps/web.py:518 cps/web.py:1783 +#: cps/web.py:1825 cps/web.py:1870 +msgid "Oops! Selected book title is unavailable. File does not exist or is not accessible" +msgstr "" + +#: cps/editbooks.py:408 +msgid "edit metadata" +msgstr "メタデータを編集" + +#: cps/editbooks.py:457 +#, python-format +msgid "%(seriesindex)s is not a valid number, skipping" +msgstr "" + +#: cps/editbooks.py:493 cps/editbooks.py:1001 +#, fuzzy, python-format +msgid "'%(langname)s' is not a valid language" +msgstr "%(langname)s は有効な言語ではありません" + +#: cps/editbooks.py:634 +msgid "User has no rights to upload additional file formats" +msgstr "" + +#: cps/editbooks.py:639 cps/editbooks.py:1029 +#, python-format +msgid "File extension '%(ext)s' is not allowed to be uploaded to this server" +msgstr "ファイル拡張子 '%(ext)s' をこのサーバにアップロードすることは許可されていません" + +#: cps/editbooks.py:643 cps/editbooks.py:1033 +msgid "File to be uploaded must have an extension" +msgstr "アップロードするファイルには拡張子が必要です" + +#: cps/editbooks.py:655 +#, python-format +msgid "Failed to create path %(path)s (Permission denied)." +msgstr "%(path)s の作成に失敗しました (Permission denied)。" + +#: cps/editbooks.py:660 +#, python-format +msgid "Failed to store file %(file)s." +msgstr "%(file)s を保存できません。" + +#: cps/editbooks.py:683 #, python-format msgid "File format %(ext)s added to %(book)s" msgstr "ファイル形式 %(ext)s が %(book)s に追加されました" -#: cps/editbooks.py:814 +#: cps/editbooks.py:697 cps/editbooks.py:809 +msgid "User has no rights to upload cover" +msgstr "" + +#: cps/editbooks.py:828 msgid "Identifiers are not Case Sensitive, Overwriting Old Identifier" msgstr "" -#: cps/editbooks.py:848 +#: cps/editbooks.py:869 msgid "Metadata successfully updated" msgstr "メタデータを更新しました" -#: cps/editbooks.py:861 -msgid "Error editing book, please check logfile for details" -msgstr "本の編集でエラーが発生しました。詳細はログファイルを確認してください" +#: cps/editbooks.py:887 +msgid "Error editing book: {}" +msgstr "" -#: cps/editbooks.py:899 +#: cps/editbooks.py:951 msgid "Uploaded book probably exists in the library, consider to change before upload new: " msgstr "" -#: cps/editbooks.py:997 +#: cps/editbooks.py:1041 #, python-format msgid "File %(filename)s could not saved to temp dir" msgstr "" -#: cps/editbooks.py:1016 +#: cps/editbooks.py:1061 #, python-format msgid "Failed to Move Cover File %(file)s: %(error)s" msgstr "" -#: cps/editbooks.py:1063 +#: cps/editbooks.py:1117 #, python-format msgid "File %(file)s uploaded" msgstr "" -#: cps/editbooks.py:1088 +#: cps/editbooks.py:1143 msgid "Source or destination format for conversion missing" msgstr "変換元の形式または変換後の形式が指定されていません" -#: cps/editbooks.py:1096 +#: cps/editbooks.py:1151 #, python-format msgid "Book successfully queued for converting to %(book_format)s" msgstr "本の %(book_format)s への変換がキューに追加されました" -#: cps/editbooks.py:1100 +#: cps/editbooks.py:1155 #, python-format msgid "There was an error converting this book: %(res)s" msgstr "この本の変換中にエラーが発生しました: %(res)s" @@ -603,175 +606,191 @@ msgstr "Googleドライブの設定が完了していません。Googleドライ msgid "Callback domain is not verified, please follow steps to verify domain in google developer console" msgstr "コールバックドメインが認証されていません。Google Developer Consoleでドメインを認証してください" -#: cps/helper.py:77 +#: cps/helper.py:81 #, python-format msgid "%(format)s format not found for book id: %(book)d" msgstr "ID: %(book)d の本に %(format)s フォーマットはありません" -#: cps/helper.py:83 cps/tasks/convert.py:73 +#: cps/helper.py:87 cps/tasks/convert.py:75 #, python-format msgid "%(format)s not found on Google Drive: %(fn)s" msgstr "Googleドライブ: %(fn)s に %(format)s はありません" -#: cps/helper.py:88 +#: cps/helper.py:92 #, python-format msgid "%(format)s not found: %(fn)s" msgstr "%(format)s がありません: %(fn)s" -#: cps/helper.py:93 cps/helper.py:217 cps/templates/detail.html:41 +#: cps/helper.py:97 cps/helper.py:221 cps/templates/detail.html:41 #: cps/templates/detail.html:45 msgid "Send to Kindle" msgstr "Kindleに送信" -#: cps/helper.py:94 cps/helper.py:111 cps/helper.py:219 +#: cps/helper.py:98 cps/helper.py:115 cps/helper.py:223 msgid "This e-mail has been sent via Calibre-Web." msgstr "このメールはCalibre-Web経由で送信されました。" -#: cps/helper.py:109 +#: cps/helper.py:113 msgid "Calibre-Web test e-mail" msgstr "Calibre-Web テストメール" -#: cps/helper.py:110 +#: cps/helper.py:114 msgid "Test e-mail" msgstr "テストメール" -#: cps/helper.py:127 +#: cps/helper.py:131 msgid "Get Started with Calibre-Web" msgstr "Calibre-Webを始める" -#: cps/helper.py:132 +#: cps/helper.py:136 #, python-format msgid "Registration e-mail for user: %(name)s" msgstr "ユーザ: %(name)s 用の登録メール" -#: cps/helper.py:143 cps/helper.py:149 +#: cps/helper.py:147 cps/helper.py:153 #, python-format msgid "Convert %(orig)s to %(format)s and send to Kindle" msgstr "%(orig)s を %(format)s に変換してからKindleに送信" -#: cps/helper.py:168 cps/helper.py:172 cps/helper.py:176 +#: cps/helper.py:172 cps/helper.py:176 cps/helper.py:180 #, python-format msgid "Send %(format)s to Kindle" msgstr "Kindleに %(format)s を送信" -#: cps/helper.py:216 cps/tasks/convert.py:90 +#: cps/helper.py:220 cps/tasks/convert.py:92 #, fuzzy, python-format msgid "%(book)s send to Kindle" msgstr "Kindleに送信" -#: cps/helper.py:221 +#: cps/helper.py:225 msgid "The requested file could not be read. Maybe wrong permissions?" msgstr "要求されたファイルを読み込めませんでした。権限設定が正しいか確認してください。" -#: cps/helper.py:313 +#: cps/helper.py:353 +msgid "Read status could not set: {}" +msgstr "" + +#: cps/helper.py:376 #, python-format msgid "Deleting bookfolder for book %(id)s failed, path has subfolders: %(path)s" msgstr "" -#: cps/helper.py:319 +#: cps/helper.py:382 #, python-format msgid "Deleting book %(id)s failed: %(message)s" msgstr "" -#: cps/helper.py:330 +#: cps/helper.py:393 #, python-format msgid "Deleting book %(id)s from database only, book path in database not valid: %(path)s" msgstr "" -#: cps/helper.py:385 -#, python-format -msgid "Rename title from: '%(src)s' to '%(dest)s' failed with error: %(error)s" +#: cps/helper.py:458 +#, fuzzy, python-format +msgid "Rename author from: '%(src)s' to '%(dest)s' failed with error: %(error)s" msgstr "エラー: %(error)s により、タイトルを %(src)s から %(dest)s に変更できませんでした。" -#: cps/helper.py:400 -#, python-format -msgid "Rename file in path '%(src)s' to '%(dest)s' failed with error: %(error)s" -msgstr "エラー: %(error)s により、ファイルパスを %(src)s から %(dest)s に変更できませんでした。" - -#: cps/helper.py:425 cps/helper.py:435 cps/helper.py:443 +#: cps/helper.py:529 cps/helper.py:538 #, python-format msgid "File %(file)s not found on Google Drive" msgstr "ファイル %(file)s はGoogleドライブ上にありません" -#: cps/helper.py:464 +#: cps/helper.py:572 +#, python-format +msgid "Rename title from: '%(src)s' to '%(dest)s' failed with error: %(error)s" +msgstr "エラー: %(error)s により、タイトルを %(src)s から %(dest)s に変更できませんでした。" + +#: cps/helper.py:592 +msgid "Error in rename file in path: {}" +msgstr "" + +#: cps/helper.py:610 #, python-format msgid "Book path %(path)s not found on Google Drive" msgstr "本のパス %(path)s はGoogleドライブ上にありません" -#: cps/helper.py:504 cps/web.py:1659 +#: cps/helper.py:651 cps/web.py:1737 #, fuzzy msgid "Found an existing account for this e-mail address" msgstr "このメールアドレスで登録されたアカウントがあります" -#: cps/helper.py:512 +#: cps/helper.py:659 msgid "This username is already taken" msgstr "" -#: cps/helper.py:522 +#: cps/helper.py:669 msgid "Invalid e-mail address format" msgstr "" -#: cps/helper.py:595 +#: cps/helper.py:754 +msgid "Python modul 'advocate' is not installed but is needed for cover downloads" +msgstr "" + +#: cps/helper.py:767 msgid "Error Downloading Cover" msgstr "" -#: cps/helper.py:598 +#: cps/helper.py:770 msgid "Cover Format Error" msgstr "" -#: cps/helper.py:608 +#: cps/helper.py:773 +msgid "You are not allowed to access localhost or the local network for cover uploads" +msgstr "" + +#: cps/helper.py:783 msgid "Failed to create path for cover" msgstr "" -#: cps/helper.py:624 +#: cps/helper.py:799 msgid "Cover-file is not a valid image file, or could not be stored" msgstr "" -#: cps/helper.py:635 +#: cps/helper.py:810 msgid "Only jpg/jpeg/png/webp/bmp files are supported as coverfile" msgstr "" -#: cps/helper.py:648 +#: cps/helper.py:822 msgid "Invalid cover file content" msgstr "" -#: cps/helper.py:652 +#: cps/helper.py:826 msgid "Only jpg/jpeg files are supported as coverfile" msgstr "" -#: cps/helper.py:704 +#: cps/helper.py:878 msgid "Unrar binary file not found" msgstr "" -#: cps/helper.py:715 +#: cps/helper.py:889 msgid "Error excecuting UnRar" msgstr "" -#: cps/helper.py:763 +#: cps/helper.py:937 msgid "Waiting" msgstr "待機中" -#: cps/helper.py:765 +#: cps/helper.py:939 msgid "Failed" msgstr "失敗" -#: cps/helper.py:767 +#: cps/helper.py:941 msgid "Started" msgstr "開始" -#: cps/helper.py:769 +#: cps/helper.py:943 msgid "Finished" msgstr "終了" -#: cps/helper.py:771 +#: cps/helper.py:945 msgid "Unknown Status" msgstr "不明" -#: cps/kobo_auth.py:127 -msgid "PLease access calibre-web from non localhost to get valid api_endpoint for kobo device" +#: cps/kobo_auth.py:128 +msgid "Please access Calibre-Web from non localhost to get valid api_endpoint for kobo device" msgstr "" -#: cps/kobo_auth.py:130 cps/kobo_auth.py:158 +#: cps/kobo_auth.py:154 msgid "Kobo Setup" msgstr "" @@ -780,7 +799,7 @@ msgstr "" msgid "Register with %(provider)s" msgstr "" -#: cps/oauth_bb.py:138 cps/remotelogin.py:133 cps/web.py:1535 +#: cps/oauth_bb.py:138 cps/remotelogin.py:130 cps/web.py:1613 #, python-format msgid "you are now logged in as: '%(nickname)s'" msgstr "%(nickname)s としてログイン中" @@ -841,163 +860,163 @@ msgstr "" msgid "Google Oauth error: {}" msgstr "" -#: cps/opds.py:384 +#: cps/opds.py:298 msgid "{} Stars" msgstr "" -#: cps/remotelogin.py:65 cps/templates/layout.html:84 -#: cps/templates/login.html:4 cps/templates/login.html:21 cps/web.py:1584 +#: cps/remotelogin.py:62 cps/templates/layout.html:84 +#: cps/templates/login.html:4 cps/templates/login.html:21 cps/web.py:1662 msgid "Login" msgstr "ログイン" -#: cps/remotelogin.py:77 cps/remotelogin.py:111 +#: cps/remotelogin.py:74 cps/remotelogin.py:108 msgid "Token not found" msgstr "トークンが見つかりません" -#: cps/remotelogin.py:86 cps/remotelogin.py:119 +#: cps/remotelogin.py:83 cps/remotelogin.py:116 msgid "Token has expired" msgstr "トークンが無効です" -#: cps/remotelogin.py:95 +#: cps/remotelogin.py:92 msgid "Success! Please return to your device" msgstr "成功です!端末に戻ってください" -#: cps/render_template.py:39 cps/web.py:416 +#: cps/render_template.py:41 cps/web.py:407 msgid "Books" msgstr "" -#: cps/render_template.py:41 +#: cps/render_template.py:43 msgid "Show recent books" msgstr "最近追加された本を表示" -#: cps/render_template.py:42 cps/templates/index.xml:25 +#: cps/render_template.py:44 cps/templates/index.xml:25 msgid "Hot Books" msgstr "人気の本" -#: cps/render_template.py:44 +#: cps/render_template.py:46 msgid "Show Hot Books" msgstr "" -#: cps/render_template.py:46 cps/render_template.py:51 +#: cps/render_template.py:48 cps/render_template.py:53 msgid "Downloaded Books" msgstr "" -#: cps/render_template.py:48 cps/render_template.py:53 +#: cps/render_template.py:50 cps/render_template.py:55 #: cps/templates/user_table.html:167 msgid "Show Downloaded Books" msgstr "" -#: cps/render_template.py:56 cps/templates/index.xml:32 cps/web.py:430 +#: cps/render_template.py:58 cps/templates/index.xml:32 cps/web.py:422 msgid "Top Rated Books" msgstr "" -#: cps/render_template.py:58 cps/templates/user_table.html:161 +#: cps/render_template.py:60 cps/templates/user_table.html:161 msgid "Show Top Rated Books" msgstr "" -#: cps/render_template.py:59 cps/templates/index.xml:54 -#: cps/templates/index.xml:58 cps/web.py:676 +#: cps/render_template.py:61 cps/templates/index.xml:54 +#: cps/templates/index.xml:58 cps/web.py:729 msgid "Read Books" msgstr "読んだ本" -#: cps/render_template.py:61 +#: cps/render_template.py:63 msgid "Show read and unread" msgstr "既読の本と未読の本を表示" -#: cps/render_template.py:63 cps/templates/index.xml:61 -#: cps/templates/index.xml:65 cps/web.py:679 +#: cps/render_template.py:65 cps/templates/index.xml:61 +#: cps/templates/index.xml:65 cps/web.py:732 msgid "Unread Books" msgstr "未読の本" -#: cps/render_template.py:65 +#: cps/render_template.py:67 msgid "Show unread" msgstr "" -#: cps/render_template.py:66 +#: cps/render_template.py:68 msgid "Discover" msgstr "見つける" -#: cps/render_template.py:68 cps/templates/index.xml:50 +#: cps/render_template.py:70 cps/templates/index.xml:50 #: cps/templates/user_table.html:162 msgid "Show Random Books" msgstr "ランダムで本を表示" -#: cps/render_template.py:69 cps/templates/book_table.html:67 -#: cps/templates/index.xml:83 cps/web.py:1041 +#: cps/render_template.py:71 cps/templates/book_table.html:67 +#: cps/templates/index.xml:83 cps/web.py:1135 msgid "Categories" msgstr "カテゴリ" -#: cps/render_template.py:71 cps/templates/user_table.html:158 +#: cps/render_template.py:73 cps/templates/user_table.html:158 msgid "Show category selection" msgstr "カテゴリ選択を表示" -#: cps/render_template.py:72 cps/templates/book_edit.html:90 +#: cps/render_template.py:74 cps/templates/book_edit.html:90 #: cps/templates/book_table.html:68 cps/templates/index.xml:90 -#: cps/templates/search_form.html:69 cps/web.py:948 cps/web.py:959 +#: cps/templates/search_form.html:69 cps/web.py:1034 cps/web.py:1041 msgid "Series" msgstr "シリーズ" -#: cps/render_template.py:74 cps/templates/user_table.html:157 +#: cps/render_template.py:76 cps/templates/user_table.html:157 msgid "Show series selection" msgstr "シリーズ選択を表示" -#: cps/render_template.py:75 cps/templates/book_table.html:66 +#: cps/render_template.py:77 cps/templates/book_table.html:66 #: cps/templates/index.xml:69 msgid "Authors" msgstr "著者" -#: cps/render_template.py:77 cps/templates/user_table.html:160 +#: cps/render_template.py:79 cps/templates/user_table.html:160 msgid "Show author selection" msgstr "著者選択を表示" -#: cps/render_template.py:79 cps/templates/book_table.html:72 -#: cps/templates/index.xml:76 cps/web.py:925 +#: cps/render_template.py:81 cps/templates/book_table.html:72 +#: cps/templates/index.xml:76 cps/web.py:1006 msgid "Publishers" msgstr "出版社" -#: cps/render_template.py:81 cps/templates/user_table.html:163 +#: cps/render_template.py:83 cps/templates/user_table.html:163 msgid "Show publisher selection" msgstr "出版社選択を表示" -#: cps/render_template.py:82 cps/templates/book_table.html:70 +#: cps/render_template.py:84 cps/templates/book_table.html:70 #: cps/templates/index.xml:97 cps/templates/search_form.html:107 -#: cps/web.py:1018 +#: cps/web.py:1108 msgid "Languages" msgstr "言語" -#: cps/render_template.py:85 cps/templates/user_table.html:155 +#: cps/render_template.py:87 cps/templates/user_table.html:155 msgid "Show language selection" msgstr "言語選択を表示" -#: cps/render_template.py:86 cps/templates/index.xml:104 +#: cps/render_template.py:88 cps/templates/index.xml:104 msgid "Ratings" msgstr "" -#: cps/render_template.py:88 cps/templates/user_table.html:164 +#: cps/render_template.py:90 cps/templates/user_table.html:164 msgid "Show ratings selection" msgstr "" -#: cps/render_template.py:89 cps/templates/index.xml:112 +#: cps/render_template.py:91 cps/templates/index.xml:112 msgid "File formats" msgstr "" -#: cps/render_template.py:91 cps/templates/user_table.html:165 +#: cps/render_template.py:93 cps/templates/user_table.html:165 msgid "Show file formats selection" msgstr "" -#: cps/render_template.py:93 cps/web.py:703 +#: cps/render_template.py:95 cps/web.py:755 msgid "Archived Books" msgstr "" -#: cps/render_template.py:95 cps/templates/user_table.html:166 +#: cps/render_template.py:97 cps/templates/user_table.html:166 msgid "Show archived books" msgstr "" -#: cps/render_template.py:97 cps/web.py:780 +#: cps/render_template.py:100 cps/web.py:837 msgid "Books List" msgstr "" -#: cps/render_template.py:99 cps/templates/user_table.html:168 +#: cps/render_template.py:102 cps/templates/user_table.html:168 msgid "Show Books List" msgstr "" @@ -1052,262 +1071,266 @@ msgstr "" msgid "Create a Shelf" msgstr "本棚を作成する" -#: cps/shelf.py:237 +#: cps/shelf.py:236 #, fuzzy msgid "Sorry you are not allowed to edit this shelf" msgstr "申し訳ありませんが、%(sname)s から本を削除することが許可されていません" -#: cps/shelf.py:239 +#: cps/shelf.py:238 msgid "Edit a shelf" msgstr "本棚を編集する" -#: cps/shelf.py:249 +#: cps/shelf.py:248 msgid "Sorry you are not allowed to create a public shelf" msgstr "" -#: cps/shelf.py:266 +#: cps/shelf.py:265 #, python-format msgid "Shelf %(title)s created" msgstr "%(title)s を作成しました" -#: cps/shelf.py:269 +#: cps/shelf.py:268 #, python-format msgid "Shelf %(title)s changed" msgstr "%(title)s を変更しました" -#: cps/shelf.py:283 +#: cps/shelf.py:282 msgid "There was an error" msgstr "エラーが発生しました" -#: cps/shelf.py:305 +#: cps/shelf.py:304 #, python-format msgid "A public shelf with the name '%(title)s' already exists." msgstr "" -#: cps/shelf.py:316 +#: cps/shelf.py:315 #, python-format msgid "A private shelf with the name '%(title)s' already exists." msgstr "" #: cps/shelf.py:337 +msgid "Error deleting Shelf" +msgstr "" + +#: cps/shelf.py:339 #, fuzzy msgid "Shelf successfully deleted" msgstr "メタデータを更新しました" -#: cps/shelf.py:386 +#: cps/shelf.py:389 #, python-format msgid "Change order of Shelf: '%(name)s'" msgstr "'%(name)s' 内の本の順番を変更する" -#: cps/shelf.py:456 +#: cps/shelf.py:461 #, python-format msgid "Shelf: '%(name)s'" msgstr "本棚: '%(name)s'" -#: cps/shelf.py:460 +#: cps/shelf.py:465 msgid "Error opening shelf. Shelf does not exist or is not accessible" msgstr "本棚を開けません。この本棚は存在しないかアクセスできません" -#: cps/updater.py:403 cps/updater.py:414 cps/updater.py:514 cps/updater.py:529 +#: cps/updater.py:426 cps/updater.py:437 cps/updater.py:538 cps/updater.py:553 msgid "Unexpected data while reading update information" msgstr "アップデート情報を読み込み中に予期しないデータが見つかりました" -#: cps/updater.py:410 cps/updater.py:521 +#: cps/updater.py:433 cps/updater.py:545 msgid "No update available. You already have the latest version installed" msgstr "アップデートはありません。すでに最新バージョンがインストールされています" -#: cps/updater.py:428 +#: cps/updater.py:451 msgid "A new update is available. Click on the button below to update to the latest version." msgstr "アップデートが利用可能です。下のボタンをクリックして最新バージョンにアップデートしてください。" -#: cps/updater.py:446 +#: cps/updater.py:469 msgid "Could not fetch update information" msgstr "アップデート情報を取得できません" -#: cps/updater.py:456 +#: cps/updater.py:479 msgid "Click on the button below to update to the latest stable version." msgstr "" -#: cps/updater.py:465 cps/updater.py:479 cps/updater.py:490 +#: cps/updater.py:488 cps/updater.py:502 cps/updater.py:513 #, python-format msgid "A new update is available. Click on the button below to update to version: %(version)s" msgstr "アップデートが利用可能です。下のボタンをクリックしてバージョン: %(version)s にアップデートしてください。" -#: cps/updater.py:507 +#: cps/updater.py:531 msgid "No release information available" msgstr "リリース情報がありません" -#: cps/templates/index.html:5 cps/web.py:440 +#: cps/templates/index.html:5 cps/web.py:434 msgid "Discover (Random Books)" msgstr "本を見つける (ランダムで表示)" -#: cps/web.py:471 +#: cps/web.py:470 msgid "Hot Books (Most Downloaded)" msgstr "" -#: cps/web.py:507 +#: cps/web.py:501 #, python-format msgid "Downloaded books by %(user)s" msgstr "" -#: cps/web.py:539 +#: cps/web.py:534 #, python-format msgid "Author: %(name)s" msgstr "" -#: cps/web.py:554 +#: cps/web.py:570 #, python-format msgid "Publisher: %(name)s" msgstr "出版社: %(name)s" -#: cps/web.py:569 +#: cps/web.py:598 #, python-format msgid "Series: %(serie)s" msgstr "シリーズ: %(serie)s" -#: cps/web.py:582 +#: cps/web.py:610 #, python-format msgid "Rating: %(rating)s stars" msgstr "" -#: cps/web.py:597 +#: cps/web.py:626 #, python-format msgid "File format: %(format)s" msgstr "" -#: cps/web.py:615 +#: cps/web.py:663 #, python-format msgid "Category: %(name)s" msgstr "カテゴリ: %(name)s" -#: cps/web.py:631 +#: cps/web.py:690 #, python-format msgid "Language: %(name)s" msgstr "言語: %(name)s" -#: cps/templates/layout.html:56 cps/web.py:737 cps/web.py:1371 +#: cps/templates/layout.html:56 cps/web.py:789 cps/web.py:1444 msgid "Advanced Search" msgstr "詳細検索" #: cps/templates/book_edit.html:235 cps/templates/feed.xml:33 #: cps/templates/index.xml:11 cps/templates/layout.html:45 #: cps/templates/layout.html:48 cps/templates/search_form.html:226 -#: cps/web.py:750 cps/web.py:1077 +#: cps/web.py:807 cps/web.py:1164 msgid "Search" msgstr "検索" -#: cps/templates/admin.html:16 cps/web.py:903 +#: cps/templates/admin.html:16 cps/web.py:979 msgid "Downloads" msgstr "" -#: cps/web.py:980 +#: cps/web.py:1068 msgid "Ratings list" msgstr "" -#: cps/web.py:1001 +#: cps/web.py:1095 msgid "File formats list" msgstr "" -#: cps/templates/layout.html:73 cps/templates/tasks.html:7 cps/web.py:1055 +#: cps/templates/layout.html:73 cps/templates/tasks.html:7 cps/web.py:1149 msgid "Tasks" msgstr "タスク" -#: cps/web.py:1215 +#: cps/web.py:1286 msgid "Published after " msgstr "これ以降に出版 " -#: cps/web.py:1222 +#: cps/web.py:1293 msgid "Published before " msgstr "これ以前に出版 " -#: cps/web.py:1244 +#: cps/web.py:1315 #, python-format msgid "Rating <= %(rating)s" msgstr "評価 <= %(rating)s" -#: cps/web.py:1246 +#: cps/web.py:1317 #, python-format msgid "Rating >= %(rating)s" msgstr "評価 >= %(rating)s" -#: cps/web.py:1248 +#: cps/web.py:1319 #, python-format msgid "Read Status = %(status)s" msgstr "" -#: cps/web.py:1353 +#: cps/web.py:1425 msgid "Error on search for custom columns, please restart Calibre-Web" msgstr "" -#: cps/web.py:1449 +#: cps/web.py:1527 #, python-format msgid "Book successfully queued for sending to %(kindlemail)s" msgstr "本の %(kindlemail)s への送信がキューに追加されました" -#: cps/web.py:1453 +#: cps/web.py:1531 #, python-format msgid "Oops! There was an error sending this book: %(res)s" msgstr "%(res)s を送信中にエラーが発生しました" -#: cps/web.py:1455 +#: cps/web.py:1533 msgid "Please update your profile with a valid Send to Kindle E-mail Address." msgstr "初めにKindleのメールアドレスを設定してください" -#: cps/web.py:1472 +#: cps/web.py:1550 msgid "E-Mail server is not configured, please contact your administrator!" msgstr "" -#: cps/templates/layout.html:85 cps/templates/register.html:17 cps/web.py:1473 -#: cps/web.py:1480 cps/web.py:1486 cps/web.py:1505 cps/web.py:1509 -#: cps/web.py:1515 +#: cps/templates/layout.html:85 cps/templates/register.html:17 cps/web.py:1551 +#: cps/web.py:1558 cps/web.py:1564 cps/web.py:1583 cps/web.py:1587 +#: cps/web.py:1593 msgid "Register" msgstr "登録" -#: cps/web.py:1507 +#: cps/web.py:1585 msgid "Your e-mail is not allowed to register" msgstr "このメールアドレスは登録が許可されていません" -#: cps/web.py:1510 +#: cps/web.py:1588 msgid "Confirmation e-mail was send to your e-mail account." msgstr "確認メールがこのメールアドレスに送信されました。" -#: cps/web.py:1524 +#: cps/web.py:1602 msgid "Cannot activate LDAP authentication" msgstr "" -#: cps/web.py:1543 +#: cps/web.py:1621 #, python-format msgid "Fallback Login as: '%(nickname)s', LDAP Server not reachable, or user not known" msgstr "" -#: cps/web.py:1549 +#: cps/web.py:1627 #, python-format msgid "Could not login: %(message)s" msgstr "" -#: cps/web.py:1553 cps/web.py:1578 +#: cps/web.py:1631 cps/web.py:1656 msgid "Wrong Username or Password" msgstr "ユーザ名またはパスワードが違います" -#: cps/web.py:1560 +#: cps/web.py:1638 msgid "New Password was send to your email address" msgstr "" -#: cps/web.py:1566 +#: cps/web.py:1644 msgid "Please enter valid username to reset password" msgstr "" -#: cps/web.py:1573 +#: cps/web.py:1651 #, python-format msgid "You are now logged in as: '%(nickname)s'" msgstr "" -#: cps/web.py:1639 cps/web.py:1688 +#: cps/web.py:1717 cps/web.py:1766 #, python-format msgid "%(name)s's profile" msgstr "%(name)s のプロフィール" -#: cps/web.py:1655 +#: cps/web.py:1733 msgid "Profile updated" msgstr "プロフィールを更新しました" @@ -1315,36 +1338,36 @@ msgstr "プロフィールを更新しました" msgid "Found no valid gmail.json file with OAuth information" msgstr "" -#: cps/tasks/convert.py:137 +#: cps/tasks/convert.py:154 #, python-format msgid "Calibre ebook-convert %(tool)s not found" msgstr "" -#: cps/tasks/convert.py:163 +#: cps/tasks/convert.py:187 #, python-format msgid "%(format)s format not found on disk" msgstr "" -#: cps/tasks/convert.py:167 +#: cps/tasks/convert.py:191 msgid "Ebook converter failed with unknown error" msgstr "" -#: cps/tasks/convert.py:177 +#: cps/tasks/convert.py:201 #, python-format msgid "Kepubify-converter failed: %(error)s" msgstr "" -#: cps/tasks/convert.py:199 +#: cps/tasks/convert.py:223 #, python-format msgid "Converted file not found or more than one file in folder %(folder)s" msgstr "" -#: cps/tasks/convert.py:222 +#: cps/tasks/convert.py:246 #, python-format msgid "Ebook-converter failed: %(error)s" msgstr "Ebook-converter が失敗しました: %(error)s" -#: cps/tasks/convert.py:245 +#: cps/tasks/convert.py:269 #, python-format msgid "Calibre failed with error: %(error)s" msgstr "" @@ -1399,7 +1422,7 @@ msgid "Edit" msgstr "編集" #: cps/templates/admin.html:25 cps/templates/book_edit.html:16 -#: cps/templates/book_table.html:97 cps/templates/modal_dialogs.html:63 +#: cps/templates/book_table.html:100 cps/templates/modal_dialogs.html:63 #: cps/templates/modal_dialogs.html:116 cps/templates/user_edit.html:67 #: cps/templates/user_table.html:149 msgid "Delete" @@ -1409,180 +1432,180 @@ msgstr "削除" msgid "Public Shelf" msgstr "" -#: cps/templates/admin.html:51 +#: cps/templates/admin.html:53 msgid "Add New User" msgstr "" -#: cps/templates/admin.html:53 +#: cps/templates/admin.html:55 msgid "Import LDAP Users" msgstr "" -#: cps/templates/admin.html:60 +#: cps/templates/admin.html:62 msgid "E-mail Server Settings" msgstr "" -#: cps/templates/admin.html:65 cps/templates/email_edit.html:31 +#: cps/templates/admin.html:67 cps/templates/email_edit.html:31 msgid "SMTP Hostname" msgstr "" -#: cps/templates/admin.html:69 cps/templates/email_edit.html:35 +#: cps/templates/admin.html:71 cps/templates/email_edit.html:35 msgid "SMTP Port" msgstr "" -#: cps/templates/admin.html:73 cps/templates/email_edit.html:39 +#: cps/templates/admin.html:75 cps/templates/email_edit.html:39 msgid "Encryption" msgstr "暗号化" -#: cps/templates/admin.html:77 cps/templates/email_edit.html:47 +#: cps/templates/admin.html:79 cps/templates/email_edit.html:47 msgid "SMTP Login" msgstr "" -#: cps/templates/admin.html:81 cps/templates/admin.html:92 +#: cps/templates/admin.html:83 cps/templates/admin.html:94 #: cps/templates/email_edit.html:55 msgid "From E-mail" msgstr "" -#: cps/templates/admin.html:88 +#: cps/templates/admin.html:90 msgid "E-Mail Service" msgstr "" -#: cps/templates/admin.html:89 +#: cps/templates/admin.html:91 msgid "Gmail via Oauth2" msgstr "" -#: cps/templates/admin.html:104 +#: cps/templates/admin.html:106 msgid "Configuration" msgstr "設定" -#: cps/templates/admin.html:107 +#: cps/templates/admin.html:109 msgid "Calibre Database Directory" msgstr "" -#: cps/templates/admin.html:111 cps/templates/config_edit.html:68 +#: cps/templates/admin.html:113 cps/templates/config_edit.html:68 msgid "Log Level" msgstr "ログレベル" -#: cps/templates/admin.html:115 +#: cps/templates/admin.html:117 msgid "Port" msgstr "ポート番号" -#: cps/templates/admin.html:120 +#: cps/templates/admin.html:122 msgid "External Port" msgstr "" -#: cps/templates/admin.html:127 cps/templates/config_view_edit.html:28 +#: cps/templates/admin.html:129 cps/templates/config_view_edit.html:28 msgid "Books per Page" msgstr "" -#: cps/templates/admin.html:131 +#: cps/templates/admin.html:133 msgid "Uploads" msgstr "" -#: cps/templates/admin.html:135 +#: cps/templates/admin.html:137 msgid "Anonymous Browsing" msgstr "" -#: cps/templates/admin.html:139 +#: cps/templates/admin.html:141 msgid "Public Registration" msgstr "" -#: cps/templates/admin.html:143 +#: cps/templates/admin.html:145 msgid "Magic Link Remote Login" msgstr "" -#: cps/templates/admin.html:147 +#: cps/templates/admin.html:149 msgid "Reverse Proxy Login" msgstr "" -#: cps/templates/admin.html:152 cps/templates/config_edit.html:173 +#: cps/templates/admin.html:154 cps/templates/config_edit.html:173 msgid "Reverse Proxy Header Name" msgstr "" -#: cps/templates/admin.html:157 +#: cps/templates/admin.html:159 #, fuzzy msgid "Edit Calibre Database Configuration" msgstr "Calibre-Web の設定を更新しました" -#: cps/templates/admin.html:158 +#: cps/templates/admin.html:160 msgid "Edit Basic Configuration" msgstr "" -#: cps/templates/admin.html:159 +#: cps/templates/admin.html:161 msgid "Edit UI Configuration" msgstr "" -#: cps/templates/admin.html:164 +#: cps/templates/admin.html:166 msgid "Administration" msgstr "管理" -#: cps/templates/admin.html:165 +#: cps/templates/admin.html:167 msgid "Download Debug Package" msgstr "" -#: cps/templates/admin.html:166 +#: cps/templates/admin.html:168 msgid "View Logs" msgstr "" -#: cps/templates/admin.html:169 +#: cps/templates/admin.html:171 msgid "Reconnect Calibre Database" msgstr "" -#: cps/templates/admin.html:170 +#: cps/templates/admin.html:172 msgid "Restart" msgstr "" -#: cps/templates/admin.html:171 +#: cps/templates/admin.html:173 msgid "Shutdown" msgstr "" -#: cps/templates/admin.html:176 +#: cps/templates/admin.html:178 msgid "Update" msgstr "アップデート" -#: cps/templates/admin.html:180 +#: cps/templates/admin.html:182 msgid "Version" msgstr "バージョン" -#: cps/templates/admin.html:181 +#: cps/templates/admin.html:183 msgid "Details" msgstr "詳細" -#: cps/templates/admin.html:187 +#: cps/templates/admin.html:189 msgid "Current version" msgstr "現在のバージョン" -#: cps/templates/admin.html:194 +#: cps/templates/admin.html:196 msgid "Check for Update" msgstr "" -#: cps/templates/admin.html:195 +#: cps/templates/admin.html:197 msgid "Perform Update" msgstr "更新を実行" -#: cps/templates/admin.html:208 +#: cps/templates/admin.html:210 msgid "Are you sure you want to restart?" msgstr "" -#: cps/templates/admin.html:213 cps/templates/admin.html:227 -#: cps/templates/admin.html:247 cps/templates/config_db.html:70 +#: cps/templates/admin.html:215 cps/templates/admin.html:229 +#: cps/templates/admin.html:249 cps/templates/config_db.html:70 msgid "OK" msgstr "" -#: cps/templates/admin.html:214 cps/templates/admin.html:228 -#: cps/templates/book_edit.html:213 cps/templates/book_table.html:124 +#: cps/templates/admin.html:216 cps/templates/admin.html:230 +#: cps/templates/book_edit.html:213 cps/templates/book_table.html:127 #: cps/templates/config_db.html:54 cps/templates/config_edit.html:359 -#: cps/templates/config_view_edit.html:173 cps/templates/modal_dialogs.html:64 +#: cps/templates/config_view_edit.html:175 cps/templates/modal_dialogs.html:64 #: cps/templates/modal_dialogs.html:99 cps/templates/modal_dialogs.html:117 #: cps/templates/modal_dialogs.html:135 cps/templates/shelf_edit.html:27 #: cps/templates/user_edit.html:144 msgid "Cancel" msgstr "" -#: cps/templates/admin.html:226 +#: cps/templates/admin.html:228 msgid "Are you sure you want to shutdown?" msgstr "" -#: cps/templates/admin.html:238 +#: cps/templates/admin.html:240 msgid "Updating, please do not reload this page" msgstr "" @@ -1594,44 +1617,43 @@ msgstr "経由" msgid "In Library" msgstr "ライブラリ内" -#: cps/templates/author.html:26 cps/templates/index.html:72 -#: cps/templates/search.html:29 cps/templates/shelf.html:19 +#: cps/templates/author.html:26 cps/templates/index.html:73 +#: cps/templates/search.html:30 cps/templates/shelf.html:19 msgid "Sort according to book date, newest first" msgstr "" -#: cps/templates/author.html:27 cps/templates/index.html:73 -#: cps/templates/search.html:30 cps/templates/shelf.html:20 +#: cps/templates/author.html:27 cps/templates/index.html:74 +#: cps/templates/search.html:31 cps/templates/shelf.html:20 msgid "Sort according to book date, oldest first" msgstr "" -#: cps/templates/author.html:28 cps/templates/index.html:74 -#: cps/templates/search.html:31 cps/templates/shelf.html:21 +#: cps/templates/author.html:28 cps/templates/index.html:75 +#: cps/templates/search.html:32 cps/templates/shelf.html:21 msgid "Sort title in alphabetical order" msgstr "" -#: cps/templates/author.html:29 cps/templates/index.html:75 -#: cps/templates/search.html:32 cps/templates/shelf.html:22 +#: cps/templates/author.html:29 cps/templates/index.html:76 +#: cps/templates/search.html:33 cps/templates/shelf.html:22 msgid "Sort title in reverse alphabetical order" msgstr "" -#: cps/templates/author.html:30 cps/templates/index.html:78 -#: cps/templates/search.html:35 cps/templates/shelf.html:25 +#: cps/templates/author.html:30 cps/templates/index.html:79 +#: cps/templates/search.html:36 cps/templates/shelf.html:25 msgid "Sort according to publishing date, newest first" msgstr "" -#: cps/templates/author.html:31 cps/templates/index.html:79 -#: cps/templates/search.html:36 cps/templates/shelf.html:26 +#: cps/templates/author.html:31 cps/templates/index.html:80 +#: cps/templates/search.html:37 cps/templates/shelf.html:26 msgid "Sort according to publishing date, oldest first" msgstr "" -#: cps/templates/author.html:57 cps/templates/author.html:117 -#: cps/templates/discover.html:30 cps/templates/index.html:29 -#: cps/templates/index.html:111 cps/templates/search.html:65 -#: cps/templates/shelf.html:54 +#: cps/templates/author.html:56 cps/templates/author.html:115 +#: cps/templates/index.html:29 cps/templates/index.html:112 +#: cps/templates/search.html:66 cps/templates/shelf.html:54 msgid "reduce" msgstr "減らす" -#: cps/templates/author.html:101 +#: cps/templates/author.html:99 msgid "More by" msgstr "" @@ -1756,7 +1778,7 @@ msgid "Fetch Metadata" msgstr "" #: cps/templates/book_edit.html:212 cps/templates/config_db.html:53 -#: cps/templates/config_edit.html:358 cps/templates/config_view_edit.html:172 +#: cps/templates/config_edit.html:358 cps/templates/config_view_edit.html:174 #: cps/templates/email_edit.html:65 cps/templates/shelf_edit.html:25 #: cps/templates/shelf_order.html:41 cps/templates/user_edit.html:142 msgid "Save" @@ -1885,27 +1907,35 @@ msgstr "ドメイン名を入力" msgid "Comments" msgstr "" -#: cps/templates/book_table.html:77 cps/templates/book_table.html:79 -#: cps/templates/book_table.html:81 cps/templates/book_table.html:83 -#: cps/templates/book_table.html:87 cps/templates/book_table.html:89 -#: cps/templates/book_table.html:91 cps/templates/book_table.html:93 +#: cps/templates/book_table.html:75 +msgid "Archiv Status" +msgstr "" + +#: cps/templates/book_table.html:77 cps/templates/search_form.html:42 +msgid "Read Status" +msgstr "" + +#: cps/templates/book_table.html:80 cps/templates/book_table.html:82 +#: cps/templates/book_table.html:84 cps/templates/book_table.html:86 +#: cps/templates/book_table.html:90 cps/templates/book_table.html:92 +#: cps/templates/book_table.html:96 #, fuzzy msgid "Enter " msgstr "登録" -#: cps/templates/book_table.html:110 cps/templates/modal_dialogs.html:46 +#: cps/templates/book_table.html:113 cps/templates/modal_dialogs.html:46 msgid "Are you really sure?" msgstr "よろしいですか?" -#: cps/templates/book_table.html:114 +#: cps/templates/book_table.html:117 msgid "Books with Title will be merged from:" msgstr "" -#: cps/templates/book_table.html:118 +#: cps/templates/book_table.html:121 msgid "Into Book with Title:" msgstr "" -#: cps/templates/book_table.html:123 +#: cps/templates/book_table.html:126 msgid "Merge" msgstr "" @@ -2081,11 +2111,6 @@ msgstr "" msgid "LDAP Encryption" msgstr "" -#: cps/templates/config_edit.html:204 cps/templates/config_view_edit.html:62 -#: cps/templates/email_edit.html:41 -msgid "None" -msgstr "なし" - #: cps/templates/config_edit.html:205 msgid "TLS" msgstr "" @@ -2303,11 +2328,11 @@ msgstr "" msgid "Show Random Books in Detail View" msgstr "" -#: cps/templates/config_view_edit.html:165 cps/templates/user_edit.html:87 +#: cps/templates/config_view_edit.html:166 cps/templates/user_edit.html:87 msgid "Add Allowed/Denied Tags" msgstr "" -#: cps/templates/config_view_edit.html:166 +#: cps/templates/config_view_edit.html:167 msgid "Add Allowed/Denied custom column values" msgstr "" @@ -2356,13 +2381,13 @@ msgstr "" msgid "Description:" msgstr "詳細:" -#: cps/templates/detail.html:256 cps/templates/search.html:14 +#: cps/templates/detail.html:256 cps/templates/search.html:15 msgid "Add to shelf" msgstr "本棚に追加" #: cps/templates/detail.html:267 cps/templates/detail.html:284 #: cps/templates/feed.xml:79 cps/templates/layout.html:137 -#: cps/templates/search.html:20 +#: cps/templates/search.html:21 msgid "(Public)" msgstr "" @@ -2440,10 +2465,14 @@ msgstr "" msgid "Next" msgstr "次" -#: cps/templates/generate_kobo_auth_url.html:5 +#: cps/templates/generate_kobo_auth_url.html:6 msgid "Open the .kobo/Kobo eReader.conf file in a text editor and add (or edit):" msgstr "" +#: cps/templates/generate_kobo_auth_url.html:11 +msgid "Kobo Token:" +msgstr "" + #: cps/templates/http_error.html:31 msgid "Calibre-Web Instance is unconfigured, please contact your administrator" msgstr "" @@ -2460,29 +2489,29 @@ msgstr "" msgid "Logout User" msgstr "" -#: cps/templates/index.html:69 +#: cps/templates/index.html:70 msgid "Sort ascending according to download count" msgstr "" -#: cps/templates/index.html:70 +#: cps/templates/index.html:71 msgid "Sort descending according to download count" msgstr "" -#: cps/templates/index.html:76 cps/templates/search.html:33 +#: cps/templates/index.html:77 cps/templates/search.html:34 #: cps/templates/shelf.html:23 msgid "Sort authors in alphabetical order" msgstr "" -#: cps/templates/index.html:77 cps/templates/search.html:34 +#: cps/templates/index.html:78 cps/templates/search.html:35 #: cps/templates/shelf.html:24 msgid "Sort authors in reverse alphabetical order" msgstr "" -#: cps/templates/index.html:81 +#: cps/templates/index.html:82 msgid "Sort ascending according to series index" msgstr "" -#: cps/templates/index.html:82 +#: cps/templates/index.html:83 msgid "Sort descending according to series index" msgstr "" @@ -2914,10 +2943,6 @@ msgstr "" msgid "Published Date To" msgstr "" -#: cps/templates/search_form.html:42 -msgid "Read Status" -msgstr "" - #: cps/templates/search_form.html:59 msgid "Exclude Tags" msgstr "タグを除外" diff --git a/cps/translations/km/LC_MESSAGES/messages.mo b/cps/translations/km/LC_MESSAGES/messages.mo index f941fa5d..34b973bb 100644 Binary files a/cps/translations/km/LC_MESSAGES/messages.mo and b/cps/translations/km/LC_MESSAGES/messages.mo differ diff --git a/cps/translations/km/LC_MESSAGES/messages.po b/cps/translations/km/LC_MESSAGES/messages.po index c4a2e60d..795c5861 100644 --- a/cps/translations/km/LC_MESSAGES/messages.po +++ b/cps/translations/km/LC_MESSAGES/messages.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: Calibre-Web\n" "Report-Msgid-Bugs-To: https://github.com/janeczku/Calibre-Web\n" -"POT-Creation-Date: 2022-01-15 09:19+0100\n" +"POT-Creation-Date: 2022-04-18 20:01+0200\n" "PO-Revision-Date: 2018-08-27 17:06+0700\n" "Last-Translator: \n" "Language: km_KH\n" @@ -17,585 +17,588 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.9.0\n" +"Generated-By: Babel 2.9.1\n" -#: cps/about.py:34 cps/about.py:49 cps/about.py:65 cps/converter.py:31 -msgid "not installed" -msgstr "មិនបានតម្លើង" - -#: cps/about.py:47 cps/about.py:63 -msgid "installed" -msgstr "" - -#: cps/about.py:145 +#: cps/about.py:86 msgid "Statistics" msgstr "ស្ថិតិ" -#: cps/admin.py:144 +#: cps/admin.py:141 msgid "Server restarted, please reload page" msgstr "ម៉ាស៊ីន server បានដំណើរការម្តងទៀត សូមបើកទំព័រជាថ្មី" -#: cps/admin.py:146 +#: cps/admin.py:143 msgid "Performing shutdown of server, please close window" msgstr "កំពុងបិទម៉ាស៊ីន server សូមបិទផ្ទាំងនេះ" -#: cps/admin.py:154 +#: cps/admin.py:151 msgid "Reconnect successful" msgstr "" -#: cps/admin.py:157 +#: cps/admin.py:154 msgid "Unknown command" msgstr "" -#: cps/admin.py:167 cps/editbooks.py:707 cps/editbooks.py:721 -#: cps/editbooks.py:866 cps/editbooks.py:868 cps/editbooks.py:895 -#: cps/editbooks.py:911 cps/updater.py:584 cps/uploader.py:93 -#: cps/uploader.py:103 +#: cps/admin.py:176 cps/editbooks.py:713 cps/editbooks.py:892 +#: cps/editbooks.py:894 cps/editbooks.py:930 cps/editbooks.py:947 +#: cps/updater.py:608 cps/uploader.py:93 cps/uploader.py:103 msgid "Unknown" msgstr "មិនដឹង" -#: cps/admin.py:188 +#: cps/admin.py:197 msgid "Admin page" msgstr "ទំព័ររដ្ឋបាល" -#: cps/admin.py:207 +#: cps/admin.py:217 msgid "Basic Configuration" msgstr "ការកំណត់សាមញ្ញ" -#: cps/admin.py:244 +#: cps/admin.py:255 msgid "UI Configuration" msgstr "ការកំណត់ផ្ទាំងប្រើប្រាស់" -#: cps/admin.py:277 cps/templates/admin.html:50 +#: cps/admin.py:289 cps/templates/admin.html:51 #, fuzzy msgid "Edit Users" msgstr "អ្នកប្រើប្រាស់រដ្ឋបាល" -#: cps/admin.py:318 cps/opds.py:109 cps/opds.py:198 cps/opds.py:275 -#: cps/opds.py:327 cps/templates/grid.html:13 cps/templates/languages.html:9 +#: cps/admin.py:333 cps/opds.py:529 cps/templates/grid.html:13 #: cps/templates/list.html:13 msgid "All" msgstr "" -#: cps/admin.py:343 cps/admin.py:1615 +#: cps/admin.py:360 cps/admin.py:1648 msgid "User not found" msgstr "" -#: cps/admin.py:357 +#: cps/admin.py:374 msgid "{} users deleted successfully" msgstr "" -#: cps/admin.py:379 cps/templates/config_view_edit.html:133 +#: cps/admin.py:397 cps/templates/config_view_edit.html:133 #: cps/templates/user_edit.html:45 cps/templates/user_table.html:81 msgid "Show All" msgstr "បង្ហាញទាំងអស់" -#: cps/admin.py:400 cps/admin.py:406 +#: cps/admin.py:418 cps/admin.py:424 msgid "Malformed request" msgstr "" -#: cps/admin.py:418 cps/admin.py:1493 +#: cps/admin.py:436 cps/admin.py:1526 msgid "Guest Name can't be changed" msgstr "" -#: cps/admin.py:430 +#: cps/admin.py:448 msgid "Guest can't have this role" msgstr "" -#: cps/admin.py:442 cps/admin.py:1451 +#: cps/admin.py:460 cps/admin.py:1484 msgid "No admin user remaining, can't remove admin role" msgstr "" -#: cps/admin.py:446 cps/admin.py:460 +#: cps/admin.py:464 cps/admin.py:478 msgid "Value has to be true or false" msgstr "" -#: cps/admin.py:448 +#: cps/admin.py:466 msgid "Invalid role" msgstr "" -#: cps/admin.py:452 +#: cps/admin.py:470 msgid "Guest can't have this view" msgstr "" -#: cps/admin.py:462 +#: cps/admin.py:480 msgid "Invalid view" msgstr "" -#: cps/admin.py:465 +#: cps/admin.py:483 msgid "Guest's Locale is determined automatically and can't be set" msgstr "" -#: cps/admin.py:469 +#: cps/admin.py:487 msgid "No Valid Locale Given" msgstr "" -#: cps/admin.py:480 +#: cps/admin.py:498 msgid "No Valid Book Language Given" msgstr "" -#: cps/admin.py:482 +#: cps/admin.py:500 cps/editbooks.py:1267 msgid "Parameter not found" msgstr "" -#: cps/admin.py:533 +#: cps/admin.py:553 msgid "Invalid Read Column" msgstr "" -#: cps/admin.py:539 +#: cps/admin.py:559 msgid "Invalid Restricted Column" msgstr "" -#: cps/admin.py:560 cps/admin.py:1323 +#: cps/admin.py:579 cps/admin.py:1355 msgid "Calibre-Web configuration updated" msgstr "" -#: cps/admin.py:572 +#: cps/admin.py:591 msgid "Do you really want to delete the Kobo Token?" msgstr "" -#: cps/admin.py:574 +#: cps/admin.py:593 msgid "Do you really want to delete this domain?" msgstr "" -#: cps/admin.py:576 +#: cps/admin.py:595 msgid "Do you really want to delete this user?" msgstr "" -#: cps/admin.py:578 +#: cps/admin.py:597 msgid "Are you sure you want to delete this shelf?" msgstr "តើអ្នកពិតជាចង់លុបធ្នើនេះមែនទេ?" -#: cps/admin.py:580 +#: cps/admin.py:599 #, fuzzy msgid "Are you sure you want to change locales of selected user(s)?" msgstr "តើអ្នកពិតជាចង់លុបធ្នើនេះមែនទេ?" -#: cps/admin.py:582 +#: cps/admin.py:601 msgid "Are you sure you want to change visible book languages for selected user(s)?" msgstr "" -#: cps/admin.py:584 +#: cps/admin.py:603 msgid "Are you sure you want to change the selected role for the selected user(s)?" msgstr "" -#: cps/admin.py:586 +#: cps/admin.py:605 #, fuzzy msgid "Are you sure you want to change the selected restrictions for the selected user(s)?" msgstr "តើអ្នកពិតជាចង់លុបធ្នើនេះមែនទេ?" -#: cps/admin.py:588 +#: cps/admin.py:607 msgid "Are you sure you want to change the selected visibility restrictions for the selected user(s)?" msgstr "" -#: cps/admin.py:590 +#: cps/admin.py:610 #, fuzzy msgid "Are you sure you want to change shelf sync behavior for the selected user(s)?" msgstr "តើអ្នកពិតជាចង់លុបធ្នើនេះមែនទេ?" -#: cps/admin.py:592 +#: cps/admin.py:612 #, fuzzy msgid "Are you sure you want to change Calibre library location?" msgstr "តើអ្នកពិតជាចង់លុបធ្នើនេះមែនទេ?" -#: cps/admin.py:594 +#: cps/admin.py:614 msgid "Are you sure you want delete Calibre-Web's sync database to force a full sync with your Kobo Reader?" msgstr "" -#: cps/admin.py:743 +#: cps/admin.py:764 msgid "Tag not found" msgstr "" -#: cps/admin.py:755 +#: cps/admin.py:776 msgid "Invalid Action" msgstr "" -#: cps/admin.py:871 cps/admin.py:877 cps/admin.py:887 cps/admin.py:897 +#: cps/admin.py:893 cps/admin.py:899 cps/admin.py:909 cps/admin.py:919 #: cps/templates/modal_dialogs.html:29 cps/templates/user_table.html:41 #: cps/templates/user_table.html:58 msgid "Deny" msgstr "" -#: cps/admin.py:873 cps/admin.py:879 cps/admin.py:889 cps/admin.py:899 +#: cps/admin.py:895 cps/admin.py:901 cps/admin.py:911 cps/admin.py:921 #: cps/templates/modal_dialogs.html:28 cps/templates/user_table.html:44 #: cps/templates/user_table.html:61 msgid "Allow" msgstr "" -#: cps/admin.py:913 +#: cps/admin.py:936 msgid "{} sync entries deleted" msgstr "" -#: cps/admin.py:1036 +#: cps/admin.py:1059 msgid "client_secrets.json Is Not Configured For Web Application" msgstr "" -#: cps/admin.py:1081 +#: cps/admin.py:1104 msgid "Logfile Location is not Valid, Please Enter Correct Path" msgstr "" -#: cps/admin.py:1087 +#: cps/admin.py:1110 msgid "Access Logfile Location is not Valid, Please Enter Correct Path" msgstr "" -#: cps/admin.py:1117 +#: cps/admin.py:1140 msgid "Please Enter a LDAP Provider, Port, DN and User Object Identifier" msgstr "" -#: cps/admin.py:1123 +#: cps/admin.py:1146 msgid "Please Enter a LDAP Service Account and Password" msgstr "" -#: cps/admin.py:1126 +#: cps/admin.py:1149 msgid "Please Enter a LDAP Service Account" msgstr "" -#: cps/admin.py:1131 +#: cps/admin.py:1154 #, python-format msgid "LDAP Group Object Filter Needs to Have One \"%s\" Format Identifier" msgstr "" -#: cps/admin.py:1133 +#: cps/admin.py:1156 msgid "LDAP Group Object Filter Has Unmatched Parenthesis" msgstr "" -#: cps/admin.py:1137 +#: cps/admin.py:1160 #, python-format msgid "LDAP User Object Filter needs to Have One \"%s\" Format Identifier" msgstr "" -#: cps/admin.py:1139 +#: cps/admin.py:1162 msgid "LDAP User Object Filter Has Unmatched Parenthesis" msgstr "" -#: cps/admin.py:1146 +#: cps/admin.py:1169 #, python-format msgid "LDAP Member User Filter needs to Have One \"%s\" Format Identifier" msgstr "" -#: cps/admin.py:1148 +#: cps/admin.py:1171 msgid "LDAP Member User Filter Has Unmatched Parenthesis" msgstr "" -#: cps/admin.py:1155 +#: cps/admin.py:1178 msgid "LDAP CACertificate, Certificate or Key Location is not Valid, Please Enter Correct Path" msgstr "" -#: cps/admin.py:1197 cps/admin.py:1308 cps/admin.py:1405 cps/admin.py:1521 -#: cps/admin.py:1590 cps/shelf.py:100 cps/shelf.py:160 cps/shelf.py:203 -#: cps/shelf.py:279 cps/shelf.py:341 cps/shelf.py:376 cps/shelf.py:451 -msgid "Settings DB is not Writeable" -msgstr "" - -#: cps/admin.py:1208 -msgid "DB Location is not Valid, Please Enter Correct Path" -msgstr "" - -#: cps/admin.py:1223 -msgid "DB is not Writeable" -msgstr "" - -#: cps/admin.py:1235 -msgid "Keyfile Location is not Valid, Please Enter Correct Path" -msgstr "" - -#: cps/admin.py:1239 -msgid "Certfile Location is not Valid, Please Enter Correct Path" -msgstr "" - -#: cps/admin.py:1346 -#, fuzzy -msgid "Database Settings updated" -msgstr "ទំនាក់ទំនងទៅមូលដ្ឋានទិន្នន័យត្រូវបានផ្តាច់" - -#: cps/admin.py:1354 -#, fuzzy -msgid "Database Configuration" -msgstr "ការកំណត់មុខងារ" - -#: cps/admin.py:1370 cps/web.py:1479 -msgid "Please fill out all fields!" -msgstr "សូមបំពេញចន្លោះទាំងអស់!" - -#: cps/admin.py:1378 -msgid "E-mail is not from valid domain" -msgstr "" - -#: cps/admin.py:1384 cps/admin.py:1543 -msgid "Add new user" -msgstr "បន្ថែមអ្នកប្រើប្រាស់ថ្មី" - -#: cps/admin.py:1395 -#, python-format -msgid "User '%(user)s' created" -msgstr "បានបង្កើតអ្នកប្រើប្រាស់ ‘%(user)s’" - -#: cps/admin.py:1401 -msgid "Found an existing account for this e-mail address or name." -msgstr "" - -#: cps/admin.py:1430 -#, python-format -msgid "User '%(nick)s' deleted" -msgstr "អ្នកប្រើប្រាស់ ‘%(nick)s’ ត្រូវបានលុប" - -#: cps/admin.py:1432 cps/admin.py:1433 -msgid "Can't delete Guest User" -msgstr "" - -#: cps/admin.py:1436 -msgid "No admin user remaining, can't delete user" -msgstr "" - -#: cps/admin.py:1509 cps/admin.py:1634 -#, python-format -msgid "Edit User %(nick)s" -msgstr "កែប្រែអ្នកប្រើប្រាស់ %(nick)s" - -#: cps/admin.py:1513 -#, python-format -msgid "User '%(nick)s' updated" -msgstr "អ្នកប្រើប្រាស់ ‘%(nick)s’ ត្រូវបានកែប្រែ" - -#: cps/admin.py:1517 cps/admin.py:1649 cps/web.py:1504 cps/web.py:1564 -msgid "An unknown error occurred. Please try again later." -msgstr "" - -#: cps/admin.py:1552 cps/templates/admin.html:98 -msgid "Edit E-mail Server Settings" -msgstr "ប្តូរការកំណត់ SMTP" - -#: cps/admin.py:1571 -msgid "Gmail Account Verification Successful" -msgstr "" - -#: cps/admin.py:1597 -#, python-format -msgid "Test e-mail queued for sending to %(email)s, please check Tasks for result" -msgstr "" - -#: cps/admin.py:1600 -#, python-format -msgid "There was an error sending the Test e-mail: %(res)s" -msgstr "" - -#: cps/admin.py:1602 -msgid "Please configure your e-mail address first..." -msgstr "" - -#: cps/admin.py:1604 -msgid "E-mail server settings updated" -msgstr "" - -#: cps/admin.py:1646 -#, python-format -msgid "Password for user %(user)s reset" -msgstr "" - -#: cps/admin.py:1652 cps/web.py:1444 -msgid "Please configure the SMTP mail settings first..." -msgstr "សូមកំណត់អ៊ីមែល SMTP ជាមុនសិន" - -#: cps/admin.py:1663 -msgid "Logfile viewer" -msgstr "" - -#: cps/admin.py:1729 -msgid "Requesting update package" -msgstr "កំពុងស្នើសុំឯកសារបច្ចុប្បន្នភាព" - -#: cps/admin.py:1730 -msgid "Downloading update package" -msgstr "កំពុងទាញយកឯកសារបច្ចុប្បន្នភាព" - -#: cps/admin.py:1731 -msgid "Unzipping update package" -msgstr "កំពុងពន្លាឯកសារបច្ចុប្បន្នភាព" - -#: cps/admin.py:1732 -msgid "Replacing files" -msgstr "" - -#: cps/admin.py:1733 -msgid "Database connections are closed" -msgstr "ទំនាក់ទំនងទៅមូលដ្ឋានទិន្នន័យត្រូវបានផ្តាច់" - -#: cps/admin.py:1734 -msgid "Stopping server" -msgstr "" - -#: cps/admin.py:1735 -msgid "Update finished, please press okay and reload page" -msgstr "ការធ្វើបច្ចុប្បន្នភាពបានបញ្ចប់ សូមចុច okay រួចបើកទំព័រជាថ្មី" - -#: cps/admin.py:1736 cps/admin.py:1737 cps/admin.py:1738 cps/admin.py:1739 -#: cps/admin.py:1740 cps/admin.py:1741 -msgid "Update failed:" -msgstr "" - -#: cps/admin.py:1736 cps/updater.py:385 cps/updater.py:595 cps/updater.py:597 -msgid "HTTP Error" -msgstr "" - -#: cps/admin.py:1737 cps/updater.py:387 cps/updater.py:599 -msgid "Connection error" -msgstr "" - -#: cps/admin.py:1738 cps/updater.py:389 cps/updater.py:601 -msgid "Timeout while establishing connection" -msgstr "" - -#: cps/admin.py:1739 cps/updater.py:391 cps/updater.py:603 -msgid "General error" -msgstr "" - -#: cps/admin.py:1740 -msgid "Update file could not be saved in temp dir" -msgstr "" - -#: cps/admin.py:1741 -msgid "Files could not be replaced during update" -msgstr "" - -#: cps/admin.py:1765 -msgid "Failed to extract at least One LDAP User" -msgstr "" - -#: cps/admin.py:1810 -msgid "Failed to Create at Least One LDAP User" -msgstr "" - -#: cps/admin.py:1823 -#, python-format -msgid "Error: %(ldaperror)s" -msgstr "" - -#: cps/admin.py:1827 -msgid "Error: No user returned in response of LDAP server" -msgstr "" - -#: cps/admin.py:1860 -msgid "At Least One LDAP User Not Found in Database" -msgstr "" - -#: cps/admin.py:1862 -msgid "{} User Successfully Imported" -msgstr "" - -#: cps/converter.py:30 -msgid "not configured" -msgstr "" - -#: cps/converter.py:32 -msgid "Execution permissions missing" -msgstr "" - -#: cps/db.py:651 cps/web.py:667 cps/web.py:1155 -#, python-format -msgid "Custom Column No.%(column)d is not existing in calibre database" -msgstr "" - -#: cps/editbooks.py:300 cps/editbooks.py:302 -msgid "Book Format Successfully Deleted" -msgstr "" - -#: cps/editbooks.py:309 cps/editbooks.py:311 -msgid "Book Successfully Deleted" -msgstr "" - -#: cps/editbooks.py:361 -msgid "You are missing permissions to delete books" -msgstr "" - -#: cps/editbooks.py:376 cps/editbooks.py:763 cps/web.py:523 cps/web.py:1703 -#: cps/web.py:1744 cps/web.py:1811 -msgid "Oops! Selected book title is unavailable. File does not exist or is not accessible" -msgstr "" - -#: cps/editbooks.py:410 -msgid "edit metadata" -msgstr "កែប្រែទិន្នន័យមេតា" - -#: cps/editbooks.py:458 -#, python-format -msgid "%(seriesindex)s is not a valid number, skipping" -msgstr "" - -#: cps/editbooks.py:494 cps/editbooks.py:958 -#, python-format -msgid "'%(langname)s' is not a valid language" -msgstr "" - -#: cps/editbooks.py:634 cps/editbooks.py:985 -#, python-format -msgid "File extension '%(ext)s' is not allowed to be uploaded to this server" -msgstr "ឯកសារប្រភេទ '%(ext)s' មិនត្រូវបានអនុញ្ញាតឲអាប់ឡូដទៅម៉ាស៊ីន server នេះទេ" - -#: cps/editbooks.py:638 cps/editbooks.py:989 -msgid "File to be uploaded must have an extension" -msgstr "ឯកសារដែលត្រូវអាប់ឡូដត្រូវមានកន្ទុយឯកសារ" - -#: cps/editbooks.py:650 -#, python-format -msgid "Failed to create path %(path)s (Permission denied)." -msgstr "មិនអាចបង្កើតទីតាំង %(path)s (ពុំមានសិទ្ធិ)។" - -#: cps/editbooks.py:655 -#, python-format -msgid "Failed to store file %(file)s." -msgstr "មិនអាចរក្សាទុកឯកសារ %(file)s ។" - -#: cps/editbooks.py:673 cps/editbooks.py:1076 cps/web.py:1664 +#: cps/admin.py:1223 cps/admin.py:1339 cps/admin.py:1437 cps/admin.py:1554 +#: cps/admin.py:1623 cps/editbooks.py:678 cps/editbooks.py:882 +#: cps/editbooks.py:1130 cps/shelf.py:100 cps/shelf.py:160 cps/shelf.py:203 +#: cps/shelf.py:278 cps/shelf.py:343 cps/shelf.py:380 cps/shelf.py:456 +#: cps/web.py:1742 #, python-format msgid "Database error: %(error)s." msgstr "" -#: cps/editbooks.py:678 +#: cps/admin.py:1235 +msgid "DB Location is not Valid, Please Enter Correct Path" +msgstr "" + +#: cps/admin.py:1253 +msgid "DB is not Writeable" +msgstr "" + +#: cps/admin.py:1266 +msgid "Keyfile Location is not Valid, Please Enter Correct Path" +msgstr "" + +#: cps/admin.py:1270 +msgid "Certfile Location is not Valid, Please Enter Correct Path" +msgstr "" + +#: cps/admin.py:1378 +#, fuzzy +msgid "Database Settings updated" +msgstr "ទំនាក់ទំនងទៅមូលដ្ឋានទិន្នន័យត្រូវបានផ្តាច់" + +#: cps/admin.py:1386 +#, fuzzy +msgid "Database Configuration" +msgstr "ការកំណត់មុខងារ" + +#: cps/admin.py:1402 cps/web.py:1557 +msgid "Please fill out all fields!" +msgstr "សូមបំពេញចន្លោះទាំងអស់!" + +#: cps/admin.py:1410 +msgid "E-mail is not from valid domain" +msgstr "" + +#: cps/admin.py:1416 cps/admin.py:1576 +msgid "Add new user" +msgstr "បន្ថែមអ្នកប្រើប្រាស់ថ្មី" + +#: cps/admin.py:1427 +#, python-format +msgid "User '%(user)s' created" +msgstr "បានបង្កើតអ្នកប្រើប្រាស់ ‘%(user)s’" + +#: cps/admin.py:1433 +msgid "Found an existing account for this e-mail address or name." +msgstr "" + +#: cps/admin.py:1463 +#, python-format +msgid "User '%(nick)s' deleted" +msgstr "អ្នកប្រើប្រាស់ ‘%(nick)s’ ត្រូវបានលុប" + +#: cps/admin.py:1465 cps/admin.py:1466 +msgid "Can't delete Guest User" +msgstr "" + +#: cps/admin.py:1469 +msgid "No admin user remaining, can't delete user" +msgstr "" + +#: cps/admin.py:1542 cps/admin.py:1667 +#, python-format +msgid "Edit User %(nick)s" +msgstr "កែប្រែអ្នកប្រើប្រាស់ %(nick)s" + +#: cps/admin.py:1546 +#, python-format +msgid "User '%(nick)s' updated" +msgstr "អ្នកប្រើប្រាស់ ‘%(nick)s’ ត្រូវបានកែប្រែ" + +#: cps/admin.py:1550 cps/admin.py:1682 cps/web.py:1582 cps/web.py:1642 +msgid "An unknown error occurred. Please try again later." +msgstr "" + +#: cps/admin.py:1585 cps/templates/admin.html:100 +msgid "Edit E-mail Server Settings" +msgstr "ប្តូរការកំណត់ SMTP" + +#: cps/admin.py:1604 +msgid "Gmail Account Verification Successful" +msgstr "" + +#: cps/admin.py:1630 +#, python-format +msgid "Test e-mail queued for sending to %(email)s, please check Tasks for result" +msgstr "" + +#: cps/admin.py:1633 +#, python-format +msgid "There was an error sending the Test e-mail: %(res)s" +msgstr "" + +#: cps/admin.py:1635 +msgid "Please configure your e-mail address first..." +msgstr "" + +#: cps/admin.py:1637 +msgid "E-mail server settings updated" +msgstr "" + +#: cps/admin.py:1679 +#, python-format +msgid "Password for user %(user)s reset" +msgstr "" + +#: cps/admin.py:1685 cps/web.py:1522 +msgid "Please configure the SMTP mail settings first..." +msgstr "សូមកំណត់អ៊ីមែល SMTP ជាមុនសិន" + +#: cps/admin.py:1696 +msgid "Logfile viewer" +msgstr "" + +#: cps/admin.py:1762 +msgid "Requesting update package" +msgstr "កំពុងស្នើសុំឯកសារបច្ចុប្បន្នភាព" + +#: cps/admin.py:1763 +msgid "Downloading update package" +msgstr "កំពុងទាញយកឯកសារបច្ចុប្បន្នភាព" + +#: cps/admin.py:1764 +msgid "Unzipping update package" +msgstr "កំពុងពន្លាឯកសារបច្ចុប្បន្នភាព" + +#: cps/admin.py:1765 +msgid "Replacing files" +msgstr "" + +#: cps/admin.py:1766 +msgid "Database connections are closed" +msgstr "ទំនាក់ទំនងទៅមូលដ្ឋានទិន្នន័យត្រូវបានផ្តាច់" + +#: cps/admin.py:1767 +msgid "Stopping server" +msgstr "" + +#: cps/admin.py:1768 +msgid "Update finished, please press okay and reload page" +msgstr "ការធ្វើបច្ចុប្បន្នភាពបានបញ្ចប់ សូមចុច okay រួចបើកទំព័រជាថ្មី" + +#: cps/admin.py:1769 cps/admin.py:1770 cps/admin.py:1771 cps/admin.py:1772 +#: cps/admin.py:1773 cps/admin.py:1774 +msgid "Update failed:" +msgstr "" + +#: cps/admin.py:1769 cps/updater.py:384 cps/updater.py:619 cps/updater.py:621 +msgid "HTTP Error" +msgstr "" + +#: cps/admin.py:1770 cps/updater.py:386 cps/updater.py:623 +msgid "Connection error" +msgstr "" + +#: cps/admin.py:1771 cps/updater.py:388 cps/updater.py:625 +msgid "Timeout while establishing connection" +msgstr "" + +#: cps/admin.py:1772 cps/updater.py:390 cps/updater.py:627 +msgid "General error" +msgstr "" + +#: cps/admin.py:1773 +msgid "Update file could not be saved in temp dir" +msgstr "" + +#: cps/admin.py:1774 +msgid "Files could not be replaced during update" +msgstr "" + +#: cps/admin.py:1798 +msgid "Failed to extract at least One LDAP User" +msgstr "" + +#: cps/admin.py:1843 +msgid "Failed to Create at Least One LDAP User" +msgstr "" + +#: cps/admin.py:1856 +#, python-format +msgid "Error: %(ldaperror)s" +msgstr "" + +#: cps/admin.py:1860 +msgid "Error: No user returned in response of LDAP server" +msgstr "" + +#: cps/admin.py:1893 +msgid "At Least One LDAP User Not Found in Database" +msgstr "" + +#: cps/admin.py:1895 +msgid "{} User Successfully Imported" +msgstr "" + +#: cps/converter.py:30 +msgid "not installed" +msgstr "មិនបានតម្លើង" + +#: cps/converter.py:31 +msgid "Execution permissions missing" +msgstr "" + +#: cps/db.py:674 cps/web.py:710 cps/web.py:1222 +#, python-format +msgid "Custom Column No.%(column)d is not existing in calibre database" +msgstr "" + +#: cps/db.py:917 cps/templates/config_edit.html:204 +#: cps/templates/config_view_edit.html:62 cps/templates/email_edit.html:41 +#: cps/web.py:551 cps/web.py:585 cps/web.py:646 cps/web.py:671 cps/web.py:1003 +#: cps/web.py:1032 cps/web.py:1066 cps/web.py:1093 cps/web.py:1132 +msgid "None" +msgstr "គ្មាន" + +#: cps/editbooks.py:295 cps/editbooks.py:297 +msgid "Book Format Successfully Deleted" +msgstr "" + +#: cps/editbooks.py:304 cps/editbooks.py:306 +msgid "Book Successfully Deleted" +msgstr "" + +#: cps/editbooks.py:358 +msgid "You are missing permissions to delete books" +msgstr "" + +#: cps/editbooks.py:373 cps/editbooks.py:765 cps/web.py:518 cps/web.py:1783 +#: cps/web.py:1825 cps/web.py:1870 +msgid "Oops! Selected book title is unavailable. File does not exist or is not accessible" +msgstr "" + +#: cps/editbooks.py:408 +msgid "edit metadata" +msgstr "កែប្រែទិន្នន័យមេតា" + +#: cps/editbooks.py:457 +#, python-format +msgid "%(seriesindex)s is not a valid number, skipping" +msgstr "" + +#: cps/editbooks.py:493 cps/editbooks.py:1001 +#, python-format +msgid "'%(langname)s' is not a valid language" +msgstr "" + +#: cps/editbooks.py:634 +msgid "User has no rights to upload additional file formats" +msgstr "" + +#: cps/editbooks.py:639 cps/editbooks.py:1029 +#, python-format +msgid "File extension '%(ext)s' is not allowed to be uploaded to this server" +msgstr "ឯកសារប្រភេទ '%(ext)s' មិនត្រូវបានអនុញ្ញាតឲអាប់ឡូដទៅម៉ាស៊ីន server នេះទេ" + +#: cps/editbooks.py:643 cps/editbooks.py:1033 +msgid "File to be uploaded must have an extension" +msgstr "ឯកសារដែលត្រូវអាប់ឡូដត្រូវមានកន្ទុយឯកសារ" + +#: cps/editbooks.py:655 +#, python-format +msgid "Failed to create path %(path)s (Permission denied)." +msgstr "មិនអាចបង្កើតទីតាំង %(path)s (ពុំមានសិទ្ធិ)។" + +#: cps/editbooks.py:660 +#, python-format +msgid "Failed to store file %(file)s." +msgstr "មិនអាចរក្សាទុកឯកសារ %(file)s ។" + +#: cps/editbooks.py:683 #, python-format msgid "File format %(ext)s added to %(book)s" msgstr "ឯកសារទម្រង់ %(ext)s ត្រូវបានបន្ថែមទៅ %(book)s" -#: cps/editbooks.py:814 +#: cps/editbooks.py:697 cps/editbooks.py:809 +msgid "User has no rights to upload cover" +msgstr "" + +#: cps/editbooks.py:828 msgid "Identifiers are not Case Sensitive, Overwriting Old Identifier" msgstr "" -#: cps/editbooks.py:848 +#: cps/editbooks.py:869 msgid "Metadata successfully updated" msgstr "" -#: cps/editbooks.py:861 -msgid "Error editing book, please check logfile for details" -msgstr "មានបញ្ហាពេលកែប្រែសៀវភៅ សូមពិនិត្យមើល logfile សម្រាប់ព័ត៌មានបន្ថែម" +#: cps/editbooks.py:887 +msgid "Error editing book: {}" +msgstr "" -#: cps/editbooks.py:899 +#: cps/editbooks.py:951 msgid "Uploaded book probably exists in the library, consider to change before upload new: " msgstr "" -#: cps/editbooks.py:997 +#: cps/editbooks.py:1041 #, python-format msgid "File %(filename)s could not saved to temp dir" msgstr "" -#: cps/editbooks.py:1016 +#: cps/editbooks.py:1061 #, python-format msgid "Failed to Move Cover File %(file)s: %(error)s" msgstr "" -#: cps/editbooks.py:1063 +#: cps/editbooks.py:1117 #, python-format msgid "File %(file)s uploaded" msgstr "" -#: cps/editbooks.py:1088 +#: cps/editbooks.py:1143 msgid "Source or destination format for conversion missing" msgstr "" -#: cps/editbooks.py:1096 +#: cps/editbooks.py:1151 #, python-format msgid "Book successfully queued for converting to %(book_format)s" msgstr "" -#: cps/editbooks.py:1100 +#: cps/editbooks.py:1155 #, python-format msgid "There was an error converting this book: %(res)s" msgstr "" @@ -608,174 +611,190 @@ msgstr "" msgid "Callback domain is not verified, please follow steps to verify domain in google developer console" msgstr "Callback domain មិនទាន់បានផ្ទៀងផ្ទាត់ឲប្រើទេ សូមធ្វើតាមជំហានដើម្បីផ្ទៀងផ្ទាត់ domain នៅក្នុង Google Developer Console" -#: cps/helper.py:77 +#: cps/helper.py:81 #, python-format msgid "%(format)s format not found for book id: %(book)d" msgstr "" -#: cps/helper.py:83 cps/tasks/convert.py:73 +#: cps/helper.py:87 cps/tasks/convert.py:75 #, python-format msgid "%(format)s not found on Google Drive: %(fn)s" msgstr "" -#: cps/helper.py:88 +#: cps/helper.py:92 #, python-format msgid "%(format)s not found: %(fn)s" msgstr "" -#: cps/helper.py:93 cps/helper.py:217 cps/templates/detail.html:41 +#: cps/helper.py:97 cps/helper.py:221 cps/templates/detail.html:41 #: cps/templates/detail.html:45 msgid "Send to Kindle" msgstr "ផ្ញើទៅ Kindle" -#: cps/helper.py:94 cps/helper.py:111 cps/helper.py:219 +#: cps/helper.py:98 cps/helper.py:115 cps/helper.py:223 msgid "This e-mail has been sent via Calibre-Web." msgstr "" -#: cps/helper.py:109 +#: cps/helper.py:113 msgid "Calibre-Web test e-mail" msgstr "" -#: cps/helper.py:110 +#: cps/helper.py:114 msgid "Test e-mail" msgstr "" -#: cps/helper.py:127 +#: cps/helper.py:131 msgid "Get Started with Calibre-Web" msgstr "" -#: cps/helper.py:132 +#: cps/helper.py:136 #, python-format msgid "Registration e-mail for user: %(name)s" msgstr "" -#: cps/helper.py:143 cps/helper.py:149 +#: cps/helper.py:147 cps/helper.py:153 #, python-format msgid "Convert %(orig)s to %(format)s and send to Kindle" msgstr "" -#: cps/helper.py:168 cps/helper.py:172 cps/helper.py:176 +#: cps/helper.py:172 cps/helper.py:176 cps/helper.py:180 #, python-format msgid "Send %(format)s to Kindle" msgstr "" -#: cps/helper.py:216 cps/tasks/convert.py:90 +#: cps/helper.py:220 cps/tasks/convert.py:92 #, fuzzy, python-format msgid "%(book)s send to Kindle" msgstr "ផ្ញើទៅ Kindle" -#: cps/helper.py:221 +#: cps/helper.py:225 msgid "The requested file could not be read. Maybe wrong permissions?" msgstr "ឯកសារដែលបានស្នើសុំមិនអាចបើកបានទេ។ អាចនឹងខុសសិទ្ធិប្រើប្រាស់ទេដឹង?" -#: cps/helper.py:313 +#: cps/helper.py:353 +msgid "Read status could not set: {}" +msgstr "" + +#: cps/helper.py:376 #, python-format msgid "Deleting bookfolder for book %(id)s failed, path has subfolders: %(path)s" msgstr "" -#: cps/helper.py:319 +#: cps/helper.py:382 #, python-format msgid "Deleting book %(id)s failed: %(message)s" msgstr "" -#: cps/helper.py:330 +#: cps/helper.py:393 #, python-format msgid "Deleting book %(id)s from database only, book path in database not valid: %(path)s" msgstr "" -#: cps/helper.py:385 -#, python-format -msgid "Rename title from: '%(src)s' to '%(dest)s' failed with error: %(error)s" +#: cps/helper.py:458 +#, fuzzy, python-format +msgid "Rename author from: '%(src)s' to '%(dest)s' failed with error: %(error)s" msgstr "ប្តូរចំណងជើងពី “%(src)s” ទៅជា “%(dest)s” បរាជ័យដោយបញ្ហា: %(error)s" -#: cps/helper.py:400 -#, python-format -msgid "Rename file in path '%(src)s' to '%(dest)s' failed with error: %(error)s" -msgstr "" - -#: cps/helper.py:425 cps/helper.py:435 cps/helper.py:443 +#: cps/helper.py:529 cps/helper.py:538 #, python-format msgid "File %(file)s not found on Google Drive" msgstr "ឯកសារ %(file)s រកមិនឃើញក្នុង Google Drive" -#: cps/helper.py:464 +#: cps/helper.py:572 +#, python-format +msgid "Rename title from: '%(src)s' to '%(dest)s' failed with error: %(error)s" +msgstr "ប្តូរចំណងជើងពី “%(src)s” ទៅជា “%(dest)s” បរាជ័យដោយបញ្ហា: %(error)s" + +#: cps/helper.py:592 +msgid "Error in rename file in path: {}" +msgstr "" + +#: cps/helper.py:610 #, python-format msgid "Book path %(path)s not found on Google Drive" msgstr "ទីតាំងសៀវភៅ %(path)s រកមិនឃើញក្នុង Google Drive" -#: cps/helper.py:504 cps/web.py:1659 +#: cps/helper.py:651 cps/web.py:1737 msgid "Found an existing account for this e-mail address" msgstr "" -#: cps/helper.py:512 +#: cps/helper.py:659 msgid "This username is already taken" msgstr "" -#: cps/helper.py:522 +#: cps/helper.py:669 msgid "Invalid e-mail address format" msgstr "" -#: cps/helper.py:595 +#: cps/helper.py:754 +msgid "Python modul 'advocate' is not installed but is needed for cover downloads" +msgstr "" + +#: cps/helper.py:767 msgid "Error Downloading Cover" msgstr "" -#: cps/helper.py:598 +#: cps/helper.py:770 msgid "Cover Format Error" msgstr "" -#: cps/helper.py:608 +#: cps/helper.py:773 +msgid "You are not allowed to access localhost or the local network for cover uploads" +msgstr "" + +#: cps/helper.py:783 msgid "Failed to create path for cover" msgstr "" -#: cps/helper.py:624 +#: cps/helper.py:799 msgid "Cover-file is not a valid image file, or could not be stored" msgstr "" -#: cps/helper.py:635 +#: cps/helper.py:810 msgid "Only jpg/jpeg/png/webp/bmp files are supported as coverfile" msgstr "" -#: cps/helper.py:648 +#: cps/helper.py:822 msgid "Invalid cover file content" msgstr "" -#: cps/helper.py:652 +#: cps/helper.py:826 msgid "Only jpg/jpeg files are supported as coverfile" msgstr "" -#: cps/helper.py:704 +#: cps/helper.py:878 msgid "Unrar binary file not found" msgstr "" -#: cps/helper.py:715 +#: cps/helper.py:889 msgid "Error excecuting UnRar" msgstr "" -#: cps/helper.py:763 +#: cps/helper.py:937 msgid "Waiting" msgstr "កំពុងរង់ចាំ" -#: cps/helper.py:765 +#: cps/helper.py:939 msgid "Failed" msgstr "បានបរាជ័យ" -#: cps/helper.py:767 +#: cps/helper.py:941 msgid "Started" msgstr "បានចាប់ផ្តើម" -#: cps/helper.py:769 +#: cps/helper.py:943 msgid "Finished" msgstr "បានបញ្ចប់" -#: cps/helper.py:771 +#: cps/helper.py:945 msgid "Unknown Status" msgstr "" -#: cps/kobo_auth.py:127 -msgid "PLease access calibre-web from non localhost to get valid api_endpoint for kobo device" +#: cps/kobo_auth.py:128 +msgid "Please access Calibre-Web from non localhost to get valid api_endpoint for kobo device" msgstr "" -#: cps/kobo_auth.py:130 cps/kobo_auth.py:158 +#: cps/kobo_auth.py:154 msgid "Kobo Setup" msgstr "" @@ -784,7 +803,7 @@ msgstr "" msgid "Register with %(provider)s" msgstr "" -#: cps/oauth_bb.py:138 cps/remotelogin.py:133 cps/web.py:1535 +#: cps/oauth_bb.py:138 cps/remotelogin.py:130 cps/web.py:1613 #, python-format msgid "you are now logged in as: '%(nickname)s'" msgstr "ឥឡូវអ្នកបានចូលដោយមានឈ្មោះថា៖ ‘%(nickname)s’" @@ -845,163 +864,163 @@ msgstr "" msgid "Google Oauth error: {}" msgstr "" -#: cps/opds.py:384 +#: cps/opds.py:298 msgid "{} Stars" msgstr "" -#: cps/remotelogin.py:65 cps/templates/layout.html:84 -#: cps/templates/login.html:4 cps/templates/login.html:21 cps/web.py:1584 +#: cps/remotelogin.py:62 cps/templates/layout.html:84 +#: cps/templates/login.html:4 cps/templates/login.html:21 cps/web.py:1662 msgid "Login" msgstr "ចូលប្រើប្រាស់" -#: cps/remotelogin.py:77 cps/remotelogin.py:111 +#: cps/remotelogin.py:74 cps/remotelogin.py:108 msgid "Token not found" msgstr "រកមិនឃើញវត្ថុតាង" -#: cps/remotelogin.py:86 cps/remotelogin.py:119 +#: cps/remotelogin.py:83 cps/remotelogin.py:116 msgid "Token has expired" msgstr "វត្ថុតាងហួសពេលកំណត់" -#: cps/remotelogin.py:95 +#: cps/remotelogin.py:92 msgid "Success! Please return to your device" msgstr "ជោគជ័យ! សូមវិលមកឧបករណ៍អ្នកវិញ" -#: cps/render_template.py:39 cps/web.py:416 +#: cps/render_template.py:41 cps/web.py:407 msgid "Books" msgstr "" -#: cps/render_template.py:41 +#: cps/render_template.py:43 msgid "Show recent books" msgstr "បង្ហាញសៀវភៅមកថ្មី" -#: cps/render_template.py:42 cps/templates/index.xml:25 +#: cps/render_template.py:44 cps/templates/index.xml:25 msgid "Hot Books" msgstr "សៀវភៅដែលមានប្រជាប្រិយភាព" -#: cps/render_template.py:44 +#: cps/render_template.py:46 msgid "Show Hot Books" msgstr "បង្ហាញសៀវភៅដែលមានប្រជាប្រិយភាព" -#: cps/render_template.py:46 cps/render_template.py:51 +#: cps/render_template.py:48 cps/render_template.py:53 msgid "Downloaded Books" msgstr "" -#: cps/render_template.py:48 cps/render_template.py:53 +#: cps/render_template.py:50 cps/render_template.py:55 #: cps/templates/user_table.html:167 msgid "Show Downloaded Books" msgstr "" -#: cps/render_template.py:56 cps/templates/index.xml:32 cps/web.py:430 +#: cps/render_template.py:58 cps/templates/index.xml:32 cps/web.py:422 msgid "Top Rated Books" msgstr "សៀវភៅដែលមានការវាយតម្លៃល្អជាងគេ" -#: cps/render_template.py:58 cps/templates/user_table.html:161 +#: cps/render_template.py:60 cps/templates/user_table.html:161 msgid "Show Top Rated Books" msgstr "បង្ហាញសៀវភៅដែលមានការវាយតម្លៃល្អជាងគេ" -#: cps/render_template.py:59 cps/templates/index.xml:54 -#: cps/templates/index.xml:58 cps/web.py:676 +#: cps/render_template.py:61 cps/templates/index.xml:54 +#: cps/templates/index.xml:58 cps/web.py:729 msgid "Read Books" msgstr "សៀវភៅដែលបានអានរួច" -#: cps/render_template.py:61 +#: cps/render_template.py:63 msgid "Show read and unread" msgstr "បង្ហាញអានរួច និងមិនទាន់អាន" -#: cps/render_template.py:63 cps/templates/index.xml:61 -#: cps/templates/index.xml:65 cps/web.py:679 +#: cps/render_template.py:65 cps/templates/index.xml:61 +#: cps/templates/index.xml:65 cps/web.py:732 msgid "Unread Books" msgstr "សៀវភៅដែលមិនទាន់បានអាន" -#: cps/render_template.py:65 +#: cps/render_template.py:67 msgid "Show unread" msgstr "" -#: cps/render_template.py:66 +#: cps/render_template.py:68 msgid "Discover" msgstr "ស្រាវជ្រាវ" -#: cps/render_template.py:68 cps/templates/index.xml:50 +#: cps/render_template.py:70 cps/templates/index.xml:50 #: cps/templates/user_table.html:162 msgid "Show Random Books" msgstr "បង្ហាញសៀវភៅចៃដន្យ" -#: cps/render_template.py:69 cps/templates/book_table.html:67 -#: cps/templates/index.xml:83 cps/web.py:1041 +#: cps/render_template.py:71 cps/templates/book_table.html:67 +#: cps/templates/index.xml:83 cps/web.py:1135 msgid "Categories" msgstr "ប្រភេទនានា" -#: cps/render_template.py:71 cps/templates/user_table.html:158 +#: cps/render_template.py:73 cps/templates/user_table.html:158 msgid "Show category selection" msgstr "បង្ហាញជម្រើសប្រភេទ" -#: cps/render_template.py:72 cps/templates/book_edit.html:90 +#: cps/render_template.py:74 cps/templates/book_edit.html:90 #: cps/templates/book_table.html:68 cps/templates/index.xml:90 -#: cps/templates/search_form.html:69 cps/web.py:948 cps/web.py:959 +#: cps/templates/search_form.html:69 cps/web.py:1034 cps/web.py:1041 msgid "Series" msgstr "ស៊េរី" -#: cps/render_template.py:74 cps/templates/user_table.html:157 +#: cps/render_template.py:76 cps/templates/user_table.html:157 msgid "Show series selection" msgstr "បង្ហាញជម្រើសស៊េរី" -#: cps/render_template.py:75 cps/templates/book_table.html:66 +#: cps/render_template.py:77 cps/templates/book_table.html:66 #: cps/templates/index.xml:69 msgid "Authors" msgstr "អ្នកនិពន្ធ" -#: cps/render_template.py:77 cps/templates/user_table.html:160 +#: cps/render_template.py:79 cps/templates/user_table.html:160 msgid "Show author selection" msgstr "បង្ហាញជម្រើសអ្នកនិពន្ធ" -#: cps/render_template.py:79 cps/templates/book_table.html:72 -#: cps/templates/index.xml:76 cps/web.py:925 +#: cps/render_template.py:81 cps/templates/book_table.html:72 +#: cps/templates/index.xml:76 cps/web.py:1006 msgid "Publishers" msgstr "" -#: cps/render_template.py:81 cps/templates/user_table.html:163 +#: cps/render_template.py:83 cps/templates/user_table.html:163 msgid "Show publisher selection" msgstr "" -#: cps/render_template.py:82 cps/templates/book_table.html:70 +#: cps/render_template.py:84 cps/templates/book_table.html:70 #: cps/templates/index.xml:97 cps/templates/search_form.html:107 -#: cps/web.py:1018 +#: cps/web.py:1108 msgid "Languages" msgstr "ភាសានានា" -#: cps/render_template.py:85 cps/templates/user_table.html:155 +#: cps/render_template.py:87 cps/templates/user_table.html:155 msgid "Show language selection" msgstr "បង្ហាញផ្នែកភាសា" -#: cps/render_template.py:86 cps/templates/index.xml:104 +#: cps/render_template.py:88 cps/templates/index.xml:104 msgid "Ratings" msgstr "" -#: cps/render_template.py:88 cps/templates/user_table.html:164 +#: cps/render_template.py:90 cps/templates/user_table.html:164 msgid "Show ratings selection" msgstr "" -#: cps/render_template.py:89 cps/templates/index.xml:112 +#: cps/render_template.py:91 cps/templates/index.xml:112 msgid "File formats" msgstr "" -#: cps/render_template.py:91 cps/templates/user_table.html:165 +#: cps/render_template.py:93 cps/templates/user_table.html:165 msgid "Show file formats selection" msgstr "" -#: cps/render_template.py:93 cps/web.py:703 +#: cps/render_template.py:95 cps/web.py:755 msgid "Archived Books" msgstr "" -#: cps/render_template.py:95 cps/templates/user_table.html:166 +#: cps/render_template.py:97 cps/templates/user_table.html:166 msgid "Show archived books" msgstr "" -#: cps/render_template.py:97 cps/web.py:780 +#: cps/render_template.py:100 cps/web.py:837 msgid "Books List" msgstr "" -#: cps/render_template.py:99 cps/templates/user_table.html:168 +#: cps/render_template.py:102 cps/templates/user_table.html:168 msgid "Show Books List" msgstr "" @@ -1056,261 +1075,265 @@ msgstr "" msgid "Create a Shelf" msgstr "បង្កើតធ្នើ" -#: cps/shelf.py:237 +#: cps/shelf.py:236 #, fuzzy msgid "Sorry you are not allowed to edit this shelf" msgstr "សូមអភ័យទោស អ្នកមិនមានសិទ្ធិដកសៀវភៅចេញពីធ្នើនេះទេ៖ %(sname)s" -#: cps/shelf.py:239 +#: cps/shelf.py:238 msgid "Edit a shelf" msgstr "កែប្រែធ្នើ" -#: cps/shelf.py:249 +#: cps/shelf.py:248 msgid "Sorry you are not allowed to create a public shelf" msgstr "" -#: cps/shelf.py:266 +#: cps/shelf.py:265 #, python-format msgid "Shelf %(title)s created" msgstr "ធ្នើឈ្មោះ %(title)s ត្រូវបានបង្កើត" -#: cps/shelf.py:269 +#: cps/shelf.py:268 #, python-format msgid "Shelf %(title)s changed" msgstr "ធ្នើឈ្មោះ %(title)s ត្រូវបានប្តូរ" -#: cps/shelf.py:283 +#: cps/shelf.py:282 msgid "There was an error" msgstr "មានបញ្ហា" -#: cps/shelf.py:305 +#: cps/shelf.py:304 #, python-format msgid "A public shelf with the name '%(title)s' already exists." msgstr "" -#: cps/shelf.py:316 +#: cps/shelf.py:315 #, python-format msgid "A private shelf with the name '%(title)s' already exists." msgstr "" #: cps/shelf.py:337 +msgid "Error deleting Shelf" +msgstr "" + +#: cps/shelf.py:339 msgid "Shelf successfully deleted" msgstr "" -#: cps/shelf.py:386 +#: cps/shelf.py:389 #, python-format msgid "Change order of Shelf: '%(name)s'" msgstr "ប្តូរលំដាប់ធ្នើ៖ ‘%(name)s’" -#: cps/shelf.py:456 +#: cps/shelf.py:461 #, python-format msgid "Shelf: '%(name)s'" msgstr "ធ្នើ៖ ‘%(name)s’" -#: cps/shelf.py:460 +#: cps/shelf.py:465 msgid "Error opening shelf. Shelf does not exist or is not accessible" msgstr "មានបញ្ហាពេលបើកធ្នើ។ ពុំមានធ្នើ ឬមិនអាចបើកបាន" -#: cps/updater.py:403 cps/updater.py:414 cps/updater.py:514 cps/updater.py:529 +#: cps/updater.py:426 cps/updater.py:437 cps/updater.py:538 cps/updater.py:553 msgid "Unexpected data while reading update information" msgstr "" -#: cps/updater.py:410 cps/updater.py:521 +#: cps/updater.py:433 cps/updater.py:545 msgid "No update available. You already have the latest version installed" msgstr "" -#: cps/updater.py:428 +#: cps/updater.py:451 msgid "A new update is available. Click on the button below to update to the latest version." msgstr "" -#: cps/updater.py:446 +#: cps/updater.py:469 msgid "Could not fetch update information" msgstr "" -#: cps/updater.py:456 +#: cps/updater.py:479 msgid "Click on the button below to update to the latest stable version." msgstr "" -#: cps/updater.py:465 cps/updater.py:479 cps/updater.py:490 +#: cps/updater.py:488 cps/updater.py:502 cps/updater.py:513 #, python-format msgid "A new update is available. Click on the button below to update to version: %(version)s" msgstr "" -#: cps/updater.py:507 +#: cps/updater.py:531 msgid "No release information available" msgstr "" -#: cps/templates/index.html:5 cps/web.py:440 +#: cps/templates/index.html:5 cps/web.py:434 msgid "Discover (Random Books)" msgstr "ស្រាវជ្រាវ (សៀវភៅចៃដន្យ)" -#: cps/web.py:471 +#: cps/web.py:470 msgid "Hot Books (Most Downloaded)" msgstr "សៀវភៅដែលត្រូវបានទាញយកច្រើនជាងគេ" -#: cps/web.py:507 +#: cps/web.py:501 #, python-format msgid "Downloaded books by %(user)s" msgstr "" -#: cps/web.py:539 +#: cps/web.py:534 #, python-format msgid "Author: %(name)s" msgstr "" -#: cps/web.py:554 +#: cps/web.py:570 #, python-format msgid "Publisher: %(name)s" msgstr "" -#: cps/web.py:569 +#: cps/web.py:598 #, python-format msgid "Series: %(serie)s" msgstr "ស៊េរី៖ %(serie)s" -#: cps/web.py:582 +#: cps/web.py:610 #, python-format msgid "Rating: %(rating)s stars" msgstr "" -#: cps/web.py:597 +#: cps/web.py:626 #, python-format msgid "File format: %(format)s" msgstr "" -#: cps/web.py:615 +#: cps/web.py:663 #, python-format msgid "Category: %(name)s" msgstr "ប្រភេទ៖ %(name)s" -#: cps/web.py:631 +#: cps/web.py:690 #, python-format msgid "Language: %(name)s" msgstr "ភាសា៖ %(name)s" -#: cps/templates/layout.html:56 cps/web.py:737 cps/web.py:1371 +#: cps/templates/layout.html:56 cps/web.py:789 cps/web.py:1444 msgid "Advanced Search" msgstr "ស្វែងរកកម្រិតខ្ពស់" #: cps/templates/book_edit.html:235 cps/templates/feed.xml:33 #: cps/templates/index.xml:11 cps/templates/layout.html:45 #: cps/templates/layout.html:48 cps/templates/search_form.html:226 -#: cps/web.py:750 cps/web.py:1077 +#: cps/web.py:807 cps/web.py:1164 msgid "Search" msgstr "ស្វែងរក" -#: cps/templates/admin.html:16 cps/web.py:903 +#: cps/templates/admin.html:16 cps/web.py:979 msgid "Downloads" msgstr "ឯកសារ DLS" -#: cps/web.py:980 +#: cps/web.py:1068 msgid "Ratings list" msgstr "" -#: cps/web.py:1001 +#: cps/web.py:1095 msgid "File formats list" msgstr "" -#: cps/templates/layout.html:73 cps/templates/tasks.html:7 cps/web.py:1055 +#: cps/templates/layout.html:73 cps/templates/tasks.html:7 cps/web.py:1149 msgid "Tasks" msgstr "កិច្ចការនានា" -#: cps/web.py:1215 +#: cps/web.py:1286 msgid "Published after " msgstr "បានបោះពុម្ភក្រោយ " -#: cps/web.py:1222 +#: cps/web.py:1293 msgid "Published before " msgstr "បានបោះពុម្ភមុន " -#: cps/web.py:1244 +#: cps/web.py:1315 #, python-format msgid "Rating <= %(rating)s" msgstr "ការវាយតម្លៃ <= %(rating)s" -#: cps/web.py:1246 +#: cps/web.py:1317 #, python-format msgid "Rating >= %(rating)s" msgstr "ការវាយតម្លៃ >= %(rating)s" -#: cps/web.py:1248 +#: cps/web.py:1319 #, python-format msgid "Read Status = %(status)s" msgstr "" -#: cps/web.py:1353 +#: cps/web.py:1425 msgid "Error on search for custom columns, please restart Calibre-Web" msgstr "" -#: cps/web.py:1449 +#: cps/web.py:1527 #, python-format msgid "Book successfully queued for sending to %(kindlemail)s" msgstr "សៀវភៅបានចូលជួរសម្រាប់ផ្ញើទៅ %(kindlemail)s ដោយជោគជ័យ" -#: cps/web.py:1453 +#: cps/web.py:1531 #, python-format msgid "Oops! There was an error sending this book: %(res)s" msgstr "មានបញ្ហានៅពេលផ្ញើសៀវភៅនេះ៖ %(res)s" -#: cps/web.py:1455 +#: cps/web.py:1533 msgid "Please update your profile with a valid Send to Kindle E-mail Address." msgstr "" -#: cps/web.py:1472 +#: cps/web.py:1550 msgid "E-Mail server is not configured, please contact your administrator!" msgstr "" -#: cps/templates/layout.html:85 cps/templates/register.html:17 cps/web.py:1473 -#: cps/web.py:1480 cps/web.py:1486 cps/web.py:1505 cps/web.py:1509 -#: cps/web.py:1515 +#: cps/templates/layout.html:85 cps/templates/register.html:17 cps/web.py:1551 +#: cps/web.py:1558 cps/web.py:1564 cps/web.py:1583 cps/web.py:1587 +#: cps/web.py:1593 msgid "Register" msgstr "ចុះឈ្មោះ" -#: cps/web.py:1507 +#: cps/web.py:1585 msgid "Your e-mail is not allowed to register" msgstr "" -#: cps/web.py:1510 +#: cps/web.py:1588 msgid "Confirmation e-mail was send to your e-mail account." msgstr "" -#: cps/web.py:1524 +#: cps/web.py:1602 msgid "Cannot activate LDAP authentication" msgstr "" -#: cps/web.py:1543 +#: cps/web.py:1621 #, python-format msgid "Fallback Login as: '%(nickname)s', LDAP Server not reachable, or user not known" msgstr "" -#: cps/web.py:1549 +#: cps/web.py:1627 #, python-format msgid "Could not login: %(message)s" msgstr "" -#: cps/web.py:1553 cps/web.py:1578 +#: cps/web.py:1631 cps/web.py:1656 msgid "Wrong Username or Password" msgstr "ខុសឈ្មោះអ្នកប្រើប្រាស់ ឬលេខសម្ងាត់" -#: cps/web.py:1560 +#: cps/web.py:1638 msgid "New Password was send to your email address" msgstr "" -#: cps/web.py:1566 +#: cps/web.py:1644 msgid "Please enter valid username to reset password" msgstr "" -#: cps/web.py:1573 +#: cps/web.py:1651 #, python-format msgid "You are now logged in as: '%(nickname)s'" msgstr "" -#: cps/web.py:1639 cps/web.py:1688 +#: cps/web.py:1717 cps/web.py:1766 #, python-format msgid "%(name)s's profile" msgstr "ព័ត៌មានសង្ខេបរបស់ %(name)s" -#: cps/web.py:1655 +#: cps/web.py:1733 msgid "Profile updated" msgstr "ព័ត៌មានសង្ខេបបានកែប្រែ" @@ -1318,36 +1341,36 @@ msgstr "ព័ត៌មានសង្ខេបបានកែប្រែ" msgid "Found no valid gmail.json file with OAuth information" msgstr "" -#: cps/tasks/convert.py:137 +#: cps/tasks/convert.py:154 #, python-format msgid "Calibre ebook-convert %(tool)s not found" msgstr "" -#: cps/tasks/convert.py:163 +#: cps/tasks/convert.py:187 #, python-format msgid "%(format)s format not found on disk" msgstr "" -#: cps/tasks/convert.py:167 +#: cps/tasks/convert.py:191 msgid "Ebook converter failed with unknown error" msgstr "" -#: cps/tasks/convert.py:177 +#: cps/tasks/convert.py:201 #, python-format msgid "Kepubify-converter failed: %(error)s" msgstr "" -#: cps/tasks/convert.py:199 +#: cps/tasks/convert.py:223 #, python-format msgid "Converted file not found or more than one file in folder %(folder)s" msgstr "" -#: cps/tasks/convert.py:222 +#: cps/tasks/convert.py:246 #, python-format msgid "Ebook-converter failed: %(error)s" msgstr "Ebook-converter បានបរាជ័យ៖ %(error)s" -#: cps/tasks/convert.py:245 +#: cps/tasks/convert.py:269 #, python-format msgid "Calibre failed with error: %(error)s" msgstr "" @@ -1402,7 +1425,7 @@ msgid "Edit" msgstr "កែប្រែ" #: cps/templates/admin.html:25 cps/templates/book_edit.html:16 -#: cps/templates/book_table.html:97 cps/templates/modal_dialogs.html:63 +#: cps/templates/book_table.html:100 cps/templates/modal_dialogs.html:63 #: cps/templates/modal_dialogs.html:116 cps/templates/user_edit.html:67 #: cps/templates/user_table.html:149 msgid "Delete" @@ -1412,180 +1435,180 @@ msgstr "លុប" msgid "Public Shelf" msgstr "" -#: cps/templates/admin.html:51 +#: cps/templates/admin.html:53 msgid "Add New User" msgstr "" -#: cps/templates/admin.html:53 +#: cps/templates/admin.html:55 msgid "Import LDAP Users" msgstr "" -#: cps/templates/admin.html:60 +#: cps/templates/admin.html:62 msgid "E-mail Server Settings" msgstr "" -#: cps/templates/admin.html:65 cps/templates/email_edit.html:31 +#: cps/templates/admin.html:67 cps/templates/email_edit.html:31 msgid "SMTP Hostname" msgstr "ឈ្មោះម៉ាស៊ីន SMTP" -#: cps/templates/admin.html:69 cps/templates/email_edit.html:35 +#: cps/templates/admin.html:71 cps/templates/email_edit.html:35 msgid "SMTP Port" msgstr "លេខ port SMTP" -#: cps/templates/admin.html:73 cps/templates/email_edit.html:39 +#: cps/templates/admin.html:75 cps/templates/email_edit.html:39 msgid "Encryption" msgstr "SSL" -#: cps/templates/admin.html:77 cps/templates/email_edit.html:47 +#: cps/templates/admin.html:79 cps/templates/email_edit.html:47 msgid "SMTP Login" msgstr "អ្នកចូលប្រើ SMTP" -#: cps/templates/admin.html:81 cps/templates/admin.html:92 +#: cps/templates/admin.html:83 cps/templates/admin.html:94 #: cps/templates/email_edit.html:55 msgid "From E-mail" msgstr "ពីអ៊ីមែល" -#: cps/templates/admin.html:88 +#: cps/templates/admin.html:90 msgid "E-Mail Service" msgstr "" -#: cps/templates/admin.html:89 +#: cps/templates/admin.html:91 msgid "Gmail via Oauth2" msgstr "" -#: cps/templates/admin.html:104 +#: cps/templates/admin.html:106 msgid "Configuration" msgstr "ការកំណត់" -#: cps/templates/admin.html:107 +#: cps/templates/admin.html:109 msgid "Calibre Database Directory" msgstr "ទីតាំង database Calibre" -#: cps/templates/admin.html:111 cps/templates/config_edit.html:68 +#: cps/templates/admin.html:113 cps/templates/config_edit.html:68 msgid "Log Level" msgstr "" -#: cps/templates/admin.html:115 +#: cps/templates/admin.html:117 msgid "Port" msgstr "លេខ port" -#: cps/templates/admin.html:120 +#: cps/templates/admin.html:122 msgid "External Port" msgstr "" -#: cps/templates/admin.html:127 cps/templates/config_view_edit.html:28 +#: cps/templates/admin.html:129 cps/templates/config_view_edit.html:28 msgid "Books per Page" msgstr "ចំនួនសៀវភៅក្នុងមួយទំព័រ" -#: cps/templates/admin.html:131 +#: cps/templates/admin.html:133 msgid "Uploads" msgstr "កំពុងអាប់ឡូដ" -#: cps/templates/admin.html:135 +#: cps/templates/admin.html:137 msgid "Anonymous Browsing" msgstr "" -#: cps/templates/admin.html:139 +#: cps/templates/admin.html:141 msgid "Public Registration" msgstr "ការចុះឈ្មាះសាធារណៈ" -#: cps/templates/admin.html:143 +#: cps/templates/admin.html:145 msgid "Magic Link Remote Login" msgstr "ការចូលប្រើប្រាស់ពីចម្ងាយ" -#: cps/templates/admin.html:147 +#: cps/templates/admin.html:149 msgid "Reverse Proxy Login" msgstr "" -#: cps/templates/admin.html:152 cps/templates/config_edit.html:173 +#: cps/templates/admin.html:154 cps/templates/config_edit.html:173 msgid "Reverse Proxy Header Name" msgstr "" -#: cps/templates/admin.html:157 +#: cps/templates/admin.html:159 #, fuzzy msgid "Edit Calibre Database Configuration" msgstr "ទីតាំង database Calibre" -#: cps/templates/admin.html:158 +#: cps/templates/admin.html:160 msgid "Edit Basic Configuration" msgstr "" -#: cps/templates/admin.html:159 +#: cps/templates/admin.html:161 msgid "Edit UI Configuration" msgstr "" -#: cps/templates/admin.html:164 +#: cps/templates/admin.html:166 msgid "Administration" msgstr "កិច្ចការរដ្ឋបាល" -#: cps/templates/admin.html:165 +#: cps/templates/admin.html:167 msgid "Download Debug Package" msgstr "" -#: cps/templates/admin.html:166 +#: cps/templates/admin.html:168 msgid "View Logs" msgstr "" -#: cps/templates/admin.html:169 +#: cps/templates/admin.html:171 msgid "Reconnect Calibre Database" msgstr "ភ្ជាប់ទៅ database Calibre ម្តងទៀត" -#: cps/templates/admin.html:170 +#: cps/templates/admin.html:172 msgid "Restart" msgstr "" -#: cps/templates/admin.html:171 +#: cps/templates/admin.html:173 msgid "Shutdown" msgstr "" -#: cps/templates/admin.html:176 +#: cps/templates/admin.html:178 msgid "Update" msgstr "" -#: cps/templates/admin.html:180 +#: cps/templates/admin.html:182 msgid "Version" msgstr "" -#: cps/templates/admin.html:181 +#: cps/templates/admin.html:183 msgid "Details" msgstr "" -#: cps/templates/admin.html:187 +#: cps/templates/admin.html:189 msgid "Current version" msgstr "" -#: cps/templates/admin.html:194 +#: cps/templates/admin.html:196 msgid "Check for Update" msgstr "រកមើលបច្ចុប្បន្នភាព" -#: cps/templates/admin.html:195 +#: cps/templates/admin.html:197 msgid "Perform Update" msgstr "ធ្វើបច្ចុប្បន្នភាព" -#: cps/templates/admin.html:208 +#: cps/templates/admin.html:210 msgid "Are you sure you want to restart?" msgstr "" -#: cps/templates/admin.html:213 cps/templates/admin.html:227 -#: cps/templates/admin.html:247 cps/templates/config_db.html:70 +#: cps/templates/admin.html:215 cps/templates/admin.html:229 +#: cps/templates/admin.html:249 cps/templates/config_db.html:70 msgid "OK" msgstr "បាទ/ចាស" -#: cps/templates/admin.html:214 cps/templates/admin.html:228 -#: cps/templates/book_edit.html:213 cps/templates/book_table.html:124 +#: cps/templates/admin.html:216 cps/templates/admin.html:230 +#: cps/templates/book_edit.html:213 cps/templates/book_table.html:127 #: cps/templates/config_db.html:54 cps/templates/config_edit.html:359 -#: cps/templates/config_view_edit.html:173 cps/templates/modal_dialogs.html:64 +#: cps/templates/config_view_edit.html:175 cps/templates/modal_dialogs.html:64 #: cps/templates/modal_dialogs.html:99 cps/templates/modal_dialogs.html:117 #: cps/templates/modal_dialogs.html:135 cps/templates/shelf_edit.html:27 #: cps/templates/user_edit.html:144 msgid "Cancel" msgstr "" -#: cps/templates/admin.html:226 +#: cps/templates/admin.html:228 msgid "Are you sure you want to shutdown?" msgstr "" -#: cps/templates/admin.html:238 +#: cps/templates/admin.html:240 msgid "Updating, please do not reload this page" msgstr "កំពុងធ្វើបច្ចុប្បន្នភាព សូមកុំបើកទំព័រជាថ្មី" @@ -1597,44 +1620,43 @@ msgstr "តាមរយៈ" msgid "In Library" msgstr "នៅក្នុងបណ្ណាល័យ" -#: cps/templates/author.html:26 cps/templates/index.html:72 -#: cps/templates/search.html:29 cps/templates/shelf.html:19 +#: cps/templates/author.html:26 cps/templates/index.html:73 +#: cps/templates/search.html:30 cps/templates/shelf.html:19 msgid "Sort according to book date, newest first" msgstr "" -#: cps/templates/author.html:27 cps/templates/index.html:73 -#: cps/templates/search.html:30 cps/templates/shelf.html:20 +#: cps/templates/author.html:27 cps/templates/index.html:74 +#: cps/templates/search.html:31 cps/templates/shelf.html:20 msgid "Sort according to book date, oldest first" msgstr "" -#: cps/templates/author.html:28 cps/templates/index.html:74 -#: cps/templates/search.html:31 cps/templates/shelf.html:21 +#: cps/templates/author.html:28 cps/templates/index.html:75 +#: cps/templates/search.html:32 cps/templates/shelf.html:21 msgid "Sort title in alphabetical order" msgstr "" -#: cps/templates/author.html:29 cps/templates/index.html:75 -#: cps/templates/search.html:32 cps/templates/shelf.html:22 +#: cps/templates/author.html:29 cps/templates/index.html:76 +#: cps/templates/search.html:33 cps/templates/shelf.html:22 msgid "Sort title in reverse alphabetical order" msgstr "" -#: cps/templates/author.html:30 cps/templates/index.html:78 -#: cps/templates/search.html:35 cps/templates/shelf.html:25 +#: cps/templates/author.html:30 cps/templates/index.html:79 +#: cps/templates/search.html:36 cps/templates/shelf.html:25 msgid "Sort according to publishing date, newest first" msgstr "" -#: cps/templates/author.html:31 cps/templates/index.html:79 -#: cps/templates/search.html:36 cps/templates/shelf.html:26 +#: cps/templates/author.html:31 cps/templates/index.html:80 +#: cps/templates/search.html:37 cps/templates/shelf.html:26 msgid "Sort according to publishing date, oldest first" msgstr "" -#: cps/templates/author.html:57 cps/templates/author.html:117 -#: cps/templates/discover.html:30 cps/templates/index.html:29 -#: cps/templates/index.html:111 cps/templates/search.html:65 -#: cps/templates/shelf.html:54 +#: cps/templates/author.html:56 cps/templates/author.html:115 +#: cps/templates/index.html:29 cps/templates/index.html:112 +#: cps/templates/search.html:66 cps/templates/shelf.html:54 msgid "reduce" msgstr "" -#: cps/templates/author.html:101 +#: cps/templates/author.html:99 msgid "More by" msgstr "បន្ថែមទៀតដោយ" @@ -1759,7 +1781,7 @@ msgid "Fetch Metadata" msgstr "មើលទិន្នន័យមេតា" #: cps/templates/book_edit.html:212 cps/templates/config_db.html:53 -#: cps/templates/config_edit.html:358 cps/templates/config_view_edit.html:172 +#: cps/templates/config_edit.html:358 cps/templates/config_view_edit.html:174 #: cps/templates/email_edit.html:65 cps/templates/shelf_edit.html:25 #: cps/templates/shelf_order.html:41 cps/templates/user_edit.html:142 msgid "Save" @@ -1887,27 +1909,35 @@ msgstr "" msgid "Comments" msgstr "" -#: cps/templates/book_table.html:77 cps/templates/book_table.html:79 -#: cps/templates/book_table.html:81 cps/templates/book_table.html:83 -#: cps/templates/book_table.html:87 cps/templates/book_table.html:89 -#: cps/templates/book_table.html:91 cps/templates/book_table.html:93 +#: cps/templates/book_table.html:75 +msgid "Archiv Status" +msgstr "" + +#: cps/templates/book_table.html:77 cps/templates/search_form.html:42 +msgid "Read Status" +msgstr "" + +#: cps/templates/book_table.html:80 cps/templates/book_table.html:82 +#: cps/templates/book_table.html:84 cps/templates/book_table.html:86 +#: cps/templates/book_table.html:90 cps/templates/book_table.html:92 +#: cps/templates/book_table.html:96 #, fuzzy msgid "Enter " msgstr "ចុះឈ្មោះ" -#: cps/templates/book_table.html:110 cps/templates/modal_dialogs.html:46 +#: cps/templates/book_table.html:113 cps/templates/modal_dialogs.html:46 msgid "Are you really sure?" msgstr "" -#: cps/templates/book_table.html:114 +#: cps/templates/book_table.html:117 msgid "Books with Title will be merged from:" msgstr "" -#: cps/templates/book_table.html:118 +#: cps/templates/book_table.html:121 msgid "Into Book with Title:" msgstr "" -#: cps/templates/book_table.html:123 +#: cps/templates/book_table.html:126 msgid "Merge" msgstr "" @@ -2083,11 +2113,6 @@ msgstr "" msgid "LDAP Encryption" msgstr "" -#: cps/templates/config_edit.html:204 cps/templates/config_view_edit.html:62 -#: cps/templates/email_edit.html:41 -msgid "None" -msgstr "គ្មាន" - #: cps/templates/config_edit.html:205 msgid "TLS" msgstr "" @@ -2306,11 +2331,11 @@ msgstr "ភាពមើលឃើញដែលមកស្រាប់សម្រ msgid "Show Random Books in Detail View" msgstr "បង្ហាញសៀវភៅចៃដន្យក្នុងការបង្ហាញជាពិស្តារ" -#: cps/templates/config_view_edit.html:165 cps/templates/user_edit.html:87 +#: cps/templates/config_view_edit.html:166 cps/templates/user_edit.html:87 msgid "Add Allowed/Denied Tags" msgstr "" -#: cps/templates/config_view_edit.html:166 +#: cps/templates/config_view_edit.html:167 msgid "Add Allowed/Denied custom column values" msgstr "" @@ -2359,13 +2384,13 @@ msgstr "" msgid "Description:" msgstr "ពិពណ៌នា" -#: cps/templates/detail.html:256 cps/templates/search.html:14 +#: cps/templates/detail.html:256 cps/templates/search.html:15 msgid "Add to shelf" msgstr "បន្ថែមទៅធ្នើ" #: cps/templates/detail.html:267 cps/templates/detail.html:284 #: cps/templates/feed.xml:79 cps/templates/layout.html:137 -#: cps/templates/search.html:20 +#: cps/templates/search.html:21 msgid "(Public)" msgstr "" @@ -2443,10 +2468,14 @@ msgstr "" msgid "Next" msgstr "បន្ទាប់" -#: cps/templates/generate_kobo_auth_url.html:5 +#: cps/templates/generate_kobo_auth_url.html:6 msgid "Open the .kobo/Kobo eReader.conf file in a text editor and add (or edit):" msgstr "" +#: cps/templates/generate_kobo_auth_url.html:11 +msgid "Kobo Token:" +msgstr "" + #: cps/templates/http_error.html:31 msgid "Calibre-Web Instance is unconfigured, please contact your administrator" msgstr "" @@ -2463,29 +2492,29 @@ msgstr "" msgid "Logout User" msgstr "" -#: cps/templates/index.html:69 +#: cps/templates/index.html:70 msgid "Sort ascending according to download count" msgstr "" -#: cps/templates/index.html:70 +#: cps/templates/index.html:71 msgid "Sort descending according to download count" msgstr "" -#: cps/templates/index.html:76 cps/templates/search.html:33 +#: cps/templates/index.html:77 cps/templates/search.html:34 #: cps/templates/shelf.html:23 msgid "Sort authors in alphabetical order" msgstr "" -#: cps/templates/index.html:77 cps/templates/search.html:34 +#: cps/templates/index.html:78 cps/templates/search.html:35 #: cps/templates/shelf.html:24 msgid "Sort authors in reverse alphabetical order" msgstr "" -#: cps/templates/index.html:81 +#: cps/templates/index.html:82 msgid "Sort ascending according to series index" msgstr "" -#: cps/templates/index.html:82 +#: cps/templates/index.html:83 msgid "Sort descending according to series index" msgstr "" @@ -2917,10 +2946,6 @@ msgstr "ថ្ងៃបោះពុម្ភចាប់ពី" msgid "Published Date To" msgstr "ថ្ងៃបោះពុម្ភរហូតដល់" -#: cps/templates/search_form.html:42 -msgid "Read Status" -msgstr "" - #: cps/templates/search_form.html:59 msgid "Exclude Tags" msgstr "លើកលែង tag" diff --git a/cps/translations/ko/LC_MESSAGES/messages.mo b/cps/translations/ko/LC_MESSAGES/messages.mo index 772e946d..e85e6720 100644 Binary files a/cps/translations/ko/LC_MESSAGES/messages.mo and b/cps/translations/ko/LC_MESSAGES/messages.mo differ diff --git a/cps/translations/ko/LC_MESSAGES/messages.po b/cps/translations/ko/LC_MESSAGES/messages.po index f8606245..31402b0f 100644 --- a/cps/translations/ko/LC_MESSAGES/messages.po +++ b/cps/translations/ko/LC_MESSAGES/messages.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: Calibre-web\n" "Report-Msgid-Bugs-To: https://github.com/janeczku/calibre-web\n" -"POT-Creation-Date: 2022-01-15 09:19+0100\n" +"POT-Creation-Date: 2022-04-18 20:01+0200\n" "PO-Revision-Date: 2022-01-10 11:30+0900\n" "Last-Translator: 내맘대로의 EPUBGUIDE.NET \n" "Language: ko\n" @@ -15,578 +15,581 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.9.0\n" +"Generated-By: Babel 2.9.1\n" -#: cps/about.py:34 cps/about.py:49 cps/about.py:65 cps/converter.py:31 -msgid "not installed" -msgstr "설치되지 않음" - -#: cps/about.py:47 cps/about.py:63 -msgid "installed" -msgstr "설치됨" - -#: cps/about.py:145 +#: cps/about.py:86 msgid "Statistics" msgstr "통계" -#: cps/admin.py:144 +#: cps/admin.py:141 msgid "Server restarted, please reload page" msgstr "서버 다시 시작으로 새로고침 필요" -#: cps/admin.py:146 +#: cps/admin.py:143 msgid "Performing shutdown of server, please close window" msgstr "서버를 종료하는 중, 창을 닫아야 함" -#: cps/admin.py:154 +#: cps/admin.py:151 msgid "Reconnect successful" msgstr "재연결 성공" -#: cps/admin.py:157 +#: cps/admin.py:154 msgid "Unknown command" msgstr "알 수 없는 명령" -#: cps/admin.py:167 cps/editbooks.py:707 cps/editbooks.py:721 -#: cps/editbooks.py:866 cps/editbooks.py:868 cps/editbooks.py:895 -#: cps/editbooks.py:911 cps/updater.py:584 cps/uploader.py:93 -#: cps/uploader.py:103 +#: cps/admin.py:176 cps/editbooks.py:713 cps/editbooks.py:892 +#: cps/editbooks.py:894 cps/editbooks.py:930 cps/editbooks.py:947 +#: cps/updater.py:608 cps/uploader.py:93 cps/uploader.py:103 msgid "Unknown" msgstr "알 수 없음" -#: cps/admin.py:188 +#: cps/admin.py:197 msgid "Admin page" msgstr "관리자 페이지" -#: cps/admin.py:207 +#: cps/admin.py:217 msgid "Basic Configuration" msgstr "기본 설정" -#: cps/admin.py:244 +#: cps/admin.py:255 msgid "UI Configuration" msgstr "UI 설정" -#: cps/admin.py:277 cps/templates/admin.html:50 +#: cps/admin.py:289 cps/templates/admin.html:51 msgid "Edit Users" msgstr "사용자 관리" -#: cps/admin.py:318 cps/opds.py:109 cps/opds.py:198 cps/opds.py:275 -#: cps/opds.py:327 cps/templates/grid.html:13 cps/templates/languages.html:9 +#: cps/admin.py:333 cps/opds.py:529 cps/templates/grid.html:13 #: cps/templates/list.html:13 msgid "All" msgstr "모두" -#: cps/admin.py:343 cps/admin.py:1615 +#: cps/admin.py:360 cps/admin.py:1648 msgid "User not found" msgstr "사용자를 찾을 수 없음" -#: cps/admin.py:357 +#: cps/admin.py:374 msgid "{} users deleted successfully" msgstr "{} 사용자를 성공적으로 삭제함" -#: cps/admin.py:379 cps/templates/config_view_edit.html:133 +#: cps/admin.py:397 cps/templates/config_view_edit.html:133 #: cps/templates/user_edit.html:45 cps/templates/user_table.html:81 msgid "Show All" msgstr "모두 보기" -#: cps/admin.py:400 cps/admin.py:406 +#: cps/admin.py:418 cps/admin.py:424 msgid "Malformed request" msgstr "잘못된 요청" -#: cps/admin.py:418 cps/admin.py:1493 +#: cps/admin.py:436 cps/admin.py:1526 msgid "Guest Name can't be changed" msgstr "Guest 이름은 수정할 수 없음" -#: cps/admin.py:430 +#: cps/admin.py:448 msgid "Guest can't have this role" msgstr "Guest는 이 권한을 사용할 수 없음" -#: cps/admin.py:442 cps/admin.py:1451 +#: cps/admin.py:460 cps/admin.py:1484 msgid "No admin user remaining, can't remove admin role" msgstr "관리자 계정이 하나 뿐일 때는 관리자를 삭제할 수 없음" -#: cps/admin.py:446 cps/admin.py:460 +#: cps/admin.py:464 cps/admin.py:478 msgid "Value has to be true or false" msgstr "값으로 rue 또는 false만 설정 가능" -#: cps/admin.py:448 +#: cps/admin.py:466 msgid "Invalid role" msgstr "잘못된 권한" -#: cps/admin.py:452 +#: cps/admin.py:470 msgid "Guest can't have this view" msgstr "Guest는 이 view를 사용할 수 없음" -#: cps/admin.py:462 +#: cps/admin.py:480 msgid "Invalid view" msgstr "잘못된 view" -#: cps/admin.py:465 +#: cps/admin.py:483 msgid "Guest's Locale is determined automatically and can't be set" msgstr "Guest의 로케일은 자동으로 결정되며 설정할 수 없음" -#: cps/admin.py:469 +#: cps/admin.py:487 msgid "No Valid Locale Given" msgstr "유효한 로케일이 아님" -#: cps/admin.py:480 +#: cps/admin.py:498 msgid "No Valid Book Language Given" msgstr "제공된 책의 언어가 유효하지 않음" -#: cps/admin.py:482 +#: cps/admin.py:500 cps/editbooks.py:1267 msgid "Parameter not found" msgstr "매개변수를 찾을 수 없음" -#: cps/admin.py:533 +#: cps/admin.py:553 msgid "Invalid Read Column" msgstr "잘못된 읽기 열" -#: cps/admin.py:539 +#: cps/admin.py:559 msgid "Invalid Restricted Column" msgstr "잘못된 제한된 열" -#: cps/admin.py:560 cps/admin.py:1323 +#: cps/admin.py:579 cps/admin.py:1355 msgid "Calibre-Web configuration updated" msgstr "Calibre-Web 설정이 업데이트 됨" -#: cps/admin.py:572 +#: cps/admin.py:591 msgid "Do you really want to delete the Kobo Token?" msgstr "Kobo Token을 삭제하시겠습니까?" -#: cps/admin.py:574 +#: cps/admin.py:593 msgid "Do you really want to delete this domain?" msgstr "이 도메인을 삭제하시겠습니까?" -#: cps/admin.py:576 +#: cps/admin.py:595 msgid "Do you really want to delete this user?" msgstr "이 사용자를 삭제하시겠습니까?" -#: cps/admin.py:578 +#: cps/admin.py:597 msgid "Are you sure you want to delete this shelf?" msgstr "이 서재를 삭제하시겠습니까?" -#: cps/admin.py:580 +#: cps/admin.py:599 msgid "Are you sure you want to change locales of selected user(s)?" msgstr "선택한 사용자의 언어를 변경하시겠습니까?" -#: cps/admin.py:582 +#: cps/admin.py:601 msgid "Are you sure you want to change visible book languages for selected user(s)?" msgstr "선택한 사용자에 대해 표시되는 책 언어를 변경하시겠습니까?" -#: cps/admin.py:584 +#: cps/admin.py:603 msgid "Are you sure you want to change the selected role for the selected user(s)?" msgstr "선택한 사용자에 대해 선택한 권한을 변경하시겠습니까?" -#: cps/admin.py:586 +#: cps/admin.py:605 msgid "Are you sure you want to change the selected restrictions for the selected user(s)?" msgstr "선택한 사용자에 대해 선택한 제한을 변경하시겠습니까?" -#: cps/admin.py:588 +#: cps/admin.py:607 msgid "Are you sure you want to change the selected visibility restrictions for the selected user(s)?" msgstr "선택한 사용자에 대해 선택한 가시성 제한을 변경하시겠습니까?" -#: cps/admin.py:590 +#: cps/admin.py:610 msgid "Are you sure you want to change shelf sync behavior for the selected user(s)?" msgstr "선택한 사용자의 실행기 동기화 동작을 변경하시겠습니까?" -#: cps/admin.py:592 +#: cps/admin.py:612 msgid "Are you sure you want to change Calibre library location?" msgstr "캘리버 서재의 언어를 변경하시겠습니까?" -#: cps/admin.py:594 +#: cps/admin.py:614 msgid "Are you sure you want delete Calibre-Web's sync database to force a full sync with your Kobo Reader?" msgstr "Kobo Reader와 전체 동기화를 강제 실행하기 위해 Calibre-Web의 동기화 데이터베이스를 삭제하시겠습니까?" -#: cps/admin.py:743 +#: cps/admin.py:764 msgid "Tag not found" msgstr "태그를 찾을 수 없음" -#: cps/admin.py:755 +#: cps/admin.py:776 msgid "Invalid Action" msgstr "잘못된 액션" -#: cps/admin.py:871 cps/admin.py:877 cps/admin.py:887 cps/admin.py:897 +#: cps/admin.py:893 cps/admin.py:899 cps/admin.py:909 cps/admin.py:919 #: cps/templates/modal_dialogs.html:29 cps/templates/user_table.html:41 #: cps/templates/user_table.html:58 msgid "Deny" msgstr "거부됨" -#: cps/admin.py:873 cps/admin.py:879 cps/admin.py:889 cps/admin.py:899 +#: cps/admin.py:895 cps/admin.py:901 cps/admin.py:911 cps/admin.py:921 #: cps/templates/modal_dialogs.html:28 cps/templates/user_table.html:44 #: cps/templates/user_table.html:61 msgid "Allow" msgstr "허용됨" -#: cps/admin.py:913 +#: cps/admin.py:936 msgid "{} sync entries deleted" msgstr "{} 동기화 항목이 삭제됨" -#: cps/admin.py:1036 +#: cps/admin.py:1059 msgid "client_secrets.json Is Not Configured For Web Application" msgstr "client_secrets.json이 Web 응용프로그램에 대해 설정되지 않음" -#: cps/admin.py:1081 +#: cps/admin.py:1104 msgid "Logfile Location is not Valid, Please Enter Correct Path" msgstr "로그 파일 위치가 오류. 올바른 경로 입력 필요" -#: cps/admin.py:1087 +#: cps/admin.py:1110 msgid "Access Logfile Location is not Valid, Please Enter Correct Path" msgstr "액세스 로그 파일 위치가 올바르지 않음. 올바른 경로 입력 필요" -#: cps/admin.py:1117 +#: cps/admin.py:1140 msgid "Please Enter a LDAP Provider, Port, DN and User Object Identifier" msgstr "LDAP 공급자, 포트, DN 및 사용자 개체 식별자를 입력" -#: cps/admin.py:1123 +#: cps/admin.py:1146 msgid "Please Enter a LDAP Service Account and Password" msgstr "LDAP 서비스 계정 및 비밀번호를 입력하십시오" -#: cps/admin.py:1126 +#: cps/admin.py:1149 msgid "Please Enter a LDAP Service Account" msgstr "LDAP 서비스 계정을 입력하십시오" -#: cps/admin.py:1131 +#: cps/admin.py:1154 #, python-format msgid "LDAP Group Object Filter Needs to Have One \"%s\" Format Identifier" msgstr "LDAP 그룹 개체 필터에는 하나의 \"%s\" 형식 식별자가 필요함" -#: cps/admin.py:1133 +#: cps/admin.py:1156 msgid "LDAP Group Object Filter Has Unmatched Parenthesis" msgstr "LDAP 그룹 개체 필터에 일치하지 않는 괄호가 있음" -#: cps/admin.py:1137 +#: cps/admin.py:1160 #, python-format msgid "LDAP User Object Filter needs to Have One \"%s\" Format Identifier" msgstr "LDAP 사용자 개체 필터에는 하나의 \"%s\" 형식 식별자 필요" -#: cps/admin.py:1139 +#: cps/admin.py:1162 msgid "LDAP User Object Filter Has Unmatched Parenthesis" msgstr "LDAP 사용자 개체 필터에 일치하지 않는 괄호가 있음" -#: cps/admin.py:1146 +#: cps/admin.py:1169 #, python-format msgid "LDAP Member User Filter needs to Have One \"%s\" Format Identifier" msgstr "LDAP 구성원 사용자 필터에는 하나의 \"%s\" 형식 식별자 필요" -#: cps/admin.py:1148 +#: cps/admin.py:1171 msgid "LDAP Member User Filter Has Unmatched Parenthesis" msgstr "LDAP 구성원 사용자 필터에 일치하지 않는 괄호가 있음" -#: cps/admin.py:1155 +#: cps/admin.py:1178 msgid "LDAP CACertificate, Certificate or Key Location is not Valid, Please Enter Correct Path" msgstr "유요하지 않은 LDAP CACertificate, 인증서 또는 키 위치. 올바른 경로를 입력 필요" -#: cps/admin.py:1197 cps/admin.py:1308 cps/admin.py:1405 cps/admin.py:1521 -#: cps/admin.py:1590 cps/shelf.py:100 cps/shelf.py:160 cps/shelf.py:203 -#: cps/shelf.py:279 cps/shelf.py:341 cps/shelf.py:376 cps/shelf.py:451 -msgid "Settings DB is not Writeable" -msgstr "설정 DB에 쓰기 권한이 없음" - -#: cps/admin.py:1208 -msgid "DB Location is not Valid, Please Enter Correct Path" -msgstr "올바르지 않은 DB 위치. 올바른 경로 입력 필요" - -#: cps/admin.py:1223 -msgid "DB is not Writeable" -msgstr "쓰기 권한이 없는 DB" - -#: cps/admin.py:1235 -msgid "Keyfile Location is not Valid, Please Enter Correct Path" -msgstr "올바르지 않은 키 파일 위치. 올바른 경로 입력 필요" - -#: cps/admin.py:1239 -msgid "Certfile Location is not Valid, Please Enter Correct Path" -msgstr "올바르지 않은 인증서 파일 위치. 올바른 경로 입력 필요" - -#: cps/admin.py:1346 -msgid "Database Settings updated" -msgstr "데이터베이스 설정이 업데이트 되었습니다" - -#: cps/admin.py:1354 -msgid "Database Configuration" -msgstr "데이터베이스 구성" - -#: cps/admin.py:1370 cps/web.py:1479 -msgid "Please fill out all fields!" -msgstr "모든 필드를 채워주십시오!" - -#: cps/admin.py:1378 -msgid "E-mail is not from valid domain" -msgstr "유효한 도메인에서 온 이메일이 아니" - -#: cps/admin.py:1384 cps/admin.py:1543 -msgid "Add new user" -msgstr "새 사용자 추가" - -#: cps/admin.py:1395 -#, python-format -msgid "User '%(user)s' created" -msgstr "사용자 '%(user)s'이(가) 생성됨" - -#: cps/admin.py:1401 -msgid "Found an existing account for this e-mail address or name." -msgstr "동일한 이메일 주소 또는 이름이 이미 등록되어 있습니다." - -#: cps/admin.py:1430 -#, python-format -msgid "User '%(nick)s' deleted" -msgstr "사용자 '%(nick)s'이(가) 삭제됨" - -#: cps/admin.py:1432 cps/admin.py:1433 -msgid "Can't delete Guest User" -msgstr "게스트 사용자는 삭제할 수 없습니다" - -#: cps/admin.py:1436 -msgid "No admin user remaining, can't delete user" -msgstr "관리자 계정이 하나 뿐일 때는 관리자 권한을 삭제할 수 없음" - -#: cps/admin.py:1509 cps/admin.py:1634 -#, python-format -msgid "Edit User %(nick)s" -msgstr "사용자 %(nick)s 편집" - -#: cps/admin.py:1513 -#, python-format -msgid "User '%(nick)s' updated" -msgstr "사용자 '%(nick)s'가 업데이트 됨" - -#: cps/admin.py:1517 cps/admin.py:1649 cps/web.py:1504 cps/web.py:1564 -msgid "An unknown error occurred. Please try again later." -msgstr "알 수없는 오류가 발생했습니다. 나중에 다시 시도 해주십시오." - -#: cps/admin.py:1552 cps/templates/admin.html:98 -msgid "Edit E-mail Server Settings" -msgstr "이메일 서버 설정 편집" - -#: cps/admin.py:1571 -msgid "Gmail Account Verification Successful" -msgstr "Gmail 계정 인증 성공" - -#: cps/admin.py:1597 -#, python-format -msgid "Test e-mail queued for sending to %(email)s, please check Tasks for result" -msgstr "%(email)s에 테스트를 위한 이메일을 보냄. 결과 확인 필요" - -#: cps/admin.py:1600 -#, python-format -msgid "There was an error sending the Test e-mail: %(res)s" -msgstr "테스트 이메일을 보내는 동안 오류가 발생했습니다: %(res)s" - -#: cps/admin.py:1602 -msgid "Please configure your e-mail address first..." -msgstr "먼저 이메일 주소를 구성하십시오..." - -#: cps/admin.py:1604 -msgid "E-mail server settings updated" -msgstr "이메일 서버 설정 업데이트됨" - -#: cps/admin.py:1646 -#, python-format -msgid "Password for user %(user)s reset" -msgstr "사용자 %(user)s의 비밀번호 재설정" - -#: cps/admin.py:1652 cps/web.py:1444 -msgid "Please configure the SMTP mail settings first..." -msgstr "먼저 SMTP 메일 설정을 구성하십시오..." - -#: cps/admin.py:1663 -msgid "Logfile viewer" -msgstr "로그 파일 뷰어" - -#: cps/admin.py:1729 -msgid "Requesting update package" -msgstr "업데이트 패키지 요청" - -#: cps/admin.py:1730 -msgid "Downloading update package" -msgstr "업데이트 패키지 다운로드" - -#: cps/admin.py:1731 -msgid "Unzipping update package" -msgstr "업데이트 패키지 압축 풀기" - -#: cps/admin.py:1732 -msgid "Replacing files" -msgstr "파일 교체" - -#: cps/admin.py:1733 -msgid "Database connections are closed" -msgstr "데이터베이스 연결이 닫힙니다" - -#: cps/admin.py:1734 -msgid "Stopping server" -msgstr "서버 중지" - -#: cps/admin.py:1735 -msgid "Update finished, please press okay and reload page" -msgstr "업데이트가 완료되었습니다. 확인을 누르고 페이지를 새로고침하세요" - -#: cps/admin.py:1736 cps/admin.py:1737 cps/admin.py:1738 cps/admin.py:1739 -#: cps/admin.py:1740 cps/admin.py:1741 -msgid "Update failed:" -msgstr "업데이트 실패:" - -#: cps/admin.py:1736 cps/updater.py:385 cps/updater.py:595 cps/updater.py:597 -msgid "HTTP Error" -msgstr "HTTP 오류" - -#: cps/admin.py:1737 cps/updater.py:387 cps/updater.py:599 -msgid "Connection error" -msgstr "연결 오류" - -#: cps/admin.py:1738 cps/updater.py:389 cps/updater.py:601 -msgid "Timeout while establishing connection" -msgstr "연결 설정 중 시간 초과" - -#: cps/admin.py:1739 cps/updater.py:391 cps/updater.py:603 -msgid "General error" -msgstr "일반 오류" - -#: cps/admin.py:1740 -msgid "Update file could not be saved in temp dir" -msgstr "임시 디렉토리에 업데이트 파일을 저장할 수 없습니다" - -#: cps/admin.py:1741 -msgid "Files could not be replaced during update" -msgstr "업데이트하는 동안 파일을 교체할 수 없습니다" - -#: cps/admin.py:1765 -msgid "Failed to extract at least One LDAP User" -msgstr "하나 이상의 LDAP 사용자를 추출하지 못했습니다" - -#: cps/admin.py:1810 -msgid "Failed to Create at Least One LDAP User" -msgstr "하나 이상의 LDAP 사용자를 생성하지 못했습니다" - -#: cps/admin.py:1823 -#, python-format -msgid "Error: %(ldaperror)s" -msgstr "오류: %(ldaperror)s" - -#: cps/admin.py:1827 -msgid "Error: No user returned in response of LDAP server" -msgstr "오류: LDAP 서버의 응답으로 사용자가 반환되지 않았습니다" - -#: cps/admin.py:1860 -msgid "At Least One LDAP User Not Found in Database" -msgstr "데이터베이스에서 하나 이상의 LDAP 사용자를 찾을 수 없습니다" - -#: cps/admin.py:1862 -msgid "{} User Successfully Imported" -msgstr "{} 사용자 가져오기 성공" - -#: cps/converter.py:30 -msgid "not configured" -msgstr "구성되지 않음" - -#: cps/converter.py:32 -msgid "Execution permissions missing" -msgstr "실행 권한 누락" - -#: cps/db.py:651 cps/web.py:667 cps/web.py:1155 -#, python-format -msgid "Custom Column No.%(column)d is not existing in calibre database" -msgstr "사용자 정의 열 번호 %(column)d이(가) calibre 데이터베이스에 없습니다" - -#: cps/editbooks.py:300 cps/editbooks.py:302 -msgid "Book Format Successfully Deleted" -msgstr "책 형식이 성공적으로 삭제되었습니다" - -#: cps/editbooks.py:309 cps/editbooks.py:311 -msgid "Book Successfully Deleted" -msgstr "책이 성공적으로 삭제되었습니다" - -#: cps/editbooks.py:361 -msgid "You are missing permissions to delete books" -msgstr "" - -#: cps/editbooks.py:376 cps/editbooks.py:763 cps/web.py:523 cps/web.py:1703 -#: cps/web.py:1744 cps/web.py:1811 -msgid "Oops! Selected book title is unavailable. File does not exist or is not accessible" -msgstr "선택한 책 제목을 사용할 수 없습니다. 파일이 존재하지 않거나 액세스할 수 없습니다" - -#: cps/editbooks.py:410 -msgid "edit metadata" -msgstr "메타데이터 편집" - -#: cps/editbooks.py:458 -#, python-format -msgid "%(seriesindex)s is not a valid number, skipping" -msgstr "%(seriesindex)s은(는) 유효한 숫자가 아닙니다. 건너뜁니다" - -#: cps/editbooks.py:494 cps/editbooks.py:958 -#, python-format -msgid "'%(langname)s' is not a valid language" -msgstr "'%(langname)s'은(는) 유효한 언어가 아닙니다" - -#: cps/editbooks.py:634 cps/editbooks.py:985 -#, python-format -msgid "File extension '%(ext)s' is not allowed to be uploaded to this server" -msgstr "파일 확장자 '%(ext)s'은(는) 이 서버에 업로드할 수 없습니다" - -#: cps/editbooks.py:638 cps/editbooks.py:989 -msgid "File to be uploaded must have an extension" -msgstr "업로드할 파일에는 확장자가 있어야 합니다" - -#: cps/editbooks.py:650 -#, python-format -msgid "Failed to create path %(path)s (Permission denied)." -msgstr "%(path)s 경로를 생성하지 못했습니다(권한이 없음)." - -#: cps/editbooks.py:655 -#, python-format -msgid "Failed to store file %(file)s." -msgstr "%(file)s 파일을 저장하지 못했습니다." - -#: cps/editbooks.py:673 cps/editbooks.py:1076 cps/web.py:1664 +#: cps/admin.py:1223 cps/admin.py:1339 cps/admin.py:1437 cps/admin.py:1554 +#: cps/admin.py:1623 cps/editbooks.py:678 cps/editbooks.py:882 +#: cps/editbooks.py:1130 cps/shelf.py:100 cps/shelf.py:160 cps/shelf.py:203 +#: cps/shelf.py:278 cps/shelf.py:343 cps/shelf.py:380 cps/shelf.py:456 +#: cps/web.py:1742 #, python-format msgid "Database error: %(error)s." msgstr "데이터베이스 오류: %(error)s." -#: cps/editbooks.py:678 +#: cps/admin.py:1235 +msgid "DB Location is not Valid, Please Enter Correct Path" +msgstr "올바르지 않은 DB 위치. 올바른 경로 입력 필요" + +#: cps/admin.py:1253 +msgid "DB is not Writeable" +msgstr "쓰기 권한이 없는 DB" + +#: cps/admin.py:1266 +msgid "Keyfile Location is not Valid, Please Enter Correct Path" +msgstr "올바르지 않은 키 파일 위치. 올바른 경로 입력 필요" + +#: cps/admin.py:1270 +msgid "Certfile Location is not Valid, Please Enter Correct Path" +msgstr "올바르지 않은 인증서 파일 위치. 올바른 경로 입력 필요" + +#: cps/admin.py:1378 +msgid "Database Settings updated" +msgstr "데이터베이스 설정이 업데이트 되었습니다" + +#: cps/admin.py:1386 +msgid "Database Configuration" +msgstr "데이터베이스 구성" + +#: cps/admin.py:1402 cps/web.py:1557 +msgid "Please fill out all fields!" +msgstr "모든 필드를 채워주십시오!" + +#: cps/admin.py:1410 +msgid "E-mail is not from valid domain" +msgstr "유효한 도메인에서 온 이메일이 아니" + +#: cps/admin.py:1416 cps/admin.py:1576 +msgid "Add new user" +msgstr "새 사용자 추가" + +#: cps/admin.py:1427 +#, python-format +msgid "User '%(user)s' created" +msgstr "사용자 '%(user)s'이(가) 생성됨" + +#: cps/admin.py:1433 +msgid "Found an existing account for this e-mail address or name." +msgstr "동일한 이메일 주소 또는 이름이 이미 등록되어 있습니다." + +#: cps/admin.py:1463 +#, python-format +msgid "User '%(nick)s' deleted" +msgstr "사용자 '%(nick)s'이(가) 삭제됨" + +#: cps/admin.py:1465 cps/admin.py:1466 +msgid "Can't delete Guest User" +msgstr "게스트 사용자는 삭제할 수 없습니다" + +#: cps/admin.py:1469 +msgid "No admin user remaining, can't delete user" +msgstr "관리자 계정이 하나 뿐일 때는 관리자 권한을 삭제할 수 없음" + +#: cps/admin.py:1542 cps/admin.py:1667 +#, python-format +msgid "Edit User %(nick)s" +msgstr "사용자 %(nick)s 편집" + +#: cps/admin.py:1546 +#, python-format +msgid "User '%(nick)s' updated" +msgstr "사용자 '%(nick)s'가 업데이트 됨" + +#: cps/admin.py:1550 cps/admin.py:1682 cps/web.py:1582 cps/web.py:1642 +msgid "An unknown error occurred. Please try again later." +msgstr "알 수없는 오류가 발생했습니다. 나중에 다시 시도 해주십시오." + +#: cps/admin.py:1585 cps/templates/admin.html:100 +msgid "Edit E-mail Server Settings" +msgstr "이메일 서버 설정 편집" + +#: cps/admin.py:1604 +msgid "Gmail Account Verification Successful" +msgstr "Gmail 계정 인증 성공" + +#: cps/admin.py:1630 +#, python-format +msgid "Test e-mail queued for sending to %(email)s, please check Tasks for result" +msgstr "%(email)s에 테스트를 위한 이메일을 보냄. 결과 확인 필요" + +#: cps/admin.py:1633 +#, python-format +msgid "There was an error sending the Test e-mail: %(res)s" +msgstr "테스트 이메일을 보내는 동안 오류가 발생했습니다: %(res)s" + +#: cps/admin.py:1635 +msgid "Please configure your e-mail address first..." +msgstr "먼저 이메일 주소를 구성하십시오..." + +#: cps/admin.py:1637 +msgid "E-mail server settings updated" +msgstr "이메일 서버 설정 업데이트됨" + +#: cps/admin.py:1679 +#, python-format +msgid "Password for user %(user)s reset" +msgstr "사용자 %(user)s의 비밀번호 재설정" + +#: cps/admin.py:1685 cps/web.py:1522 +msgid "Please configure the SMTP mail settings first..." +msgstr "먼저 SMTP 메일 설정을 구성하십시오..." + +#: cps/admin.py:1696 +msgid "Logfile viewer" +msgstr "로그 파일 뷰어" + +#: cps/admin.py:1762 +msgid "Requesting update package" +msgstr "업데이트 패키지 요청" + +#: cps/admin.py:1763 +msgid "Downloading update package" +msgstr "업데이트 패키지 다운로드" + +#: cps/admin.py:1764 +msgid "Unzipping update package" +msgstr "업데이트 패키지 압축 풀기" + +#: cps/admin.py:1765 +msgid "Replacing files" +msgstr "파일 교체" + +#: cps/admin.py:1766 +msgid "Database connections are closed" +msgstr "데이터베이스 연결이 닫힙니다" + +#: cps/admin.py:1767 +msgid "Stopping server" +msgstr "서버 중지" + +#: cps/admin.py:1768 +msgid "Update finished, please press okay and reload page" +msgstr "업데이트가 완료되었습니다. 확인을 누르고 페이지를 새로고침하세요" + +#: cps/admin.py:1769 cps/admin.py:1770 cps/admin.py:1771 cps/admin.py:1772 +#: cps/admin.py:1773 cps/admin.py:1774 +msgid "Update failed:" +msgstr "업데이트 실패:" + +#: cps/admin.py:1769 cps/updater.py:384 cps/updater.py:619 cps/updater.py:621 +msgid "HTTP Error" +msgstr "HTTP 오류" + +#: cps/admin.py:1770 cps/updater.py:386 cps/updater.py:623 +msgid "Connection error" +msgstr "연결 오류" + +#: cps/admin.py:1771 cps/updater.py:388 cps/updater.py:625 +msgid "Timeout while establishing connection" +msgstr "연결 설정 중 시간 초과" + +#: cps/admin.py:1772 cps/updater.py:390 cps/updater.py:627 +msgid "General error" +msgstr "일반 오류" + +#: cps/admin.py:1773 +msgid "Update file could not be saved in temp dir" +msgstr "임시 디렉토리에 업데이트 파일을 저장할 수 없습니다" + +#: cps/admin.py:1774 +msgid "Files could not be replaced during update" +msgstr "업데이트하는 동안 파일을 교체할 수 없습니다" + +#: cps/admin.py:1798 +msgid "Failed to extract at least One LDAP User" +msgstr "하나 이상의 LDAP 사용자를 추출하지 못했습니다" + +#: cps/admin.py:1843 +msgid "Failed to Create at Least One LDAP User" +msgstr "하나 이상의 LDAP 사용자를 생성하지 못했습니다" + +#: cps/admin.py:1856 +#, python-format +msgid "Error: %(ldaperror)s" +msgstr "오류: %(ldaperror)s" + +#: cps/admin.py:1860 +msgid "Error: No user returned in response of LDAP server" +msgstr "오류: LDAP 서버의 응답으로 사용자가 반환되지 않았습니다" + +#: cps/admin.py:1893 +msgid "At Least One LDAP User Not Found in Database" +msgstr "데이터베이스에서 하나 이상의 LDAP 사용자를 찾을 수 없습니다" + +#: cps/admin.py:1895 +msgid "{} User Successfully Imported" +msgstr "{} 사용자 가져오기 성공" + +#: cps/converter.py:30 +msgid "not installed" +msgstr "설치되지 않음" + +#: cps/converter.py:31 +msgid "Execution permissions missing" +msgstr "실행 권한 누락" + +#: cps/db.py:674 cps/web.py:710 cps/web.py:1222 +#, python-format +msgid "Custom Column No.%(column)d is not existing in calibre database" +msgstr "사용자 정의 열 번호 %(column)d이(가) calibre 데이터베이스에 없습니다" + +#: cps/db.py:917 cps/templates/config_edit.html:204 +#: cps/templates/config_view_edit.html:62 cps/templates/email_edit.html:41 +#: cps/web.py:551 cps/web.py:585 cps/web.py:646 cps/web.py:671 cps/web.py:1003 +#: cps/web.py:1032 cps/web.py:1066 cps/web.py:1093 cps/web.py:1132 +msgid "None" +msgstr "None" + +#: cps/editbooks.py:295 cps/editbooks.py:297 +msgid "Book Format Successfully Deleted" +msgstr "책 형식이 성공적으로 삭제되었습니다" + +#: cps/editbooks.py:304 cps/editbooks.py:306 +msgid "Book Successfully Deleted" +msgstr "책이 성공적으로 삭제되었습니다" + +#: cps/editbooks.py:358 +msgid "You are missing permissions to delete books" +msgstr "" + +#: cps/editbooks.py:373 cps/editbooks.py:765 cps/web.py:518 cps/web.py:1783 +#: cps/web.py:1825 cps/web.py:1870 +msgid "Oops! Selected book title is unavailable. File does not exist or is not accessible" +msgstr "선택한 책 제목을 사용할 수 없습니다. 파일이 존재하지 않거나 액세스할 수 없습니다" + +#: cps/editbooks.py:408 +msgid "edit metadata" +msgstr "메타데이터 편집" + +#: cps/editbooks.py:457 +#, python-format +msgid "%(seriesindex)s is not a valid number, skipping" +msgstr "%(seriesindex)s은(는) 유효한 숫자가 아닙니다. 건너뜁니다" + +#: cps/editbooks.py:493 cps/editbooks.py:1001 +#, python-format +msgid "'%(langname)s' is not a valid language" +msgstr "'%(langname)s'은(는) 유효한 언어가 아닙니다" + +#: cps/editbooks.py:634 +msgid "User has no rights to upload additional file formats" +msgstr "" + +#: cps/editbooks.py:639 cps/editbooks.py:1029 +#, python-format +msgid "File extension '%(ext)s' is not allowed to be uploaded to this server" +msgstr "파일 확장자 '%(ext)s'은(는) 이 서버에 업로드할 수 없습니다" + +#: cps/editbooks.py:643 cps/editbooks.py:1033 +msgid "File to be uploaded must have an extension" +msgstr "업로드할 파일에는 확장자가 있어야 합니다" + +#: cps/editbooks.py:655 +#, python-format +msgid "Failed to create path %(path)s (Permission denied)." +msgstr "%(path)s 경로를 생성하지 못했습니다(권한이 없음)." + +#: cps/editbooks.py:660 +#, python-format +msgid "Failed to store file %(file)s." +msgstr "%(file)s 파일을 저장하지 못했습니다." + +#: cps/editbooks.py:683 #, python-format msgid "File format %(ext)s added to %(book)s" msgstr "파일 형식 %(ext)s이(가) %(book)s에 추가되었습니다" -#: cps/editbooks.py:814 +#: cps/editbooks.py:697 cps/editbooks.py:809 +msgid "User has no rights to upload cover" +msgstr "" + +#: cps/editbooks.py:828 msgid "Identifiers are not Case Sensitive, Overwriting Old Identifier" msgstr "식별자는 대소문자를 구분하지 않으며 이전 식별자를 덮어씁니다" -#: cps/editbooks.py:848 +#: cps/editbooks.py:869 msgid "Metadata successfully updated" msgstr "메타데이터가 성공적으로 업데이트되었습니다" -#: cps/editbooks.py:861 -msgid "Error editing book, please check logfile for details" -msgstr "책을 수정하는 동안 오류가 발생했습니다. 자세한 내용은 로그 파일을 확인하세요" +#: cps/editbooks.py:887 +msgid "Error editing book: {}" +msgstr "" -#: cps/editbooks.py:899 +#: cps/editbooks.py:951 msgid "Uploaded book probably exists in the library, consider to change before upload new: " msgstr "업로드한 책이 라이브러리에 있을 수 있음. 새로 업로드하기 전에 확인 필요: " -#: cps/editbooks.py:997 +#: cps/editbooks.py:1041 #, python-format msgid "File %(filename)s could not saved to temp dir" msgstr "파일 %(filename)s을(를) 임시 디렉토리에 저장할 수 없습니다" -#: cps/editbooks.py:1016 +#: cps/editbooks.py:1061 #, python-format msgid "Failed to Move Cover File %(file)s: %(error)s" msgstr "표지 파일%(file)s를 이동하지 못했습니다.:%(error)s" -#: cps/editbooks.py:1063 +#: cps/editbooks.py:1117 #, python-format msgid "File %(file)s uploaded" msgstr "파일 %(file)s 업로드됨" -#: cps/editbooks.py:1088 +#: cps/editbooks.py:1143 msgid "Source or destination format for conversion missing" msgstr "변환을 위한 소스 또는 대상 형식이 누락되었습니다" -#: cps/editbooks.py:1096 +#: cps/editbooks.py:1151 #, python-format msgid "Book successfully queued for converting to %(book_format)s" msgstr "책이 %(book_format)s(으)로 변환하기 위해 대기 중입니다" -#: cps/editbooks.py:1100 +#: cps/editbooks.py:1155 #, python-format msgid "There was an error converting this book: %(res)s" msgstr "이 책을 변환하는 동안 오류가 발생했습니다: %(res)s" @@ -599,174 +602,191 @@ msgstr "Google 드라이브 설정이 완료되지 않았습니다. Google 드 msgid "Callback domain is not verified, please follow steps to verify domain in google developer console" msgstr "콜백 도메인이 확인되지 않았습니다. 단계에 따라 Google 개발자 콘솔에서 도메인을 확인하세요" -#: cps/helper.py:77 +#: cps/helper.py:81 #, python-format msgid "%(format)s format not found for book id: %(book)d" msgstr "책 ID에 대한 %(format)s 형식을 찾을 수 없음: %(book)d" -#: cps/helper.py:83 cps/tasks/convert.py:73 +#: cps/helper.py:87 cps/tasks/convert.py:75 #, python-format msgid "%(format)s not found on Google Drive: %(fn)s" msgstr "%(format)s을(를) Google 드라이브에서 찾을 수 없음: %(fn)s" -#: cps/helper.py:88 +#: cps/helper.py:92 #, python-format msgid "%(format)s not found: %(fn)s" msgstr "%(format)s을(를) 찾을 수 없음: %(fn)s" -#: cps/helper.py:93 cps/helper.py:217 cps/templates/detail.html:41 +#: cps/helper.py:97 cps/helper.py:221 cps/templates/detail.html:41 #: cps/templates/detail.html:45 msgid "Send to Kindle" msgstr "킨들로 보내기" -#: cps/helper.py:94 cps/helper.py:111 cps/helper.py:219 +#: cps/helper.py:98 cps/helper.py:115 cps/helper.py:223 msgid "This e-mail has been sent via Calibre-Web." msgstr "이 이메일은 Calibre Web을 통해 전송되었습니다." -#: cps/helper.py:109 +#: cps/helper.py:113 msgid "Calibre-Web test e-mail" msgstr "Calibre-Web 테스트 이메일" -#: cps/helper.py:110 +#: cps/helper.py:114 msgid "Test e-mail" msgstr "테스트 이메일" -#: cps/helper.py:127 +#: cps/helper.py:131 msgid "Get Started with Calibre-Web" msgstr "Calibre-Web 시작하기" -#: cps/helper.py:132 +#: cps/helper.py:136 #, python-format msgid "Registration e-mail for user: %(name)s" msgstr "사용자 등록 이메일: %(name)s" -#: cps/helper.py:143 cps/helper.py:149 +#: cps/helper.py:147 cps/helper.py:153 #, python-format msgid "Convert %(orig)s to %(format)s and send to Kindle" msgstr "%(orig)s를 %(format)s로 변환하고 킨들로 보내기" -#: cps/helper.py:168 cps/helper.py:172 cps/helper.py:176 +#: cps/helper.py:172 cps/helper.py:176 cps/helper.py:180 #, python-format msgid "Send %(format)s to Kindle" msgstr "킨들에 %(format)s 보내기" -#: cps/helper.py:216 cps/tasks/convert.py:90 +#: cps/helper.py:220 cps/tasks/convert.py:92 #, python-format msgid "%(book)s send to Kindle" msgstr "%(book)s을 킨들로 보내기" -#: cps/helper.py:221 +#: cps/helper.py:225 msgid "The requested file could not be read. Maybe wrong permissions?" msgstr "요청한 파일을 읽을 수 없습니다. 올바른 권한인가요?" -#: cps/helper.py:313 +#: cps/helper.py:353 +msgid "Read status could not set: {}" +msgstr "" + +#: cps/helper.py:376 #, python-format msgid "Deleting bookfolder for book %(id)s failed, path has subfolders: %(path)s" msgstr "책 %(id)s에 대한 책 폴더를 삭제하지 못했습니다. 경로에 하위 폴더가 있습니다: %(path)s" -#: cps/helper.py:319 +#: cps/helper.py:382 #, python-format msgid "Deleting book %(id)s failed: %(message)s" msgstr "%(id)s 도서 삭제 실패: %(message)s" -#: cps/helper.py:330 +#: cps/helper.py:393 #, python-format msgid "Deleting book %(id)s from database only, book path in database not valid: %(path)s" msgstr "데이터베이스에서만 책 %(id)s 을(를) 삭제 중, 데이터베이스의 책 경로가 유효하지 않음: %(path)s" -#: cps/helper.py:385 -#, python-format -msgid "Rename title from: '%(src)s' to '%(dest)s' failed with error: %(error)s" +#: cps/helper.py:458 +#, fuzzy, python-format +msgid "Rename author from: '%(src)s' to '%(dest)s' failed with error: %(error)s" msgstr "제목 이름을 '%(src)s'에서 '%(dest)s'(으)로 변경하지 못했습니다. 오류: %(error)s" -#: cps/helper.py:400 -#, python-format -msgid "Rename file in path '%(src)s' to '%(dest)s' failed with error: %(error)s" -msgstr "'%(src)s' 경로의 파일 이름을 '%(dest)s'(으)로 변경하지 못했습니다. 오류: %(error)s" - -#: cps/helper.py:425 cps/helper.py:435 cps/helper.py:443 +#: cps/helper.py:529 cps/helper.py:538 #, python-format msgid "File %(file)s not found on Google Drive" msgstr "Google 드라이브에서 %(file)s 파일을 찾을 수 없습니다" -#: cps/helper.py:464 +#: cps/helper.py:572 +#, python-format +msgid "Rename title from: '%(src)s' to '%(dest)s' failed with error: %(error)s" +msgstr "제목 이름을 '%(src)s'에서 '%(dest)s'(으)로 변경하지 못했습니다. 오류: %(error)s" + +#: cps/helper.py:592 +msgid "Error in rename file in path: {}" +msgstr "" + +#: cps/helper.py:610 #, python-format msgid "Book path %(path)s not found on Google Drive" msgstr "Google 드라이브에서 책 경로 %(path)s을(를) 찾을 수 없습니다" -#: cps/helper.py:504 cps/web.py:1659 +#: cps/helper.py:651 cps/web.py:1737 msgid "Found an existing account for this e-mail address" msgstr "등록되어 있는 이메일 주소입니다" -#: cps/helper.py:512 +#: cps/helper.py:659 msgid "This username is already taken" msgstr "등록되어 있는 username입니다" -#: cps/helper.py:522 +#: cps/helper.py:669 msgid "Invalid e-mail address format" msgstr "이메일 주소 형식이 잘못되었습니다" -#: cps/helper.py:595 +#: cps/helper.py:754 +msgid "Python modul 'advocate' is not installed but is needed for cover downloads" +msgstr "" + +#: cps/helper.py:767 msgid "Error Downloading Cover" msgstr "표지 다운로드 중 오류 발생" -#: cps/helper.py:598 +#: cps/helper.py:770 msgid "Cover Format Error" msgstr "표지 형식 오류" -#: cps/helper.py:608 +#: cps/helper.py:773 +msgid "You are not allowed to access localhost or the local network for cover uploads" +msgstr "" + +#: cps/helper.py:783 msgid "Failed to create path for cover" msgstr "표지 경로 생성 실패" -#: cps/helper.py:624 +#: cps/helper.py:799 msgid "Cover-file is not a valid image file, or could not be stored" msgstr "표지 파일이 유효한 이미지 파일이 아니거나 저장할 수 없습니다" -#: cps/helper.py:635 +#: cps/helper.py:810 msgid "Only jpg/jpeg/png/webp/bmp files are supported as coverfile" msgstr "표지는 jpg/jpeg/png/webp/bmp 파일만 지원됩니다" -#: cps/helper.py:648 +#: cps/helper.py:822 msgid "Invalid cover file content" msgstr "잘못된 표지 파일 콘텐츠" -#: cps/helper.py:652 +#: cps/helper.py:826 msgid "Only jpg/jpeg files are supported as coverfile" msgstr "표지 파일로 jpg/jpeg 파일만 지원됩니다" -#: cps/helper.py:704 +#: cps/helper.py:878 msgid "Unrar binary file not found" msgstr "Unrar 바이너리 파일을 찾을 수 없습니다" -#: cps/helper.py:715 +#: cps/helper.py:889 msgid "Error excecuting UnRar" msgstr "UnRar 실행 오류" -#: cps/helper.py:763 +#: cps/helper.py:937 msgid "Waiting" msgstr "대기중" -#: cps/helper.py:765 +#: cps/helper.py:939 msgid "Failed" msgstr "실패" -#: cps/helper.py:767 +#: cps/helper.py:941 msgid "Started" msgstr "시작됨" -#: cps/helper.py:769 +#: cps/helper.py:943 msgid "Finished" msgstr "종료" -#: cps/helper.py:771 +#: cps/helper.py:945 msgid "Unknown Status" msgstr "알 수 없는 상태" -#: cps/kobo_auth.py:127 -msgid "PLease access calibre-web from non localhost to get valid api_endpoint for kobo device" +#: cps/kobo_auth.py:128 +#, fuzzy +msgid "Please access Calibre-Web from non localhost to get valid api_endpoint for kobo device" msgstr "코보(kobo) 장치에 대한 유효한 api_endpoint를 얻으려면 로컬 호스트가 아닌 곳에서 calibre-web에 액세스하십시오" -#: cps/kobo_auth.py:130 cps/kobo_auth.py:158 +#: cps/kobo_auth.py:154 msgid "Kobo Setup" msgstr "Kobo 설정" @@ -775,7 +795,7 @@ msgstr "Kobo 설정" msgid "Register with %(provider)s" msgstr "%(provider)s에 등록" -#: cps/oauth_bb.py:138 cps/remotelogin.py:133 cps/web.py:1535 +#: cps/oauth_bb.py:138 cps/remotelogin.py:130 cps/web.py:1613 #, python-format msgid "you are now logged in as: '%(nickname)s'" msgstr "다음 사용자로 로그인했습니다: '%(nickname)s'" @@ -836,163 +856,163 @@ msgstr "Google 인증 오류입니다. 나중에 다시 시도하세요." msgid "Google Oauth error: {}" msgstr "Google 인증 오류: {}" -#: cps/opds.py:384 +#: cps/opds.py:298 msgid "{} Stars" msgstr "{} Stars" -#: cps/remotelogin.py:65 cps/templates/layout.html:84 -#: cps/templates/login.html:4 cps/templates/login.html:21 cps/web.py:1584 +#: cps/remotelogin.py:62 cps/templates/layout.html:84 +#: cps/templates/login.html:4 cps/templates/login.html:21 cps/web.py:1662 msgid "Login" msgstr "로그인" -#: cps/remotelogin.py:77 cps/remotelogin.py:111 +#: cps/remotelogin.py:74 cps/remotelogin.py:108 msgid "Token not found" msgstr "토큰을 찾을 수 없습니다" -#: cps/remotelogin.py:86 cps/remotelogin.py:119 +#: cps/remotelogin.py:83 cps/remotelogin.py:116 msgid "Token has expired" msgstr "토큰이 만료되었습니다" -#: cps/remotelogin.py:95 +#: cps/remotelogin.py:92 msgid "Success! Please return to your device" msgstr "성공! 기기로 돌아가주세요" -#: cps/render_template.py:39 cps/web.py:416 +#: cps/render_template.py:41 cps/web.py:407 msgid "Books" msgstr "책" -#: cps/render_template.py:41 +#: cps/render_template.py:43 msgid "Show recent books" msgstr "최근 책 보기" -#: cps/render_template.py:42 cps/templates/index.xml:25 +#: cps/render_template.py:44 cps/templates/index.xml:25 msgid "Hot Books" msgstr "인기있는 책" -#: cps/render_template.py:44 +#: cps/render_template.py:46 msgid "Show Hot Books" msgstr "주목받는 책 보기" -#: cps/render_template.py:46 cps/render_template.py:51 +#: cps/render_template.py:48 cps/render_template.py:53 msgid "Downloaded Books" msgstr "다운로드된 책" -#: cps/render_template.py:48 cps/render_template.py:53 +#: cps/render_template.py:50 cps/render_template.py:55 #: cps/templates/user_table.html:167 msgid "Show Downloaded Books" msgstr "다운로드된 책 보기" -#: cps/render_template.py:56 cps/templates/index.xml:32 cps/web.py:430 +#: cps/render_template.py:58 cps/templates/index.xml:32 cps/web.py:422 msgid "Top Rated Books" msgstr "평점이 높은 책" -#: cps/render_template.py:58 cps/templates/user_table.html:161 +#: cps/render_template.py:60 cps/templates/user_table.html:161 msgid "Show Top Rated Books" msgstr "평점이 높은 책 보기" -#: cps/render_template.py:59 cps/templates/index.xml:54 -#: cps/templates/index.xml:58 cps/web.py:676 +#: cps/render_template.py:61 cps/templates/index.xml:54 +#: cps/templates/index.xml:58 cps/web.py:729 msgid "Read Books" msgstr "읽은 책" -#: cps/render_template.py:61 +#: cps/render_template.py:63 msgid "Show read and unread" msgstr "읽은 책과 읽지 않은 책 보기" -#: cps/render_template.py:63 cps/templates/index.xml:61 -#: cps/templates/index.xml:65 cps/web.py:679 +#: cps/render_template.py:65 cps/templates/index.xml:61 +#: cps/templates/index.xml:65 cps/web.py:732 msgid "Unread Books" msgstr "읽지 않은 책" -#: cps/render_template.py:65 +#: cps/render_template.py:67 msgid "Show unread" msgstr "읽지 않은 책 보기" -#: cps/render_template.py:66 +#: cps/render_template.py:68 msgid "Discover" msgstr "발견" -#: cps/render_template.py:68 cps/templates/index.xml:50 +#: cps/render_template.py:70 cps/templates/index.xml:50 #: cps/templates/user_table.html:162 msgid "Show Random Books" msgstr "무작위 추천" -#: cps/render_template.py:69 cps/templates/book_table.html:67 -#: cps/templates/index.xml:83 cps/web.py:1041 +#: cps/render_template.py:71 cps/templates/book_table.html:67 +#: cps/templates/index.xml:83 cps/web.py:1135 msgid "Categories" msgstr "카테고리" -#: cps/render_template.py:71 cps/templates/user_table.html:158 +#: cps/render_template.py:73 cps/templates/user_table.html:158 msgid "Show category selection" msgstr "카테고리별 보기" -#: cps/render_template.py:72 cps/templates/book_edit.html:90 +#: cps/render_template.py:74 cps/templates/book_edit.html:90 #: cps/templates/book_table.html:68 cps/templates/index.xml:90 -#: cps/templates/search_form.html:69 cps/web.py:948 cps/web.py:959 +#: cps/templates/search_form.html:69 cps/web.py:1034 cps/web.py:1041 msgid "Series" msgstr "시리즈" -#: cps/render_template.py:74 cps/templates/user_table.html:157 +#: cps/render_template.py:76 cps/templates/user_table.html:157 msgid "Show series selection" msgstr "시리즈별 보기" -#: cps/render_template.py:75 cps/templates/book_table.html:66 +#: cps/render_template.py:77 cps/templates/book_table.html:66 #: cps/templates/index.xml:69 msgid "Authors" msgstr "저자" -#: cps/render_template.py:77 cps/templates/user_table.html:160 +#: cps/render_template.py:79 cps/templates/user_table.html:160 msgid "Show author selection" msgstr "저자별 보기" -#: cps/render_template.py:79 cps/templates/book_table.html:72 -#: cps/templates/index.xml:76 cps/web.py:925 +#: cps/render_template.py:81 cps/templates/book_table.html:72 +#: cps/templates/index.xml:76 cps/web.py:1006 msgid "Publishers" msgstr "출판사" -#: cps/render_template.py:81 cps/templates/user_table.html:163 +#: cps/render_template.py:83 cps/templates/user_table.html:163 msgid "Show publisher selection" msgstr "출판사별 보기" -#: cps/render_template.py:82 cps/templates/book_table.html:70 +#: cps/render_template.py:84 cps/templates/book_table.html:70 #: cps/templates/index.xml:97 cps/templates/search_form.html:107 -#: cps/web.py:1018 +#: cps/web.py:1108 msgid "Languages" msgstr "언어" -#: cps/render_template.py:85 cps/templates/user_table.html:155 +#: cps/render_template.py:87 cps/templates/user_table.html:155 msgid "Show language selection" msgstr "언어별 보기" -#: cps/render_template.py:86 cps/templates/index.xml:104 +#: cps/render_template.py:88 cps/templates/index.xml:104 msgid "Ratings" msgstr "평점" -#: cps/render_template.py:88 cps/templates/user_table.html:164 +#: cps/render_template.py:90 cps/templates/user_table.html:164 msgid "Show ratings selection" msgstr "평점별 보기" -#: cps/render_template.py:89 cps/templates/index.xml:112 +#: cps/render_template.py:91 cps/templates/index.xml:112 msgid "File formats" msgstr "파일 유형" -#: cps/render_template.py:91 cps/templates/user_table.html:165 +#: cps/render_template.py:93 cps/templates/user_table.html:165 msgid "Show file formats selection" msgstr "파일 유형별 보기" -#: cps/render_template.py:93 cps/web.py:703 +#: cps/render_template.py:95 cps/web.py:755 msgid "Archived Books" msgstr "보관된 책" -#: cps/render_template.py:95 cps/templates/user_table.html:166 +#: cps/render_template.py:97 cps/templates/user_table.html:166 msgid "Show archived books" msgstr "보관된 책 보기" -#: cps/render_template.py:97 cps/web.py:780 +#: cps/render_template.py:100 cps/web.py:837 msgid "Books List" msgstr "책 목록" -#: cps/render_template.py:99 cps/templates/user_table.html:168 +#: cps/render_template.py:102 cps/templates/user_table.html:168 msgid "Show Books List" msgstr "책 목록 보기" @@ -1046,261 +1066,265 @@ msgstr "죄송합니다. 이 서가에서 책을 삭제할 권한이 없습니 msgid "Create a Shelf" msgstr "책장 추가" -#: cps/shelf.py:237 +#: cps/shelf.py:236 msgid "Sorry you are not allowed to edit this shelf" msgstr "죄송합니다. 이 책장을 편집할 권한이 없습니다" -#: cps/shelf.py:239 +#: cps/shelf.py:238 msgid "Edit a shelf" msgstr "책장 편집" -#: cps/shelf.py:249 +#: cps/shelf.py:248 msgid "Sorry you are not allowed to create a public shelf" msgstr "죄송합니다. 이 공개 책장을 만들 권한이 없습니다" -#: cps/shelf.py:266 +#: cps/shelf.py:265 #, python-format msgid "Shelf %(title)s created" msgstr "%(title)s 책장이 추가됨" -#: cps/shelf.py:269 +#: cps/shelf.py:268 #, python-format msgid "Shelf %(title)s changed" msgstr "%(title)s 책장이 변경됨" -#: cps/shelf.py:283 +#: cps/shelf.py:282 msgid "There was an error" msgstr "오류가 발생하였습니다" -#: cps/shelf.py:305 +#: cps/shelf.py:304 #, python-format msgid "A public shelf with the name '%(title)s' already exists." msgstr "이름이 '%(title)s'인 공개 책장이 이미 있습니다." -#: cps/shelf.py:316 +#: cps/shelf.py:315 #, python-format msgid "A private shelf with the name '%(title)s' already exists." msgstr "이름이 '%(title)s'인 개인 책장이 이미 있습니다." #: cps/shelf.py:337 +msgid "Error deleting Shelf" +msgstr "" + +#: cps/shelf.py:339 #, fuzzy msgid "Shelf successfully deleted" msgstr "책이 성공적으로 삭제되었습니다" -#: cps/shelf.py:386 +#: cps/shelf.py:389 #, python-format msgid "Change order of Shelf: '%(name)s'" msgstr "책장 순서 변경: '%(name)s'" -#: cps/shelf.py:456 +#: cps/shelf.py:461 #, python-format msgid "Shelf: '%(name)s'" msgstr "책장: '%(name)s'" -#: cps/shelf.py:460 +#: cps/shelf.py:465 msgid "Error opening shelf. Shelf does not exist or is not accessible" msgstr "책장을 여는 동안 오류가 발생했습니다. 책장이 존재하지 않거나 접근할 수 없습니다" -#: cps/updater.py:403 cps/updater.py:414 cps/updater.py:514 cps/updater.py:529 +#: cps/updater.py:426 cps/updater.py:437 cps/updater.py:538 cps/updater.py:553 msgid "Unexpected data while reading update information" msgstr "업데이트 정보를 읽는 동안 예기치 않은 데이터" -#: cps/updater.py:410 cps/updater.py:521 +#: cps/updater.py:433 cps/updater.py:545 msgid "No update available. You already have the latest version installed" msgstr "업데이트가 없습니다. 이미 최신 버전이 설치되어 있습니다" -#: cps/updater.py:428 +#: cps/updater.py:451 msgid "A new update is available. Click on the button below to update to the latest version." msgstr "새로운 업데이트가 있습니다. 아래 버튼을 클릭하여 최신 버전으로 업데이트하십시오." -#: cps/updater.py:446 +#: cps/updater.py:469 msgid "Could not fetch update information" msgstr "업데이트 정보를 가져올 수 없습니다" -#: cps/updater.py:456 +#: cps/updater.py:479 msgid "Click on the button below to update to the latest stable version." msgstr "새로운 업데이트가 있습니다. 아래 버튼을 클릭하여 최신 버전으로 업데이트하십시오." -#: cps/updater.py:465 cps/updater.py:479 cps/updater.py:490 +#: cps/updater.py:488 cps/updater.py:502 cps/updater.py:513 #, python-format msgid "A new update is available. Click on the button below to update to version: %(version)s" msgstr "최신 안정 버전 %(version)s으로 업데이트하려면 아래 버튼을 클릭하세요" -#: cps/updater.py:507 +#: cps/updater.py:531 msgid "No release information available" msgstr "출시 정보가 없습니다" -#: cps/templates/index.html:5 cps/web.py:440 +#: cps/templates/index.html:5 cps/web.py:434 msgid "Discover (Random Books)" msgstr "발견(무작위 도서)" -#: cps/web.py:471 +#: cps/web.py:470 msgid "Hot Books (Most Downloaded)" msgstr "인기있는 책(가장 많이 다운로드됨)" -#: cps/web.py:507 +#: cps/web.py:501 #, python-format msgid "Downloaded books by %(user)s" msgstr "%(user)s이(가) 다운로드한 책" -#: cps/web.py:539 +#: cps/web.py:534 #, python-format msgid "Author: %(name)s" msgstr "저자: %(name)s" -#: cps/web.py:554 +#: cps/web.py:570 #, python-format msgid "Publisher: %(name)s" msgstr "출판사: %(name)s" -#: cps/web.py:569 +#: cps/web.py:598 #, python-format msgid "Series: %(serie)s" msgstr "시리즈: %(serie)s" -#: cps/web.py:582 +#: cps/web.py:610 #, python-format msgid "Rating: %(rating)s stars" msgstr "평가: %(rating)s 별" -#: cps/web.py:597 +#: cps/web.py:626 #, python-format msgid "File format: %(format)s" msgstr "파일 유형: %(format)s" -#: cps/web.py:615 +#: cps/web.py:663 #, python-format msgid "Category: %(name)s" msgstr "카테고리: %(name)s" -#: cps/web.py:631 +#: cps/web.py:690 #, python-format msgid "Language: %(name)s" msgstr "언어: %(name)s" -#: cps/templates/layout.html:56 cps/web.py:737 cps/web.py:1371 +#: cps/templates/layout.html:56 cps/web.py:789 cps/web.py:1444 msgid "Advanced Search" msgstr "상세 검색" #: cps/templates/book_edit.html:235 cps/templates/feed.xml:33 #: cps/templates/index.xml:11 cps/templates/layout.html:45 #: cps/templates/layout.html:48 cps/templates/search_form.html:226 -#: cps/web.py:750 cps/web.py:1077 +#: cps/web.py:807 cps/web.py:1164 msgid "Search" msgstr "검색" -#: cps/templates/admin.html:16 cps/web.py:903 +#: cps/templates/admin.html:16 cps/web.py:979 msgid "Downloads" msgstr "다운로드" -#: cps/web.py:980 +#: cps/web.py:1068 msgid "Ratings list" msgstr "평점 목록" -#: cps/web.py:1001 +#: cps/web.py:1095 msgid "File formats list" msgstr "파일 유형 목록" -#: cps/templates/layout.html:73 cps/templates/tasks.html:7 cps/web.py:1055 +#: cps/templates/layout.html:73 cps/templates/tasks.html:7 cps/web.py:1149 msgid "Tasks" msgstr "작업" -#: cps/web.py:1215 +#: cps/web.py:1286 msgid "Published after " msgstr "Published after " -#: cps/web.py:1222 +#: cps/web.py:1293 msgid "Published before " msgstr "Published before " -#: cps/web.py:1244 +#: cps/web.py:1315 #, python-format msgid "Rating <= %(rating)s" msgstr "평점 <= %(rating)s" -#: cps/web.py:1246 +#: cps/web.py:1317 #, python-format msgid "Rating >= %(rating)s" msgstr "평점 >= %(rating)s" -#: cps/web.py:1248 +#: cps/web.py:1319 #, python-format msgid "Read Status = %(status)s" msgstr "읽은 상태 = %(status)s" -#: cps/web.py:1353 +#: cps/web.py:1425 msgid "Error on search for custom columns, please restart Calibre-Web" msgstr "사용자 정의 열을 검색하는 동안 오류가 발생했습니다. Calibre-Web을 다시 시작하십시오" -#: cps/web.py:1449 +#: cps/web.py:1527 #, python-format msgid "Book successfully queued for sending to %(kindlemail)s" msgstr "성공적으로 %(kindlemail)s에 보내기 예약이 되었습니다" -#: cps/web.py:1453 +#: cps/web.py:1531 #, python-format msgid "Oops! There was an error sending this book: %(res)s" msgstr "책을 보내는 중에 오류 발생: %(res)s" -#: cps/web.py:1455 +#: cps/web.py:1533 msgid "Please update your profile with a valid Send to Kindle E-mail Address." msgstr "Kindle로 보내는 유효한 이메일 주소로 프로필을 업데이트하십시오." -#: cps/web.py:1472 +#: cps/web.py:1550 msgid "E-Mail server is not configured, please contact your administrator!" msgstr "이메일 서버가 구성되지 않았습니다. 관리자에게 문의하십시오!" -#: cps/templates/layout.html:85 cps/templates/register.html:17 cps/web.py:1473 -#: cps/web.py:1480 cps/web.py:1486 cps/web.py:1505 cps/web.py:1509 -#: cps/web.py:1515 +#: cps/templates/layout.html:85 cps/templates/register.html:17 cps/web.py:1551 +#: cps/web.py:1558 cps/web.py:1564 cps/web.py:1583 cps/web.py:1587 +#: cps/web.py:1593 msgid "Register" msgstr "등록" -#: cps/web.py:1507 +#: cps/web.py:1585 msgid "Your e-mail is not allowed to register" msgstr "이메일을 등록할 수 없습니다" -#: cps/web.py:1510 +#: cps/web.py:1588 msgid "Confirmation e-mail was send to your e-mail account." msgstr "확인을 위한 이메일이 발송되었습니다." -#: cps/web.py:1524 +#: cps/web.py:1602 msgid "Cannot activate LDAP authentication" msgstr "LDAP 인증을 활성화할 수 없습니다" -#: cps/web.py:1543 +#: cps/web.py:1621 #, python-format msgid "Fallback Login as: '%(nickname)s', LDAP Server not reachable, or user not known" msgstr "대체 로그인: '%(nickname)s', LDAP 서버에 연결할 수 없음 또는 사용자를 알 수 없음" -#: cps/web.py:1549 +#: cps/web.py:1627 #, python-format msgid "Could not login: %(message)s" msgstr "로그인 실패: %(message)s" -#: cps/web.py:1553 cps/web.py:1578 +#: cps/web.py:1631 cps/web.py:1656 msgid "Wrong Username or Password" msgstr "잘못된 사용자명 또는 비밀번호" -#: cps/web.py:1560 +#: cps/web.py:1638 msgid "New Password was send to your email address" msgstr "새 비밀번호가 이메일로 전송되었습니다" -#: cps/web.py:1566 +#: cps/web.py:1644 msgid "Please enter valid username to reset password" msgstr "비밀번호를 재설정하려면 유효한 사용자 이름을 입력하십시오" -#: cps/web.py:1573 +#: cps/web.py:1651 #, python-format msgid "You are now logged in as: '%(nickname)s'" msgstr "다음 사용자로 로그인: '%(nickname)s" -#: cps/web.py:1639 cps/web.py:1688 +#: cps/web.py:1717 cps/web.py:1766 #, python-format msgid "%(name)s's profile" msgstr "%(name)s 프로필" -#: cps/web.py:1655 +#: cps/web.py:1733 msgid "Profile updated" msgstr "프로필이 업데이트 됨" @@ -1308,36 +1332,36 @@ msgstr "프로필이 업데이트 됨" msgid "Found no valid gmail.json file with OAuth information" msgstr "인증 정보가 포함된 유효한 gmail.json 파일을 찾을 수 없습니다" -#: cps/tasks/convert.py:137 +#: cps/tasks/convert.py:154 #, python-format msgid "Calibre ebook-convert %(tool)s not found" msgstr "Calibre ebook-convert %(tool)s을(를) 찾을 수 없습니다" -#: cps/tasks/convert.py:163 +#: cps/tasks/convert.py:187 #, python-format msgid "%(format)s format not found on disk" msgstr "%(format)s 형식을 찾을 수 없습니다" -#: cps/tasks/convert.py:167 +#: cps/tasks/convert.py:191 msgid "Ebook converter failed with unknown error" msgstr "알 수 없는 오류로 인해 전자책 변환이 실패했습니다" -#: cps/tasks/convert.py:177 +#: cps/tasks/convert.py:201 #, python-format msgid "Kepubify-converter failed: %(error)s" msgstr "Kepubify 변환 실패: %(error)s" -#: cps/tasks/convert.py:199 +#: cps/tasks/convert.py:223 #, python-format msgid "Converted file not found or more than one file in folder %(folder)s" msgstr "변환된 파일을 찾을 수 없거나 %(folder)s 폴더에 하나 이상의 파일이 존재합니다" -#: cps/tasks/convert.py:222 +#: cps/tasks/convert.py:246 #, python-format msgid "Ebook-converter failed: %(error)s" msgstr "\"전자책 변환 실패: %(error)s" -#: cps/tasks/convert.py:245 +#: cps/tasks/convert.py:269 #, python-format msgid "Calibre failed with error: %(error)s" msgstr "오류로 인한 Calibre 실패: %(error)s" @@ -1392,7 +1416,7 @@ msgid "Edit" msgstr "편집" #: cps/templates/admin.html:25 cps/templates/book_edit.html:16 -#: cps/templates/book_table.html:97 cps/templates/modal_dialogs.html:63 +#: cps/templates/book_table.html:100 cps/templates/modal_dialogs.html:63 #: cps/templates/modal_dialogs.html:116 cps/templates/user_edit.html:67 #: cps/templates/user_table.html:149 msgid "Delete" @@ -1402,179 +1426,179 @@ msgstr "삭제" msgid "Public Shelf" msgstr "공개 책장" -#: cps/templates/admin.html:51 +#: cps/templates/admin.html:53 msgid "Add New User" msgstr "사용자 추가" -#: cps/templates/admin.html:53 +#: cps/templates/admin.html:55 msgid "Import LDAP Users" msgstr "LDAP 사용자 가져오기" -#: cps/templates/admin.html:60 +#: cps/templates/admin.html:62 msgid "E-mail Server Settings" msgstr "이메일 서버 설정" -#: cps/templates/admin.html:65 cps/templates/email_edit.html:31 +#: cps/templates/admin.html:67 cps/templates/email_edit.html:31 msgid "SMTP Hostname" msgstr "SMTP Hostname" -#: cps/templates/admin.html:69 cps/templates/email_edit.html:35 +#: cps/templates/admin.html:71 cps/templates/email_edit.html:35 msgid "SMTP Port" msgstr "SMTP Port" -#: cps/templates/admin.html:73 cps/templates/email_edit.html:39 +#: cps/templates/admin.html:75 cps/templates/email_edit.html:39 msgid "Encryption" msgstr "암호화" -#: cps/templates/admin.html:77 cps/templates/email_edit.html:47 +#: cps/templates/admin.html:79 cps/templates/email_edit.html:47 msgid "SMTP Login" msgstr "SMTP Login" -#: cps/templates/admin.html:81 cps/templates/admin.html:92 +#: cps/templates/admin.html:83 cps/templates/admin.html:94 #: cps/templates/email_edit.html:55 msgid "From E-mail" msgstr "From E-mail" -#: cps/templates/admin.html:88 +#: cps/templates/admin.html:90 msgid "E-Mail Service" msgstr "E-Mail Service" -#: cps/templates/admin.html:89 +#: cps/templates/admin.html:91 msgid "Gmail via Oauth2" msgstr "Gmail via Oauth2" -#: cps/templates/admin.html:104 +#: cps/templates/admin.html:106 msgid "Configuration" msgstr "환경 설정" -#: cps/templates/admin.html:107 +#: cps/templates/admin.html:109 msgid "Calibre Database Directory" msgstr "Calibre DB 폴더" -#: cps/templates/admin.html:111 cps/templates/config_edit.html:68 +#: cps/templates/admin.html:113 cps/templates/config_edit.html:68 msgid "Log Level" msgstr "Log Level" -#: cps/templates/admin.html:115 +#: cps/templates/admin.html:117 msgid "Port" msgstr "Port" -#: cps/templates/admin.html:120 +#: cps/templates/admin.html:122 msgid "External Port" msgstr "External Port" -#: cps/templates/admin.html:127 cps/templates/config_view_edit.html:28 +#: cps/templates/admin.html:129 cps/templates/config_view_edit.html:28 msgid "Books per Page" msgstr "페이지당 보여 줄 책 수" -#: cps/templates/admin.html:131 +#: cps/templates/admin.html:133 msgid "Uploads" msgstr "업로드" -#: cps/templates/admin.html:135 +#: cps/templates/admin.html:137 msgid "Anonymous Browsing" msgstr "익명 보기" -#: cps/templates/admin.html:139 +#: cps/templates/admin.html:141 msgid "Public Registration" msgstr "공개 등록" -#: cps/templates/admin.html:143 +#: cps/templates/admin.html:145 msgid "Magic Link Remote Login" msgstr "Magic Link Remote Login" -#: cps/templates/admin.html:147 +#: cps/templates/admin.html:149 msgid "Reverse Proxy Login" msgstr "Reverse Proxy Login" -#: cps/templates/admin.html:152 cps/templates/config_edit.html:173 +#: cps/templates/admin.html:154 cps/templates/config_edit.html:173 msgid "Reverse Proxy Header Name" msgstr "Reverse Proxy Header Name" -#: cps/templates/admin.html:157 +#: cps/templates/admin.html:159 msgid "Edit Calibre Database Configuration" msgstr "Calibre Database 환경 설정 편집" -#: cps/templates/admin.html:158 +#: cps/templates/admin.html:160 msgid "Edit Basic Configuration" msgstr "기본 환경 설정 편집" -#: cps/templates/admin.html:159 +#: cps/templates/admin.html:161 msgid "Edit UI Configuration" msgstr "UI 환경 설정 편집" -#: cps/templates/admin.html:164 +#: cps/templates/admin.html:166 msgid "Administration" msgstr "관리" -#: cps/templates/admin.html:165 +#: cps/templates/admin.html:167 msgid "Download Debug Package" msgstr "Debug Package 다운로드" -#: cps/templates/admin.html:166 +#: cps/templates/admin.html:168 msgid "View Logs" msgstr "로그 보기" -#: cps/templates/admin.html:169 +#: cps/templates/admin.html:171 msgid "Reconnect Calibre Database" msgstr "Calibre DB 다시 연결" -#: cps/templates/admin.html:170 +#: cps/templates/admin.html:172 msgid "Restart" msgstr "재시작" -#: cps/templates/admin.html:171 +#: cps/templates/admin.html:173 msgid "Shutdown" msgstr "종료" -#: cps/templates/admin.html:176 +#: cps/templates/admin.html:178 msgid "Update" msgstr "업데이트" -#: cps/templates/admin.html:180 +#: cps/templates/admin.html:182 msgid "Version" msgstr "버전" -#: cps/templates/admin.html:181 +#: cps/templates/admin.html:183 msgid "Details" msgstr "세부 정보" -#: cps/templates/admin.html:187 +#: cps/templates/admin.html:189 msgid "Current version" msgstr "현재 버전" -#: cps/templates/admin.html:194 +#: cps/templates/admin.html:196 msgid "Check for Update" msgstr "업데이트 확인" -#: cps/templates/admin.html:195 +#: cps/templates/admin.html:197 msgid "Perform Update" msgstr "업데이트 실행" -#: cps/templates/admin.html:208 +#: cps/templates/admin.html:210 msgid "Are you sure you want to restart?" msgstr "재시작을 하시겠습니까?" -#: cps/templates/admin.html:213 cps/templates/admin.html:227 -#: cps/templates/admin.html:247 cps/templates/config_db.html:70 +#: cps/templates/admin.html:215 cps/templates/admin.html:229 +#: cps/templates/admin.html:249 cps/templates/config_db.html:70 msgid "OK" msgstr "예" -#: cps/templates/admin.html:214 cps/templates/admin.html:228 -#: cps/templates/book_edit.html:213 cps/templates/book_table.html:124 +#: cps/templates/admin.html:216 cps/templates/admin.html:230 +#: cps/templates/book_edit.html:213 cps/templates/book_table.html:127 #: cps/templates/config_db.html:54 cps/templates/config_edit.html:359 -#: cps/templates/config_view_edit.html:173 cps/templates/modal_dialogs.html:64 +#: cps/templates/config_view_edit.html:175 cps/templates/modal_dialogs.html:64 #: cps/templates/modal_dialogs.html:99 cps/templates/modal_dialogs.html:117 #: cps/templates/modal_dialogs.html:135 cps/templates/shelf_edit.html:27 #: cps/templates/user_edit.html:144 msgid "Cancel" msgstr "취소" -#: cps/templates/admin.html:226 +#: cps/templates/admin.html:228 msgid "Are you sure you want to shutdown?" msgstr "종료를 하시겠습니까?" -#: cps/templates/admin.html:238 +#: cps/templates/admin.html:240 msgid "Updating, please do not reload this page" msgstr "Встановлення оновлень, будь-ласка, не оновлюйте сторінку" @@ -1586,44 +1610,43 @@ msgstr "via" msgid "In Library" msgstr "In Library" -#: cps/templates/author.html:26 cps/templates/index.html:72 -#: cps/templates/search.html:29 cps/templates/shelf.html:19 +#: cps/templates/author.html:26 cps/templates/index.html:73 +#: cps/templates/search.html:30 cps/templates/shelf.html:19 msgid "Sort according to book date, newest first" msgstr "책 목록 정렬, 최신순" -#: cps/templates/author.html:27 cps/templates/index.html:73 -#: cps/templates/search.html:30 cps/templates/shelf.html:20 +#: cps/templates/author.html:27 cps/templates/index.html:74 +#: cps/templates/search.html:31 cps/templates/shelf.html:20 msgid "Sort according to book date, oldest first" msgstr "책 목록 정렬, 오래된 순" -#: cps/templates/author.html:28 cps/templates/index.html:74 -#: cps/templates/search.html:31 cps/templates/shelf.html:21 +#: cps/templates/author.html:28 cps/templates/index.html:75 +#: cps/templates/search.html:32 cps/templates/shelf.html:21 msgid "Sort title in alphabetical order" msgstr "가나다 순 정렬" -#: cps/templates/author.html:29 cps/templates/index.html:75 -#: cps/templates/search.html:32 cps/templates/shelf.html:22 +#: cps/templates/author.html:29 cps/templates/index.html:76 +#: cps/templates/search.html:33 cps/templates/shelf.html:22 msgid "Sort title in reverse alphabetical order" msgstr "가나다 역순 정렬" -#: cps/templates/author.html:30 cps/templates/index.html:78 -#: cps/templates/search.html:35 cps/templates/shelf.html:25 +#: cps/templates/author.html:30 cps/templates/index.html:79 +#: cps/templates/search.html:36 cps/templates/shelf.html:25 msgid "Sort according to publishing date, newest first" msgstr "발행일 순으로 정렬, 최신순" -#: cps/templates/author.html:31 cps/templates/index.html:79 -#: cps/templates/search.html:36 cps/templates/shelf.html:26 +#: cps/templates/author.html:31 cps/templates/index.html:80 +#: cps/templates/search.html:37 cps/templates/shelf.html:26 msgid "Sort according to publishing date, oldest first" msgstr "발행일 순으로 정렬, 오래된 순" -#: cps/templates/author.html:57 cps/templates/author.html:117 -#: cps/templates/discover.html:30 cps/templates/index.html:29 -#: cps/templates/index.html:111 cps/templates/search.html:65 -#: cps/templates/shelf.html:54 +#: cps/templates/author.html:56 cps/templates/author.html:115 +#: cps/templates/index.html:29 cps/templates/index.html:112 +#: cps/templates/search.html:66 cps/templates/shelf.html:54 msgid "reduce" msgstr "reduce" -#: cps/templates/author.html:101 +#: cps/templates/author.html:99 msgid "More by" msgstr "More by" @@ -1748,7 +1771,7 @@ msgid "Fetch Metadata" msgstr "메타정보 가져오기" #: cps/templates/book_edit.html:212 cps/templates/config_db.html:53 -#: cps/templates/config_edit.html:358 cps/templates/config_view_edit.html:172 +#: cps/templates/config_edit.html:358 cps/templates/config_view_edit.html:174 #: cps/templates/email_edit.html:65 cps/templates/shelf_edit.html:25 #: cps/templates/shelf_order.html:41 cps/templates/user_edit.html:142 msgid "Save" @@ -1875,26 +1898,34 @@ msgstr "코멘트 입력" msgid "Comments" msgstr "코멘트" -#: cps/templates/book_table.html:77 cps/templates/book_table.html:79 -#: cps/templates/book_table.html:81 cps/templates/book_table.html:83 -#: cps/templates/book_table.html:87 cps/templates/book_table.html:89 -#: cps/templates/book_table.html:91 cps/templates/book_table.html:93 +#: cps/templates/book_table.html:75 +msgid "Archiv Status" +msgstr "" + +#: cps/templates/book_table.html:77 cps/templates/search_form.html:42 +msgid "Read Status" +msgstr "읽은 상태" + +#: cps/templates/book_table.html:80 cps/templates/book_table.html:82 +#: cps/templates/book_table.html:84 cps/templates/book_table.html:86 +#: cps/templates/book_table.html:90 cps/templates/book_table.html:92 +#: cps/templates/book_table.html:96 msgid "Enter " msgstr "입력 " -#: cps/templates/book_table.html:110 cps/templates/modal_dialogs.html:46 +#: cps/templates/book_table.html:113 cps/templates/modal_dialogs.html:46 msgid "Are you really sure?" msgstr "정말 확신합니까?" -#: cps/templates/book_table.html:114 +#: cps/templates/book_table.html:117 msgid "Books with Title will be merged from:" msgstr "제목이 있는 책은 다음에서 병합됨:" -#: cps/templates/book_table.html:118 +#: cps/templates/book_table.html:121 msgid "Into Book with Title:" msgstr "제목이 있는 책으로:" -#: cps/templates/book_table.html:123 +#: cps/templates/book_table.html:126 msgid "Merge" msgstr "병합" @@ -2070,11 +2101,6 @@ msgstr "LDAP 서버 포트" msgid "LDAP Encryption" msgstr "LDAP 암호화" -#: cps/templates/config_edit.html:204 cps/templates/config_view_edit.html:62 -#: cps/templates/email_edit.html:41 -msgid "None" -msgstr "None" - #: cps/templates/config_edit.html:205 msgid "TLS" msgstr "TLS" @@ -2291,11 +2317,11 @@ msgstr "신규 사용자를 위한 기본 기능" msgid "Show Random Books in Detail View" msgstr "상세 보기에서 임의의 책 표시" -#: cps/templates/config_view_edit.html:165 cps/templates/user_edit.html:87 +#: cps/templates/config_view_edit.html:166 cps/templates/user_edit.html:87 msgid "Add Allowed/Denied Tags" msgstr "허용/거부 태그 추가" -#: cps/templates/config_view_edit.html:166 +#: cps/templates/config_view_edit.html:167 msgid "Add Allowed/Denied custom column values" msgstr "허용/거부 사용자 정의 열 값 추가" @@ -2344,13 +2370,13 @@ msgstr "보관됨" msgid "Description:" msgstr "설명:" -#: cps/templates/detail.html:256 cps/templates/search.html:14 +#: cps/templates/detail.html:256 cps/templates/search.html:15 msgid "Add to shelf" msgstr "서재에 추가" #: cps/templates/detail.html:267 cps/templates/detail.html:284 #: cps/templates/feed.xml:79 cps/templates/layout.html:137 -#: cps/templates/search.html:20 +#: cps/templates/search.html:21 msgid "(Public)" msgstr "(공개)" @@ -2428,10 +2454,15 @@ msgstr "거부 도메인(블랙리스트)" msgid "Next" msgstr "다음" -#: cps/templates/generate_kobo_auth_url.html:5 +#: cps/templates/generate_kobo_auth_url.html:6 msgid "Open the .kobo/Kobo eReader.conf file in a text editor and add (or edit):" msgstr "텍스트 편집기에서 .kobo/Kobo eReader.conf 파일을 열고 다음을 추가(또는 편집):" +#: cps/templates/generate_kobo_auth_url.html:11 +#, fuzzy +msgid "Kobo Token:" +msgstr "코보 연동 토큰" + #: cps/templates/http_error.html:31 msgid "Calibre-Web Instance is unconfigured, please contact your administrator" msgstr "Calibre-Web Instance가 구성되지 않았습니다. 관리자에게 문의" @@ -2448,29 +2479,29 @@ msgstr "홈으로" msgid "Logout User" msgstr "로그아웃" -#: cps/templates/index.html:69 +#: cps/templates/index.html:70 msgid "Sort ascending according to download count" msgstr "다운로드 횟수에 따라 오름차순 정렬" -#: cps/templates/index.html:70 +#: cps/templates/index.html:71 msgid "Sort descending according to download count" msgstr "다운로드 횟수에 따라 내림차순 정렬" -#: cps/templates/index.html:76 cps/templates/search.html:33 +#: cps/templates/index.html:77 cps/templates/search.html:34 #: cps/templates/shelf.html:23 msgid "Sort authors in alphabetical order" msgstr "저자를 가나다순(알파벳순)으로 정렬" -#: cps/templates/index.html:77 cps/templates/search.html:34 +#: cps/templates/index.html:78 cps/templates/search.html:35 #: cps/templates/shelf.html:24 msgid "Sort authors in reverse alphabetical order" msgstr "저자를 가나다(알파벳) 역순으로 정렬" -#: cps/templates/index.html:81 +#: cps/templates/index.html:82 msgid "Sort ascending according to series index" msgstr "시리즈 인덱스에 따라 오름차순 정렬" -#: cps/templates/index.html:82 +#: cps/templates/index.html:83 msgid "Sort descending according to series index" msgstr "시리즈 인덱스에 따라 내림차순 정렬" @@ -2900,10 +2931,6 @@ msgstr "출간일(부터)" msgid "Published Date To" msgstr "출간일(까지)" -#: cps/templates/search_form.html:42 -msgid "Read Status" -msgstr "읽은 상태" - #: cps/templates/search_form.html:59 msgid "Exclude Tags" msgstr "태그 제외" diff --git a/cps/translations/nl/LC_MESSAGES/messages.mo b/cps/translations/nl/LC_MESSAGES/messages.mo index 8c8db9e7..589137d9 100644 Binary files a/cps/translations/nl/LC_MESSAGES/messages.mo and b/cps/translations/nl/LC_MESSAGES/messages.mo differ diff --git a/cps/translations/nl/LC_MESSAGES/messages.po b/cps/translations/nl/LC_MESSAGES/messages.po index da786104..a8bd8632 100644 --- a/cps/translations/nl/LC_MESSAGES/messages.po +++ b/cps/translations/nl/LC_MESSAGES/messages.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: Calibre-Web (GPLV3)\n" "Report-Msgid-Bugs-To: https://github.com/janeczku/Calibre-Web\n" -"POT-Creation-Date: 2022-01-15 09:19+0100\n" +"POT-Creation-Date: 2022-04-18 20:01+0200\n" "PO-Revision-Date: 2020-12-12 08:20+0100\n" "Last-Translator: Marcel Maas \n" "Language: nl\n" @@ -17,588 +17,591 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.9.0\n" +"Generated-By: Babel 2.9.1\n" -#: cps/about.py:34 cps/about.py:49 cps/about.py:65 cps/converter.py:31 -msgid "not installed" -msgstr "niet geïnstalleerd" - -#: cps/about.py:47 cps/about.py:63 -msgid "installed" -msgstr "geïnstalleerd" - -#: cps/about.py:145 +#: cps/about.py:86 msgid "Statistics" msgstr "Statistieken" -#: cps/admin.py:144 +#: cps/admin.py:141 msgid "Server restarted, please reload page" msgstr "De server is herstart, vernieuw de pagina" -#: cps/admin.py:146 +#: cps/admin.py:143 msgid "Performing shutdown of server, please close window" msgstr "Bezig met het afsluiten van de server, sluit het venster" -#: cps/admin.py:154 +#: cps/admin.py:151 msgid "Reconnect successful" msgstr "Opnieuw verbinden gelukt" -#: cps/admin.py:157 +#: cps/admin.py:154 msgid "Unknown command" msgstr "Onbekende opdracht" -#: cps/admin.py:167 cps/editbooks.py:707 cps/editbooks.py:721 -#: cps/editbooks.py:866 cps/editbooks.py:868 cps/editbooks.py:895 -#: cps/editbooks.py:911 cps/updater.py:584 cps/uploader.py:93 -#: cps/uploader.py:103 +#: cps/admin.py:176 cps/editbooks.py:713 cps/editbooks.py:892 +#: cps/editbooks.py:894 cps/editbooks.py:930 cps/editbooks.py:947 +#: cps/updater.py:608 cps/uploader.py:93 cps/uploader.py:103 msgid "Unknown" msgstr "Onbekend" -#: cps/admin.py:188 +#: cps/admin.py:197 msgid "Admin page" msgstr "Systeembeheer" -#: cps/admin.py:207 +#: cps/admin.py:217 msgid "Basic Configuration" msgstr "Basisconfiguratie" -#: cps/admin.py:244 +#: cps/admin.py:255 msgid "UI Configuration" msgstr "Uiterlijk aanpassen" -#: cps/admin.py:277 cps/templates/admin.html:50 +#: cps/admin.py:289 cps/templates/admin.html:51 #, fuzzy msgid "Edit Users" msgstr "Systeembeheerder" -#: cps/admin.py:318 cps/opds.py:109 cps/opds.py:198 cps/opds.py:275 -#: cps/opds.py:327 cps/templates/grid.html:13 cps/templates/languages.html:9 +#: cps/admin.py:333 cps/opds.py:529 cps/templates/grid.html:13 #: cps/templates/list.html:13 msgid "All" msgstr "Alles" -#: cps/admin.py:343 cps/admin.py:1615 +#: cps/admin.py:360 cps/admin.py:1648 msgid "User not found" msgstr "Gebruiker niet gevonden" -#: cps/admin.py:357 +#: cps/admin.py:374 msgid "{} users deleted successfully" msgstr "{} gebruikers succesvol verwijderd" -#: cps/admin.py:379 cps/templates/config_view_edit.html:133 +#: cps/admin.py:397 cps/templates/config_view_edit.html:133 #: cps/templates/user_edit.html:45 cps/templates/user_table.html:81 msgid "Show All" msgstr "Alle talen" -#: cps/admin.py:400 cps/admin.py:406 +#: cps/admin.py:418 cps/admin.py:424 msgid "Malformed request" msgstr "Misvormd verzoek" -#: cps/admin.py:418 cps/admin.py:1493 +#: cps/admin.py:436 cps/admin.py:1526 msgid "Guest Name can't be changed" msgstr "Gast naam kan niet worden veranderd" -#: cps/admin.py:430 +#: cps/admin.py:448 msgid "Guest can't have this role" msgstr "Gast kan deze rol niet hebben" -#: cps/admin.py:442 cps/admin.py:1451 +#: cps/admin.py:460 cps/admin.py:1484 msgid "No admin user remaining, can't remove admin role" msgstr "Kan systeembeheerder rol niet verwijderen van de laatste systeembeheerder" -#: cps/admin.py:446 cps/admin.py:460 +#: cps/admin.py:464 cps/admin.py:478 msgid "Value has to be true or false" msgstr "Waarde moet Waar of Onwaar zijn" -#: cps/admin.py:448 +#: cps/admin.py:466 msgid "Invalid role" msgstr "Ongeldige rol" -#: cps/admin.py:452 +#: cps/admin.py:470 msgid "Guest can't have this view" msgstr "Gast kan dit niet bekijken" -#: cps/admin.py:462 +#: cps/admin.py:480 msgid "Invalid view" msgstr "Ongeldige waarde" -#: cps/admin.py:465 +#: cps/admin.py:483 msgid "Guest's Locale is determined automatically and can't be set" msgstr "Gasts locale is automatisch bepaald en kan niet handmatig worden ingesteld" -#: cps/admin.py:469 +#: cps/admin.py:487 msgid "No Valid Locale Given" msgstr "Geen geldige locale is opgegeven" -#: cps/admin.py:480 +#: cps/admin.py:498 msgid "No Valid Book Language Given" msgstr "Geen geldige boek taal is opgegeven" -#: cps/admin.py:482 +#: cps/admin.py:500 cps/editbooks.py:1267 msgid "Parameter not found" msgstr "Parameter is niet gevonden" -#: cps/admin.py:533 +#: cps/admin.py:553 msgid "Invalid Read Column" msgstr "Ongeldige gelezen kolom" -#: cps/admin.py:539 +#: cps/admin.py:559 msgid "Invalid Restricted Column" msgstr "Ongeldige beperkte kolom" -#: cps/admin.py:560 cps/admin.py:1323 +#: cps/admin.py:579 cps/admin.py:1355 msgid "Calibre-Web configuration updated" msgstr "Calibre-Web-configuratie bijgewerkt" -#: cps/admin.py:572 +#: cps/admin.py:591 msgid "Do you really want to delete the Kobo Token?" msgstr "Wil je je Kobo Token echt verwijderen?" -#: cps/admin.py:574 +#: cps/admin.py:593 msgid "Do you really want to delete this domain?" msgstr "Wil je dit domein echt verwijderen?" -#: cps/admin.py:576 +#: cps/admin.py:595 msgid "Do you really want to delete this user?" msgstr "Wil je deze gebruiker echt verwijderen?" -#: cps/admin.py:578 +#: cps/admin.py:597 msgid "Are you sure you want to delete this shelf?" msgstr "Weet je zeker dat je deze boekenplank wilt verwijderen?" -#: cps/admin.py:580 +#: cps/admin.py:599 #, fuzzy msgid "Are you sure you want to change locales of selected user(s)?" msgstr "Weet je zeker dat je de locales van de geselecteerde gebruiker(s) wil veranderen?" -#: cps/admin.py:582 +#: cps/admin.py:601 msgid "Are you sure you want to change visible book languages for selected user(s)?" msgstr "Weet je zeker dat je de zichtbare talen voor de geselecteerde gebruiker(s) wil veranderen?" -#: cps/admin.py:584 +#: cps/admin.py:603 msgid "Are you sure you want to change the selected role for the selected user(s)?" msgstr "Weet je zeker dat je de geselecteerde rol van de geselecteerde gebruiker(s) wil veranderen?" -#: cps/admin.py:586 +#: cps/admin.py:605 #, fuzzy msgid "Are you sure you want to change the selected restrictions for the selected user(s)?" msgstr "Weet je zeker dat je de geselecteerde beperkingen voor de geselecteerde gebruikers(s) wil verwijderen?" -#: cps/admin.py:588 +#: cps/admin.py:607 msgid "Are you sure you want to change the selected visibility restrictions for the selected user(s)?" msgstr "Weet je zeker dat je de geselecteerde zichtbaarheidsbeperkingen voor de geselecteerde gebruiker(s) wil veranderen?" -#: cps/admin.py:590 +#: cps/admin.py:610 #, fuzzy msgid "Are you sure you want to change shelf sync behavior for the selected user(s)?" msgstr "Weet je zeker dat je de synchronisatiegedrag van boekenplanken voor de geselecteerde gebruiker(s) wil veranderen?" -#: cps/admin.py:592 +#: cps/admin.py:612 #, fuzzy msgid "Are you sure you want to change Calibre library location?" msgstr "Weet je zeker dat je de locatie van de Calibre-bibliotheek wil veranderen?" -#: cps/admin.py:594 +#: cps/admin.py:614 msgid "Are you sure you want delete Calibre-Web's sync database to force a full sync with your Kobo Reader?" msgstr "" -#: cps/admin.py:743 +#: cps/admin.py:764 msgid "Tag not found" msgstr "Tag niet gevonden" -#: cps/admin.py:755 +#: cps/admin.py:776 msgid "Invalid Action" msgstr "Ongeldige actie" -#: cps/admin.py:871 cps/admin.py:877 cps/admin.py:887 cps/admin.py:897 +#: cps/admin.py:893 cps/admin.py:899 cps/admin.py:909 cps/admin.py:919 #: cps/templates/modal_dialogs.html:29 cps/templates/user_table.html:41 #: cps/templates/user_table.html:58 msgid "Deny" msgstr "Weigeren" -#: cps/admin.py:873 cps/admin.py:879 cps/admin.py:889 cps/admin.py:899 +#: cps/admin.py:895 cps/admin.py:901 cps/admin.py:911 cps/admin.py:921 #: cps/templates/modal_dialogs.html:28 cps/templates/user_table.html:44 #: cps/templates/user_table.html:61 msgid "Allow" msgstr "Toestaan" -#: cps/admin.py:913 +#: cps/admin.py:936 msgid "{} sync entries deleted" msgstr "" -#: cps/admin.py:1036 +#: cps/admin.py:1059 msgid "client_secrets.json Is Not Configured For Web Application" msgstr "client_secrets.json is niet geconfigureerd voor webapplicatie" -#: cps/admin.py:1081 +#: cps/admin.py:1104 msgid "Logfile Location is not Valid, Please Enter Correct Path" msgstr "De locatie van het logbestand is onjuist, voer een geldige locatie in" -#: cps/admin.py:1087 +#: cps/admin.py:1110 msgid "Access Logfile Location is not Valid, Please Enter Correct Path" msgstr "De locatie vam het toegangslog is onjuist, voer een geldige locatie in" -#: cps/admin.py:1117 +#: cps/admin.py:1140 msgid "Please Enter a LDAP Provider, Port, DN and User Object Identifier" msgstr "Voer alsjeblieft een LDAP Provider, Port, DN en User Object Identifier in" -#: cps/admin.py:1123 +#: cps/admin.py:1146 msgid "Please Enter a LDAP Service Account and Password" msgstr "Voer een geldig LDAP Service Account en wachtwoord in" -#: cps/admin.py:1126 +#: cps/admin.py:1149 msgid "Please Enter a LDAP Service Account" msgstr "Voer een LDAP Service Account in" -#: cps/admin.py:1131 +#: cps/admin.py:1154 #, python-format msgid "LDAP Group Object Filter Needs to Have One \"%s\" Format Identifier" msgstr "LDAP Groep Object Filter Moet Een \"%s\" Formaat Identificiatie hebben" -#: cps/admin.py:1133 +#: cps/admin.py:1156 msgid "LDAP Group Object Filter Has Unmatched Parenthesis" msgstr "LDAP Groep Object Filter heeft een niet-gebalanceerd haakje" -#: cps/admin.py:1137 +#: cps/admin.py:1160 #, python-format msgid "LDAP User Object Filter needs to Have One \"%s\" Format Identifier" msgstr "LDAP Gebruiker Object Filter moet \"%s\" Formaat Identificatie hebben" -#: cps/admin.py:1139 +#: cps/admin.py:1162 msgid "LDAP User Object Filter Has Unmatched Parenthesis" msgstr "LDAP Gebruiker Filter heeft een niet-gebalanceerd haakje" -#: cps/admin.py:1146 +#: cps/admin.py:1169 #, python-format msgid "LDAP Member User Filter needs to Have One \"%s\" Format Identifier" msgstr "LDAP Lid Gebruiker Filter moet een \"%s\" Formaat Identificatie hebben" -#: cps/admin.py:1148 +#: cps/admin.py:1171 msgid "LDAP Member User Filter Has Unmatched Parenthesis" msgstr "LDAP Lid Gebruiker Filter heeft een niet-gebalanceerd haakje" -#: cps/admin.py:1155 +#: cps/admin.py:1178 msgid "LDAP CACertificate, Certificate or Key Location is not Valid, Please Enter Correct Path" msgstr "LDAP CACertficaat, Certificaat of Sleutel Locatie is ongeldig. Voer alsjeblieft een geldig pad in." -#: cps/admin.py:1197 cps/admin.py:1308 cps/admin.py:1405 cps/admin.py:1521 -#: cps/admin.py:1590 cps/shelf.py:100 cps/shelf.py:160 cps/shelf.py:203 -#: cps/shelf.py:279 cps/shelf.py:341 cps/shelf.py:376 cps/shelf.py:451 -msgid "Settings DB is not Writeable" -msgstr "DB-instellingen niet opgeslagen" - -#: cps/admin.py:1208 -msgid "DB Location is not Valid, Please Enter Correct Path" -msgstr "Database niet gevonden, voer de juiste locatie in" - -#: cps/admin.py:1223 -msgid "DB is not Writeable" -msgstr "Kan niet schrijven naar database" - -#: cps/admin.py:1235 -msgid "Keyfile Location is not Valid, Please Enter Correct Path" -msgstr "SSL-sleutellocatie is niet geldig, voer een geldig pad in" - -#: cps/admin.py:1239 -msgid "Certfile Location is not Valid, Please Enter Correct Path" -msgstr "SSL-certificaatlocatie is niet geldig, voer een geldig pad in" - -#: cps/admin.py:1346 -#, fuzzy -msgid "Database Settings updated" -msgstr "E-mailserver-instellingen bijgewerkt" - -#: cps/admin.py:1354 -#, fuzzy -msgid "Database Configuration" -msgstr "Databaseconfiguratie" - -#: cps/admin.py:1370 cps/web.py:1479 -msgid "Please fill out all fields!" -msgstr "Vul alle velden in!" - -#: cps/admin.py:1378 -msgid "E-mail is not from valid domain" -msgstr "Het e-mailadres bevat geen geldige domeinnaam" - -#: cps/admin.py:1384 cps/admin.py:1543 -msgid "Add new user" -msgstr "Gebruiker toevoegen" - -#: cps/admin.py:1395 -#, python-format -msgid "User '%(user)s' created" -msgstr "Gebruiker '%(user)s' aangemaakt" - -#: cps/admin.py:1401 -#, fuzzy -msgid "Found an existing account for this e-mail address or name." -msgstr "Bestaand account met dit e-mailadres of deze gebruikersnaam aangetroffen." - -#: cps/admin.py:1430 -#, python-format -msgid "User '%(nick)s' deleted" -msgstr "Gebruiker '%(nick)s' verwijderd" - -#: cps/admin.py:1432 cps/admin.py:1433 -msgid "Can't delete Guest User" -msgstr "Kan Gast gebruiker niet verwijderen" - -#: cps/admin.py:1436 -msgid "No admin user remaining, can't delete user" -msgstr "Kan laatste systeembeheerder niet verwijderen" - -#: cps/admin.py:1509 cps/admin.py:1634 -#, python-format -msgid "Edit User %(nick)s" -msgstr "Gebruiker '%(nick)s' bewerken" - -#: cps/admin.py:1513 -#, python-format -msgid "User '%(nick)s' updated" -msgstr "Gebruiker '%(nick)s' bijgewerkt" - -#: cps/admin.py:1517 cps/admin.py:1649 cps/web.py:1504 cps/web.py:1564 -msgid "An unknown error occurred. Please try again later." -msgstr "Onbekende fout opgetreden. Probeer het later nog eens." - -#: cps/admin.py:1552 cps/templates/admin.html:98 -msgid "Edit E-mail Server Settings" -msgstr "SMTP-instellingen bewerken" - -#: cps/admin.py:1571 -msgid "Gmail Account Verification Successful" -msgstr "Gmail Account succesvol geverifieerd" - -#: cps/admin.py:1597 -#, python-format -msgid "Test e-mail queued for sending to %(email)s, please check Tasks for result" -msgstr "Test E-Mail wordt verzonden naar %(email)s, controleer de taken voor het resultaat" - -#: cps/admin.py:1600 -#, python-format -msgid "There was an error sending the Test e-mail: %(res)s" -msgstr "Fout opgetreden bij het versturen van de test-e-mail: %(res)s" - -#: cps/admin.py:1602 -msgid "Please configure your e-mail address first..." -msgstr "Gelieve eerst je e-mail adres configureren..." - -#: cps/admin.py:1604 -msgid "E-mail server settings updated" -msgstr "E-mailserver-instellingen bijgewerkt" - -#: cps/admin.py:1646 -#, python-format -msgid "Password for user %(user)s reset" -msgstr "Wachtwoord voor gebruiker %(user)s is hersteld" - -#: cps/admin.py:1652 cps/web.py:1444 -msgid "Please configure the SMTP mail settings first..." -msgstr "Stel eerst SMTP-mail in..." - -#: cps/admin.py:1663 -msgid "Logfile viewer" -msgstr "Logbestand lezer" - -#: cps/admin.py:1729 -msgid "Requesting update package" -msgstr "Update opvragen" - -#: cps/admin.py:1730 -msgid "Downloading update package" -msgstr "Update downloaden" - -#: cps/admin.py:1731 -msgid "Unzipping update package" -msgstr "Update uitpakken" - -#: cps/admin.py:1732 -msgid "Replacing files" -msgstr "Update toepassen" - -#: cps/admin.py:1733 -msgid "Database connections are closed" -msgstr "Databaseverbindingen zijn gesloten" - -#: cps/admin.py:1734 -msgid "Stopping server" -msgstr "Bezig met stoppen van Calibre-Web" - -#: cps/admin.py:1735 -msgid "Update finished, please press okay and reload page" -msgstr "Update voltooid, klik op 'Oké' en vernieuw de pagina" - -#: cps/admin.py:1736 cps/admin.py:1737 cps/admin.py:1738 cps/admin.py:1739 -#: cps/admin.py:1740 cps/admin.py:1741 -msgid "Update failed:" -msgstr "Update mislukt:" - -#: cps/admin.py:1736 cps/updater.py:385 cps/updater.py:595 cps/updater.py:597 -msgid "HTTP Error" -msgstr "HTTP-fout" - -#: cps/admin.py:1737 cps/updater.py:387 cps/updater.py:599 -msgid "Connection error" -msgstr "Verbindingsfout" - -#: cps/admin.py:1738 cps/updater.py:389 cps/updater.py:601 -msgid "Timeout while establishing connection" -msgstr "Time-out tijdens maken van verbinding" - -#: cps/admin.py:1739 cps/updater.py:391 cps/updater.py:603 -msgid "General error" -msgstr "Algemene fout" - -#: cps/admin.py:1740 -#, fuzzy -msgid "Update file could not be saved in temp dir" -msgstr "Geüpload bestand kon niet opgeslagen worden in de tijdelijke map" - -#: cps/admin.py:1741 -msgid "Files could not be replaced during update" -msgstr "" - -#: cps/admin.py:1765 -#, fuzzy -msgid "Failed to extract at least One LDAP User" -msgstr "Mislukt om minstens een LDAP gebruiker aan te maken" - -#: cps/admin.py:1810 -msgid "Failed to Create at Least One LDAP User" -msgstr "Het is niet gelukt tenminste een LDAP gebruiker aan te maken" - -#: cps/admin.py:1823 -#, python-format -msgid "Error: %(ldaperror)s" -msgstr "Fout: %(ldaperror)s" - -#: cps/admin.py:1827 -msgid "Error: No user returned in response of LDAP server" -msgstr "Fout: No user returned in response of LDAP server" - -#: cps/admin.py:1860 -msgid "At Least One LDAP User Not Found in Database" -msgstr "Minstens een LDAP Gebruiker is niet gevonden in de Database" - -#: cps/admin.py:1862 -msgid "{} User Successfully Imported" -msgstr "{} Gebruiker succesvol geïmporteerd" - -#: cps/converter.py:30 -msgid "not configured" -msgstr "niet geconfigureerd" - -#: cps/converter.py:32 -msgid "Execution permissions missing" -msgstr "Kan programma niet uitvoeren" - -#: cps/db.py:651 cps/web.py:667 cps/web.py:1155 -#, python-format -msgid "Custom Column No.%(column)d is not existing in calibre database" -msgstr "Aangepaste kolom Nr.%(column)d bestaat niet in de Calibre Database" - -#: cps/editbooks.py:300 cps/editbooks.py:302 -msgid "Book Format Successfully Deleted" -msgstr "Het boekformaat is verwijderd" - -#: cps/editbooks.py:309 cps/editbooks.py:311 -msgid "Book Successfully Deleted" -msgstr "Het boek is verwijderd" - -#: cps/editbooks.py:361 -msgid "You are missing permissions to delete books" -msgstr "" - -#: cps/editbooks.py:376 cps/editbooks.py:763 cps/web.py:523 cps/web.py:1703 -#: cps/web.py:1744 cps/web.py:1811 -msgid "Oops! Selected book title is unavailable. File does not exist or is not accessible" -msgstr "Oeps! Geselecteerd boek is niet beschikbaar. Bestand bestaat niet of is niet toegankelijk" - -#: cps/editbooks.py:410 -msgid "edit metadata" -msgstr "metagegevens bewerken" - -#: cps/editbooks.py:458 -#, python-format -msgid "%(seriesindex)s is not a valid number, skipping" -msgstr "%(seriesindex)s is geen geldig nummer, sla het over" - -#: cps/editbooks.py:494 cps/editbooks.py:958 -#, fuzzy, python-format -msgid "'%(langname)s' is not a valid language" -msgstr "%(langname)s is geen geldige taal" - -#: cps/editbooks.py:634 cps/editbooks.py:985 -#, python-format -msgid "File extension '%(ext)s' is not allowed to be uploaded to this server" -msgstr "De bestandsextensie '%(ext)s' is niet toegestaan op deze server" - -#: cps/editbooks.py:638 cps/editbooks.py:989 -msgid "File to be uploaded must have an extension" -msgstr "Het te uploaden bestand moet voorzien zijn van een extensie" - -#: cps/editbooks.py:650 -#, python-format -msgid "Failed to create path %(path)s (Permission denied)." -msgstr "Kan de locatie '%(path)s' niet aanmaken (niet gemachtigd)." - -#: cps/editbooks.py:655 -#, python-format -msgid "Failed to store file %(file)s." -msgstr "Kan %(file)s niet opslaan." - -#: cps/editbooks.py:673 cps/editbooks.py:1076 cps/web.py:1664 +#: cps/admin.py:1223 cps/admin.py:1339 cps/admin.py:1437 cps/admin.py:1554 +#: cps/admin.py:1623 cps/editbooks.py:678 cps/editbooks.py:882 +#: cps/editbooks.py:1130 cps/shelf.py:100 cps/shelf.py:160 cps/shelf.py:203 +#: cps/shelf.py:278 cps/shelf.py:343 cps/shelf.py:380 cps/shelf.py:456 +#: cps/web.py:1742 #, python-format msgid "Database error: %(error)s." msgstr "Database fout: %(error)s." -#: cps/editbooks.py:678 +#: cps/admin.py:1235 +msgid "DB Location is not Valid, Please Enter Correct Path" +msgstr "Database niet gevonden, voer de juiste locatie in" + +#: cps/admin.py:1253 +msgid "DB is not Writeable" +msgstr "Kan niet schrijven naar database" + +#: cps/admin.py:1266 +msgid "Keyfile Location is not Valid, Please Enter Correct Path" +msgstr "SSL-sleutellocatie is niet geldig, voer een geldig pad in" + +#: cps/admin.py:1270 +msgid "Certfile Location is not Valid, Please Enter Correct Path" +msgstr "SSL-certificaatlocatie is niet geldig, voer een geldig pad in" + +#: cps/admin.py:1378 +#, fuzzy +msgid "Database Settings updated" +msgstr "E-mailserver-instellingen bijgewerkt" + +#: cps/admin.py:1386 +#, fuzzy +msgid "Database Configuration" +msgstr "Databaseconfiguratie" + +#: cps/admin.py:1402 cps/web.py:1557 +msgid "Please fill out all fields!" +msgstr "Vul alle velden in!" + +#: cps/admin.py:1410 +msgid "E-mail is not from valid domain" +msgstr "Het e-mailadres bevat geen geldige domeinnaam" + +#: cps/admin.py:1416 cps/admin.py:1576 +msgid "Add new user" +msgstr "Gebruiker toevoegen" + +#: cps/admin.py:1427 +#, python-format +msgid "User '%(user)s' created" +msgstr "Gebruiker '%(user)s' aangemaakt" + +#: cps/admin.py:1433 +#, fuzzy +msgid "Found an existing account for this e-mail address or name." +msgstr "Bestaand account met dit e-mailadres of deze gebruikersnaam aangetroffen." + +#: cps/admin.py:1463 +#, python-format +msgid "User '%(nick)s' deleted" +msgstr "Gebruiker '%(nick)s' verwijderd" + +#: cps/admin.py:1465 cps/admin.py:1466 +msgid "Can't delete Guest User" +msgstr "Kan Gast gebruiker niet verwijderen" + +#: cps/admin.py:1469 +msgid "No admin user remaining, can't delete user" +msgstr "Kan laatste systeembeheerder niet verwijderen" + +#: cps/admin.py:1542 cps/admin.py:1667 +#, python-format +msgid "Edit User %(nick)s" +msgstr "Gebruiker '%(nick)s' bewerken" + +#: cps/admin.py:1546 +#, python-format +msgid "User '%(nick)s' updated" +msgstr "Gebruiker '%(nick)s' bijgewerkt" + +#: cps/admin.py:1550 cps/admin.py:1682 cps/web.py:1582 cps/web.py:1642 +msgid "An unknown error occurred. Please try again later." +msgstr "Onbekende fout opgetreden. Probeer het later nog eens." + +#: cps/admin.py:1585 cps/templates/admin.html:100 +msgid "Edit E-mail Server Settings" +msgstr "SMTP-instellingen bewerken" + +#: cps/admin.py:1604 +msgid "Gmail Account Verification Successful" +msgstr "Gmail Account succesvol geverifieerd" + +#: cps/admin.py:1630 +#, python-format +msgid "Test e-mail queued for sending to %(email)s, please check Tasks for result" +msgstr "Test E-Mail wordt verzonden naar %(email)s, controleer de taken voor het resultaat" + +#: cps/admin.py:1633 +#, python-format +msgid "There was an error sending the Test e-mail: %(res)s" +msgstr "Fout opgetreden bij het versturen van de test-e-mail: %(res)s" + +#: cps/admin.py:1635 +msgid "Please configure your e-mail address first..." +msgstr "Gelieve eerst je e-mail adres configureren..." + +#: cps/admin.py:1637 +msgid "E-mail server settings updated" +msgstr "E-mailserver-instellingen bijgewerkt" + +#: cps/admin.py:1679 +#, python-format +msgid "Password for user %(user)s reset" +msgstr "Wachtwoord voor gebruiker %(user)s is hersteld" + +#: cps/admin.py:1685 cps/web.py:1522 +msgid "Please configure the SMTP mail settings first..." +msgstr "Stel eerst SMTP-mail in..." + +#: cps/admin.py:1696 +msgid "Logfile viewer" +msgstr "Logbestand lezer" + +#: cps/admin.py:1762 +msgid "Requesting update package" +msgstr "Update opvragen" + +#: cps/admin.py:1763 +msgid "Downloading update package" +msgstr "Update downloaden" + +#: cps/admin.py:1764 +msgid "Unzipping update package" +msgstr "Update uitpakken" + +#: cps/admin.py:1765 +msgid "Replacing files" +msgstr "Update toepassen" + +#: cps/admin.py:1766 +msgid "Database connections are closed" +msgstr "Databaseverbindingen zijn gesloten" + +#: cps/admin.py:1767 +msgid "Stopping server" +msgstr "Bezig met stoppen van Calibre-Web" + +#: cps/admin.py:1768 +msgid "Update finished, please press okay and reload page" +msgstr "Update voltooid, klik op 'Oké' en vernieuw de pagina" + +#: cps/admin.py:1769 cps/admin.py:1770 cps/admin.py:1771 cps/admin.py:1772 +#: cps/admin.py:1773 cps/admin.py:1774 +msgid "Update failed:" +msgstr "Update mislukt:" + +#: cps/admin.py:1769 cps/updater.py:384 cps/updater.py:619 cps/updater.py:621 +msgid "HTTP Error" +msgstr "HTTP-fout" + +#: cps/admin.py:1770 cps/updater.py:386 cps/updater.py:623 +msgid "Connection error" +msgstr "Verbindingsfout" + +#: cps/admin.py:1771 cps/updater.py:388 cps/updater.py:625 +msgid "Timeout while establishing connection" +msgstr "Time-out tijdens maken van verbinding" + +#: cps/admin.py:1772 cps/updater.py:390 cps/updater.py:627 +msgid "General error" +msgstr "Algemene fout" + +#: cps/admin.py:1773 +#, fuzzy +msgid "Update file could not be saved in temp dir" +msgstr "Geüpload bestand kon niet opgeslagen worden in de tijdelijke map" + +#: cps/admin.py:1774 +msgid "Files could not be replaced during update" +msgstr "" + +#: cps/admin.py:1798 +#, fuzzy +msgid "Failed to extract at least One LDAP User" +msgstr "Mislukt om minstens een LDAP gebruiker aan te maken" + +#: cps/admin.py:1843 +msgid "Failed to Create at Least One LDAP User" +msgstr "Het is niet gelukt tenminste een LDAP gebruiker aan te maken" + +#: cps/admin.py:1856 +#, python-format +msgid "Error: %(ldaperror)s" +msgstr "Fout: %(ldaperror)s" + +#: cps/admin.py:1860 +msgid "Error: No user returned in response of LDAP server" +msgstr "Fout: No user returned in response of LDAP server" + +#: cps/admin.py:1893 +msgid "At Least One LDAP User Not Found in Database" +msgstr "Minstens een LDAP Gebruiker is niet gevonden in de Database" + +#: cps/admin.py:1895 +msgid "{} User Successfully Imported" +msgstr "{} Gebruiker succesvol geïmporteerd" + +#: cps/converter.py:30 +msgid "not installed" +msgstr "niet geïnstalleerd" + +#: cps/converter.py:31 +msgid "Execution permissions missing" +msgstr "Kan programma niet uitvoeren" + +#: cps/db.py:674 cps/web.py:710 cps/web.py:1222 +#, python-format +msgid "Custom Column No.%(column)d is not existing in calibre database" +msgstr "Aangepaste kolom Nr.%(column)d bestaat niet in de Calibre Database" + +#: cps/db.py:917 cps/templates/config_edit.html:204 +#: cps/templates/config_view_edit.html:62 cps/templates/email_edit.html:41 +#: cps/web.py:551 cps/web.py:585 cps/web.py:646 cps/web.py:671 cps/web.py:1003 +#: cps/web.py:1032 cps/web.py:1066 cps/web.py:1093 cps/web.py:1132 +msgid "None" +msgstr "Geen" + +#: cps/editbooks.py:295 cps/editbooks.py:297 +msgid "Book Format Successfully Deleted" +msgstr "Het boekformaat is verwijderd" + +#: cps/editbooks.py:304 cps/editbooks.py:306 +msgid "Book Successfully Deleted" +msgstr "Het boek is verwijderd" + +#: cps/editbooks.py:358 +msgid "You are missing permissions to delete books" +msgstr "" + +#: cps/editbooks.py:373 cps/editbooks.py:765 cps/web.py:518 cps/web.py:1783 +#: cps/web.py:1825 cps/web.py:1870 +msgid "Oops! Selected book title is unavailable. File does not exist or is not accessible" +msgstr "Oeps! Geselecteerd boek is niet beschikbaar. Bestand bestaat niet of is niet toegankelijk" + +#: cps/editbooks.py:408 +msgid "edit metadata" +msgstr "metagegevens bewerken" + +#: cps/editbooks.py:457 +#, python-format +msgid "%(seriesindex)s is not a valid number, skipping" +msgstr "%(seriesindex)s is geen geldig nummer, sla het over" + +#: cps/editbooks.py:493 cps/editbooks.py:1001 +#, fuzzy, python-format +msgid "'%(langname)s' is not a valid language" +msgstr "%(langname)s is geen geldige taal" + +#: cps/editbooks.py:634 +msgid "User has no rights to upload additional file formats" +msgstr "" + +#: cps/editbooks.py:639 cps/editbooks.py:1029 +#, python-format +msgid "File extension '%(ext)s' is not allowed to be uploaded to this server" +msgstr "De bestandsextensie '%(ext)s' is niet toegestaan op deze server" + +#: cps/editbooks.py:643 cps/editbooks.py:1033 +msgid "File to be uploaded must have an extension" +msgstr "Het te uploaden bestand moet voorzien zijn van een extensie" + +#: cps/editbooks.py:655 +#, python-format +msgid "Failed to create path %(path)s (Permission denied)." +msgstr "Kan de locatie '%(path)s' niet aanmaken (niet gemachtigd)." + +#: cps/editbooks.py:660 +#, python-format +msgid "Failed to store file %(file)s." +msgstr "Kan %(file)s niet opslaan." + +#: cps/editbooks.py:683 #, python-format msgid "File format %(ext)s added to %(book)s" msgstr "Bestandsformaat %(ext)s toegevoegd aan %(book)s" -#: cps/editbooks.py:814 +#: cps/editbooks.py:697 cps/editbooks.py:809 +msgid "User has no rights to upload cover" +msgstr "" + +#: cps/editbooks.py:828 msgid "Identifiers are not Case Sensitive, Overwriting Old Identifier" msgstr "Identificatoren zijn niet hoofdlettergevoelig, overschrijf huidige identificatoren" -#: cps/editbooks.py:848 +#: cps/editbooks.py:869 msgid "Metadata successfully updated" msgstr "De metagegevens zijn bijgewerkt" -#: cps/editbooks.py:861 -msgid "Error editing book, please check logfile for details" -msgstr "Kan het boek niet bewerken, controleer het logbestand" +#: cps/editbooks.py:887 +msgid "Error editing book: {}" +msgstr "" -#: cps/editbooks.py:899 +#: cps/editbooks.py:951 msgid "Uploaded book probably exists in the library, consider to change before upload new: " msgstr "Geüpload boek staat mogelijk al in de bibliotheek, controleer alvorens door te gaan: " -#: cps/editbooks.py:997 +#: cps/editbooks.py:1041 #, python-format msgid "File %(filename)s could not saved to temp dir" msgstr "Bestand %(filename)s kon niet opgeslagen worden in de tijdelijke map" -#: cps/editbooks.py:1016 +#: cps/editbooks.py:1061 #, python-format msgid "Failed to Move Cover File %(file)s: %(error)s" msgstr "Omslag %(file)s niet verplaatst: %(error)s" -#: cps/editbooks.py:1063 +#: cps/editbooks.py:1117 #, python-format msgid "File %(file)s uploaded" msgstr "Bestand %(file)s geüpload" -#: cps/editbooks.py:1088 +#: cps/editbooks.py:1143 msgid "Source or destination format for conversion missing" msgstr "Bron- of doelformaat ontbreekt voor conversie" -#: cps/editbooks.py:1096 +#: cps/editbooks.py:1151 #, python-format msgid "Book successfully queued for converting to %(book_format)s" msgstr "Het boek is in de wachtrij geplaatst voor conversie naar %(book_format)s" -#: cps/editbooks.py:1100 +#: cps/editbooks.py:1155 #, python-format msgid "There was an error converting this book: %(res)s" msgstr "Er is een fout opgetreden bij het converteren van dit boek: %(res)s" @@ -611,175 +614,192 @@ msgstr "Het instellen van Google Drive is niet afgerond, heractiveer Google Driv msgid "Callback domain is not verified, please follow steps to verify domain in google developer console" msgstr "Het callback-domein is niet geverifieerd. Volg de stappen in de Google-ontwikkelaarsconsole om het domein te verifiëren" -#: cps/helper.py:77 +#: cps/helper.py:81 #, python-format msgid "%(format)s format not found for book id: %(book)d" msgstr "%(format)s formaat niet gevonden voor boek met id: %(book)d" -#: cps/helper.py:83 cps/tasks/convert.py:73 +#: cps/helper.py:87 cps/tasks/convert.py:75 #, python-format msgid "%(format)s not found on Google Drive: %(fn)s" msgstr "%(format)s niet aangetroffen op Google Drive: %(fn)s" -#: cps/helper.py:88 +#: cps/helper.py:92 #, python-format msgid "%(format)s not found: %(fn)s" msgstr "%(format)s niet gevonden %(fn)s" -#: cps/helper.py:93 cps/helper.py:217 cps/templates/detail.html:41 +#: cps/helper.py:97 cps/helper.py:221 cps/templates/detail.html:41 #: cps/templates/detail.html:45 msgid "Send to Kindle" msgstr "Versturen naar Kindle" -#: cps/helper.py:94 cps/helper.py:111 cps/helper.py:219 +#: cps/helper.py:98 cps/helper.py:115 cps/helper.py:223 msgid "This e-mail has been sent via Calibre-Web." msgstr "Deze e-mail is verstuurd via Calibre-Web." -#: cps/helper.py:109 +#: cps/helper.py:113 msgid "Calibre-Web test e-mail" msgstr "Calibre-Web - test-e-mail" -#: cps/helper.py:110 +#: cps/helper.py:114 msgid "Test e-mail" msgstr "Test-e-mail" -#: cps/helper.py:127 +#: cps/helper.py:131 msgid "Get Started with Calibre-Web" msgstr "Aan de slag met Calibre-Web" -#: cps/helper.py:132 +#: cps/helper.py:136 #, python-format msgid "Registration e-mail for user: %(name)s" msgstr "Registratie-e-mailadres van gebruiker: %(name)s" -#: cps/helper.py:143 cps/helper.py:149 +#: cps/helper.py:147 cps/helper.py:153 #, python-format msgid "Convert %(orig)s to %(format)s and send to Kindle" msgstr "%(orig)s converteren naar %(format)s en versturen naar Kindle" -#: cps/helper.py:168 cps/helper.py:172 cps/helper.py:176 +#: cps/helper.py:172 cps/helper.py:176 cps/helper.py:180 #, python-format msgid "Send %(format)s to Kindle" msgstr "%(format)s versturen naar Kindle" -#: cps/helper.py:216 cps/tasks/convert.py:90 +#: cps/helper.py:220 cps/tasks/convert.py:92 #, fuzzy, python-format msgid "%(book)s send to Kindle" msgstr "%(book)s verzonden naar Kindle" -#: cps/helper.py:221 +#: cps/helper.py:225 msgid "The requested file could not be read. Maybe wrong permissions?" msgstr "Het opgevraagde bestand kan niet worden gelezen. Ben je hiertoe gemachtigd?" -#: cps/helper.py:313 +#: cps/helper.py:353 +msgid "Read status could not set: {}" +msgstr "" + +#: cps/helper.py:376 #, python-format msgid "Deleting bookfolder for book %(id)s failed, path has subfolders: %(path)s" msgstr "Het verwijderen van de boekenmap voor boek %(id)s is mislukt, het pad heeft submappen: %(path)s" -#: cps/helper.py:319 +#: cps/helper.py:382 #, python-format msgid "Deleting book %(id)s failed: %(message)s" msgstr "Verwijderen van boek %(id)s mislukt: %(message)s" -#: cps/helper.py:330 +#: cps/helper.py:393 #, fuzzy, python-format msgid "Deleting book %(id)s from database only, book path in database not valid: %(path)s" msgstr "Verwijder boek %(id)s alleen uit database, boek pad is ongeldig: %(path)s" -#: cps/helper.py:385 -#, python-format -msgid "Rename title from: '%(src)s' to '%(dest)s' failed with error: %(error)s" +#: cps/helper.py:458 +#, fuzzy, python-format +msgid "Rename author from: '%(src)s' to '%(dest)s' failed with error: %(error)s" msgstr "Kan de titel '%(src)s' niet wijzigen in '%(dest)s': %(error)s" -#: cps/helper.py:400 -#, python-format -msgid "Rename file in path '%(src)s' to '%(dest)s' failed with error: %(error)s" -msgstr "Kan het bestand in '%(src)s' niet wijzigen naar '%(dest)s': %(error)s" - -#: cps/helper.py:425 cps/helper.py:435 cps/helper.py:443 +#: cps/helper.py:529 cps/helper.py:538 #, python-format msgid "File %(file)s not found on Google Drive" msgstr "Bestand '%(file)s' niet aangetroffen op Google Drive" -#: cps/helper.py:464 +#: cps/helper.py:572 +#, python-format +msgid "Rename title from: '%(src)s' to '%(dest)s' failed with error: %(error)s" +msgstr "Kan de titel '%(src)s' niet wijzigen in '%(dest)s': %(error)s" + +#: cps/helper.py:592 +msgid "Error in rename file in path: {}" +msgstr "" + +#: cps/helper.py:610 #, python-format msgid "Book path %(path)s not found on Google Drive" msgstr "Boeken locatie '%(path)s' niet aangetroffen op Google Drive" -#: cps/helper.py:504 cps/web.py:1659 +#: cps/helper.py:651 cps/web.py:1737 #, fuzzy msgid "Found an existing account for this e-mail address" msgstr "Bestaand account met dit e-mailadres aangetroffen." -#: cps/helper.py:512 +#: cps/helper.py:659 msgid "This username is already taken" msgstr "Deze gebruikersnaam is al in gebruik" -#: cps/helper.py:522 +#: cps/helper.py:669 msgid "Invalid e-mail address format" msgstr "Ongeldig E-Mail adres" -#: cps/helper.py:595 +#: cps/helper.py:754 +msgid "Python modul 'advocate' is not installed but is needed for cover downloads" +msgstr "" + +#: cps/helper.py:767 msgid "Error Downloading Cover" msgstr "Fout bij downloaden omslag" -#: cps/helper.py:598 +#: cps/helper.py:770 msgid "Cover Format Error" msgstr "Onjuist omslagformaat" -#: cps/helper.py:608 +#: cps/helper.py:773 +msgid "You are not allowed to access localhost or the local network for cover uploads" +msgstr "" + +#: cps/helper.py:783 msgid "Failed to create path for cover" msgstr "Locatie aanmaken voor omslag mislukt" -#: cps/helper.py:624 +#: cps/helper.py:799 msgid "Cover-file is not a valid image file, or could not be stored" msgstr "Omslag-bestand is geen afbeelding of kon niet opgeslagen worden" -#: cps/helper.py:635 +#: cps/helper.py:810 msgid "Only jpg/jpeg/png/webp/bmp files are supported as coverfile" msgstr "Alleen jpg/jpeg/png/webp/bmp bestanden worden ondersteund als omslag" -#: cps/helper.py:648 +#: cps/helper.py:822 msgid "Invalid cover file content" msgstr "" -#: cps/helper.py:652 +#: cps/helper.py:826 msgid "Only jpg/jpeg files are supported as coverfile" msgstr "Alleen jpg/jpeg bestanden zijn toegestaan als omslag" -#: cps/helper.py:704 +#: cps/helper.py:878 msgid "Unrar binary file not found" msgstr "Unrar executable niet gevonden" -#: cps/helper.py:715 +#: cps/helper.py:889 msgid "Error excecuting UnRar" msgstr "Fout bij het uitvoeren van Unrar" -#: cps/helper.py:763 +#: cps/helper.py:937 msgid "Waiting" msgstr "Wachten" -#: cps/helper.py:765 +#: cps/helper.py:939 msgid "Failed" msgstr "Mislukt" -#: cps/helper.py:767 +#: cps/helper.py:941 msgid "Started" msgstr "Gestart" -#: cps/helper.py:769 +#: cps/helper.py:943 msgid "Finished" msgstr "Voltooid" -#: cps/helper.py:771 +#: cps/helper.py:945 msgid "Unknown Status" msgstr "Onbekende status" -#: cps/kobo_auth.py:127 -msgid "PLease access calibre-web from non localhost to get valid api_endpoint for kobo device" +#: cps/kobo_auth.py:128 +#, fuzzy +msgid "Please access Calibre-Web from non localhost to get valid api_endpoint for kobo device" msgstr "Je kunt Calibre-Web niet vanaf de lokale computer openen om een geldige api_endpoint te krijgen voor je kobo toestel" -#: cps/kobo_auth.py:130 cps/kobo_auth.py:158 +#: cps/kobo_auth.py:154 msgid "Kobo Setup" msgstr "Kobo Instellen" @@ -788,7 +808,7 @@ msgstr "Kobo Instellen" msgid "Register with %(provider)s" msgstr "Aanmelden bij %(provider)s" -#: cps/oauth_bb.py:138 cps/remotelogin.py:133 cps/web.py:1535 +#: cps/oauth_bb.py:138 cps/remotelogin.py:130 cps/web.py:1613 #, python-format msgid "you are now logged in as: '%(nickname)s'" msgstr "je bent ingelogd als: '%(nickname)s'" @@ -849,163 +869,163 @@ msgstr "Google OAuth fout, probeer het later nog eens." msgid "Google Oauth error: {}" msgstr "Google OAuth foutmelding: {}" -#: cps/opds.py:384 +#: cps/opds.py:298 msgid "{} Stars" msgstr "{} sterren" -#: cps/remotelogin.py:65 cps/templates/layout.html:84 -#: cps/templates/login.html:4 cps/templates/login.html:21 cps/web.py:1584 +#: cps/remotelogin.py:62 cps/templates/layout.html:84 +#: cps/templates/login.html:4 cps/templates/login.html:21 cps/web.py:1662 msgid "Login" msgstr "Inloggen" -#: cps/remotelogin.py:77 cps/remotelogin.py:111 +#: cps/remotelogin.py:74 cps/remotelogin.py:108 msgid "Token not found" msgstr "Toegangssleutel niet gevonden" -#: cps/remotelogin.py:86 cps/remotelogin.py:119 +#: cps/remotelogin.py:83 cps/remotelogin.py:116 msgid "Token has expired" msgstr "Toegangssleutel is verlopen" -#: cps/remotelogin.py:95 +#: cps/remotelogin.py:92 msgid "Success! Please return to your device" msgstr "Gelukt! Ga terug naar je apparaat" -#: cps/render_template.py:39 cps/web.py:416 +#: cps/render_template.py:41 cps/web.py:407 msgid "Books" msgstr "Boeken" -#: cps/render_template.py:41 +#: cps/render_template.py:43 msgid "Show recent books" msgstr "Recent toegevoegde boeken tonen" -#: cps/render_template.py:42 cps/templates/index.xml:25 +#: cps/render_template.py:44 cps/templates/index.xml:25 msgid "Hot Books" msgstr "Populaire boeken" -#: cps/render_template.py:44 +#: cps/render_template.py:46 msgid "Show Hot Books" msgstr "Populaire boeken tonen" -#: cps/render_template.py:46 cps/render_template.py:51 +#: cps/render_template.py:48 cps/render_template.py:53 msgid "Downloaded Books" msgstr "Gedownloade boeken" -#: cps/render_template.py:48 cps/render_template.py:53 +#: cps/render_template.py:50 cps/render_template.py:55 #: cps/templates/user_table.html:167 msgid "Show Downloaded Books" msgstr "Gedownloade boeken tonen" -#: cps/render_template.py:56 cps/templates/index.xml:32 cps/web.py:430 +#: cps/render_template.py:58 cps/templates/index.xml:32 cps/web.py:422 msgid "Top Rated Books" msgstr "Best beoordeelde boeken" -#: cps/render_template.py:58 cps/templates/user_table.html:161 +#: cps/render_template.py:60 cps/templates/user_table.html:161 msgid "Show Top Rated Books" msgstr "Best beoordeelde boeken tonen" -#: cps/render_template.py:59 cps/templates/index.xml:54 -#: cps/templates/index.xml:58 cps/web.py:676 +#: cps/render_template.py:61 cps/templates/index.xml:54 +#: cps/templates/index.xml:58 cps/web.py:729 msgid "Read Books" msgstr "Gelezen boeken" -#: cps/render_template.py:61 +#: cps/render_template.py:63 msgid "Show read and unread" msgstr "Gelezen/Ongelezen boeken tonen" -#: cps/render_template.py:63 cps/templates/index.xml:61 -#: cps/templates/index.xml:65 cps/web.py:679 +#: cps/render_template.py:65 cps/templates/index.xml:61 +#: cps/templates/index.xml:65 cps/web.py:732 msgid "Unread Books" msgstr "Ongelezen boeken" -#: cps/render_template.py:65 +#: cps/render_template.py:67 msgid "Show unread" msgstr "Ongelezen boeken tonen" -#: cps/render_template.py:66 +#: cps/render_template.py:68 msgid "Discover" msgstr "Willekeurige boeken" -#: cps/render_template.py:68 cps/templates/index.xml:50 +#: cps/render_template.py:70 cps/templates/index.xml:50 #: cps/templates/user_table.html:162 msgid "Show Random Books" msgstr "Willekeurige boeken tonen" -#: cps/render_template.py:69 cps/templates/book_table.html:67 -#: cps/templates/index.xml:83 cps/web.py:1041 +#: cps/render_template.py:71 cps/templates/book_table.html:67 +#: cps/templates/index.xml:83 cps/web.py:1135 msgid "Categories" msgstr "Categorieën" -#: cps/render_template.py:71 cps/templates/user_table.html:158 +#: cps/render_template.py:73 cps/templates/user_table.html:158 msgid "Show category selection" msgstr "Categoriekeuze tonen" -#: cps/render_template.py:72 cps/templates/book_edit.html:90 +#: cps/render_template.py:74 cps/templates/book_edit.html:90 #: cps/templates/book_table.html:68 cps/templates/index.xml:90 -#: cps/templates/search_form.html:69 cps/web.py:948 cps/web.py:959 +#: cps/templates/search_form.html:69 cps/web.py:1034 cps/web.py:1041 msgid "Series" msgstr "Boekenreeksen" -#: cps/render_template.py:74 cps/templates/user_table.html:157 +#: cps/render_template.py:76 cps/templates/user_table.html:157 msgid "Show series selection" msgstr "Boekenreeksenkeuze tonen" -#: cps/render_template.py:75 cps/templates/book_table.html:66 +#: cps/render_template.py:77 cps/templates/book_table.html:66 #: cps/templates/index.xml:69 msgid "Authors" msgstr "Auteurs" -#: cps/render_template.py:77 cps/templates/user_table.html:160 +#: cps/render_template.py:79 cps/templates/user_table.html:160 msgid "Show author selection" msgstr "Auteurkeuze tonen" -#: cps/render_template.py:79 cps/templates/book_table.html:72 -#: cps/templates/index.xml:76 cps/web.py:925 +#: cps/render_template.py:81 cps/templates/book_table.html:72 +#: cps/templates/index.xml:76 cps/web.py:1006 msgid "Publishers" msgstr "Uitgevers" -#: cps/render_template.py:81 cps/templates/user_table.html:163 +#: cps/render_template.py:83 cps/templates/user_table.html:163 msgid "Show publisher selection" msgstr "Uitgeverskeuze tonen" -#: cps/render_template.py:82 cps/templates/book_table.html:70 +#: cps/render_template.py:84 cps/templates/book_table.html:70 #: cps/templates/index.xml:97 cps/templates/search_form.html:107 -#: cps/web.py:1018 +#: cps/web.py:1108 msgid "Languages" msgstr "Talen" -#: cps/render_template.py:85 cps/templates/user_table.html:155 +#: cps/render_template.py:87 cps/templates/user_table.html:155 msgid "Show language selection" msgstr "Taalkeuze tonen" -#: cps/render_template.py:86 cps/templates/index.xml:104 +#: cps/render_template.py:88 cps/templates/index.xml:104 msgid "Ratings" msgstr "Beoordelingen" -#: cps/render_template.py:88 cps/templates/user_table.html:164 +#: cps/render_template.py:90 cps/templates/user_table.html:164 msgid "Show ratings selection" msgstr "Beoordelingen tonen" -#: cps/render_template.py:89 cps/templates/index.xml:112 +#: cps/render_template.py:91 cps/templates/index.xml:112 msgid "File formats" msgstr "Bestandsformaten" -#: cps/render_template.py:91 cps/templates/user_table.html:165 +#: cps/render_template.py:93 cps/templates/user_table.html:165 msgid "Show file formats selection" msgstr "Bestandsformaten tonen" -#: cps/render_template.py:93 cps/web.py:703 +#: cps/render_template.py:95 cps/web.py:755 msgid "Archived Books" msgstr "Gearchiveerde boeken" -#: cps/render_template.py:95 cps/templates/user_table.html:166 +#: cps/render_template.py:97 cps/templates/user_table.html:166 msgid "Show archived books" msgstr "Gearchiveerde boeken tonen" -#: cps/render_template.py:97 cps/web.py:780 +#: cps/render_template.py:100 cps/web.py:837 msgid "Books List" msgstr "Boekenlijst" -#: cps/render_template.py:99 cps/templates/user_table.html:168 +#: cps/render_template.py:102 cps/templates/user_table.html:168 msgid "Show Books List" msgstr "Boekenlijst tonen" @@ -1060,262 +1080,266 @@ msgstr "" msgid "Create a Shelf" msgstr "Boekenplank maken" -#: cps/shelf.py:237 +#: cps/shelf.py:236 #, fuzzy msgid "Sorry you are not allowed to edit this shelf" msgstr "Je bent niet gemachtigd deze boekenplank aan te passen" -#: cps/shelf.py:239 +#: cps/shelf.py:238 msgid "Edit a shelf" msgstr "Pas een boekenplank aan" -#: cps/shelf.py:249 +#: cps/shelf.py:248 msgid "Sorry you are not allowed to create a public shelf" msgstr "" -#: cps/shelf.py:266 +#: cps/shelf.py:265 #, python-format msgid "Shelf %(title)s created" msgstr "Boekenplank '%(title)s' aangemaakt" -#: cps/shelf.py:269 +#: cps/shelf.py:268 #, python-format msgid "Shelf %(title)s changed" msgstr "Boekenplank '%(title)s' is aangepast" -#: cps/shelf.py:283 +#: cps/shelf.py:282 msgid "There was an error" msgstr "Er is een fout opgetreden" -#: cps/shelf.py:305 +#: cps/shelf.py:304 #, python-format msgid "A public shelf with the name '%(title)s' already exists." msgstr "Een openbare boekenplank met de naam '%(title)s' bestaat al." -#: cps/shelf.py:316 +#: cps/shelf.py:315 #, python-format msgid "A private shelf with the name '%(title)s' already exists." msgstr "Een persoonlijke boekenplank met de naam '%(title)s' bestaat al." #: cps/shelf.py:337 +msgid "Error deleting Shelf" +msgstr "" + +#: cps/shelf.py:339 #, fuzzy msgid "Shelf successfully deleted" msgstr "Het boek is verwijderd" -#: cps/shelf.py:386 +#: cps/shelf.py:389 #, python-format msgid "Change order of Shelf: '%(name)s'" msgstr "Volgorde van boekenplank veranderen: '%(name)s'" -#: cps/shelf.py:456 +#: cps/shelf.py:461 #, python-format msgid "Shelf: '%(name)s'" msgstr "Boekenplank: '%(name)s'" -#: cps/shelf.py:460 +#: cps/shelf.py:465 msgid "Error opening shelf. Shelf does not exist or is not accessible" msgstr "Kan boekenplank niet openen: de boekenplank bestaat niet of is ontoegankelijk" -#: cps/updater.py:403 cps/updater.py:414 cps/updater.py:514 cps/updater.py:529 +#: cps/updater.py:426 cps/updater.py:437 cps/updater.py:538 cps/updater.py:553 msgid "Unexpected data while reading update information" msgstr "Onverwachte gegevens tijdens het uitlezen van de update-informatie" -#: cps/updater.py:410 cps/updater.py:521 +#: cps/updater.py:433 cps/updater.py:545 msgid "No update available. You already have the latest version installed" msgstr "Er is geen update beschikbaar." -#: cps/updater.py:428 +#: cps/updater.py:451 msgid "A new update is available. Click on the button below to update to the latest version." msgstr "Er is een update beschikbaar. Klik op de knop hieronder om te updaten naar de nieuwste versie." -#: cps/updater.py:446 +#: cps/updater.py:469 msgid "Could not fetch update information" msgstr "De update-informatie kan niet worden opgehaald" -#: cps/updater.py:456 +#: cps/updater.py:479 msgid "Click on the button below to update to the latest stable version." msgstr "Klik op de onderstaande knop om de laatste stabiele versie te installeren." -#: cps/updater.py:465 cps/updater.py:479 cps/updater.py:490 +#: cps/updater.py:488 cps/updater.py:502 cps/updater.py:513 #, python-format msgid "A new update is available. Click on the button below to update to version: %(version)s" msgstr "Er is een update beschikbaar. Klik op de knop hieronder om te updaten naar versie: %(version)s" -#: cps/updater.py:507 +#: cps/updater.py:531 msgid "No release information available" msgstr "Geen update-informatie beschikbaar" -#: cps/templates/index.html:5 cps/web.py:440 +#: cps/templates/index.html:5 cps/web.py:434 msgid "Discover (Random Books)" msgstr "Verkennen (willekeurige boeken)" -#: cps/web.py:471 +#: cps/web.py:470 msgid "Hot Books (Most Downloaded)" msgstr "Populaire boeken (meest gedownload)" -#: cps/web.py:507 +#: cps/web.py:501 #, python-format msgid "Downloaded books by %(user)s" msgstr "Gedownloade boeken door %(user)s" -#: cps/web.py:539 +#: cps/web.py:534 #, python-format msgid "Author: %(name)s" msgstr "Auteur: %(name)s" -#: cps/web.py:554 +#: cps/web.py:570 #, python-format msgid "Publisher: %(name)s" msgstr "Uitgever: %(name)s" -#: cps/web.py:569 +#: cps/web.py:598 #, python-format msgid "Series: %(serie)s" msgstr "Reeks: %(serie)s" -#: cps/web.py:582 +#: cps/web.py:610 #, python-format msgid "Rating: %(rating)s stars" msgstr "Beoordeling: %(rating)s sterren" -#: cps/web.py:597 +#: cps/web.py:626 #, python-format msgid "File format: %(format)s" msgstr "Bestandsformaat: %(format)s" -#: cps/web.py:615 +#: cps/web.py:663 #, python-format msgid "Category: %(name)s" msgstr "Categorie: %(name)s" -#: cps/web.py:631 +#: cps/web.py:690 #, python-format msgid "Language: %(name)s" msgstr "Taal: %(name)s" -#: cps/templates/layout.html:56 cps/web.py:737 cps/web.py:1371 +#: cps/templates/layout.html:56 cps/web.py:789 cps/web.py:1444 msgid "Advanced Search" msgstr "Geavanceerd zoeken" #: cps/templates/book_edit.html:235 cps/templates/feed.xml:33 #: cps/templates/index.xml:11 cps/templates/layout.html:45 #: cps/templates/layout.html:48 cps/templates/search_form.html:226 -#: cps/web.py:750 cps/web.py:1077 +#: cps/web.py:807 cps/web.py:1164 msgid "Search" msgstr "Zoeken" -#: cps/templates/admin.html:16 cps/web.py:903 +#: cps/templates/admin.html:16 cps/web.py:979 msgid "Downloads" msgstr "Downloads" -#: cps/web.py:980 +#: cps/web.py:1068 msgid "Ratings list" msgstr "Beoordelingen" -#: cps/web.py:1001 +#: cps/web.py:1095 msgid "File formats list" msgstr "Alle bestandsformaten" -#: cps/templates/layout.html:73 cps/templates/tasks.html:7 cps/web.py:1055 +#: cps/templates/layout.html:73 cps/templates/tasks.html:7 cps/web.py:1149 msgid "Tasks" msgstr "Taken" -#: cps/web.py:1215 +#: cps/web.py:1286 msgid "Published after " msgstr "Gepubliceerd na " -#: cps/web.py:1222 +#: cps/web.py:1293 msgid "Published before " msgstr "Gepubliceerd vóór " -#: cps/web.py:1244 +#: cps/web.py:1315 #, python-format msgid "Rating <= %(rating)s" msgstr "Beoordeling <= %(rating)s" -#: cps/web.py:1246 +#: cps/web.py:1317 #, python-format msgid "Rating >= %(rating)s" msgstr "Beoordeling >= %(rating)s" -#: cps/web.py:1248 +#: cps/web.py:1319 #, python-format msgid "Read Status = %(status)s" msgstr "Lees Status = %(status)s" -#: cps/web.py:1353 +#: cps/web.py:1425 msgid "Error on search for custom columns, please restart Calibre-Web" msgstr "Fout tijdens het zoeken van aangepaste kolommen, start Calibre-Web opnieuw op" -#: cps/web.py:1449 +#: cps/web.py:1527 #, python-format msgid "Book successfully queued for sending to %(kindlemail)s" msgstr "Het boek is in de wachtrij geplaatst om te worden verstuurd aan %(kindlemail)s" -#: cps/web.py:1453 +#: cps/web.py:1531 #, python-format msgid "Oops! There was an error sending this book: %(res)s" msgstr "Fout opgetreden bij het versturen van dit boek: %(res)s" -#: cps/web.py:1455 +#: cps/web.py:1533 msgid "Please update your profile with a valid Send to Kindle E-mail Address." msgstr "Stel je kindle-e-mailadres in..." -#: cps/web.py:1472 +#: cps/web.py:1550 msgid "E-Mail server is not configured, please contact your administrator!" msgstr "E-mailserver is niet geconfigureerd, neem contact op met de beheerder!" -#: cps/templates/layout.html:85 cps/templates/register.html:17 cps/web.py:1473 -#: cps/web.py:1480 cps/web.py:1486 cps/web.py:1505 cps/web.py:1509 -#: cps/web.py:1515 +#: cps/templates/layout.html:85 cps/templates/register.html:17 cps/web.py:1551 +#: cps/web.py:1558 cps/web.py:1564 cps/web.py:1583 cps/web.py:1587 +#: cps/web.py:1593 msgid "Register" msgstr "Registreren" -#: cps/web.py:1507 +#: cps/web.py:1585 msgid "Your e-mail is not allowed to register" msgstr "Dit e-mailadres mag niet worden gebruikt voor registratie" -#: cps/web.py:1510 +#: cps/web.py:1588 msgid "Confirmation e-mail was send to your e-mail account." msgstr "Er is een bevestigings-e-mail verstuurd naar je e-mailadres." -#: cps/web.py:1524 +#: cps/web.py:1602 msgid "Cannot activate LDAP authentication" msgstr "Kan de LDAP authenticatie niet activeren" -#: cps/web.py:1543 +#: cps/web.py:1621 #, python-format msgid "Fallback Login as: '%(nickname)s', LDAP Server not reachable, or user not known" msgstr "Terugvallen op login: '%(nickname)s', LDAP Server is onbereikbaar, of de gebruiker is onbekend" -#: cps/web.py:1549 +#: cps/web.py:1627 #, python-format msgid "Could not login: %(message)s" msgstr "Inloggen mislukt: %(message)s" -#: cps/web.py:1553 cps/web.py:1578 +#: cps/web.py:1631 cps/web.py:1656 msgid "Wrong Username or Password" msgstr "Verkeerde gebruikersnaam of wachtwoord" -#: cps/web.py:1560 +#: cps/web.py:1638 msgid "New Password was send to your email address" msgstr "Een nieuw wachtwoord is verzonden naar je e-mailadres" -#: cps/web.py:1566 +#: cps/web.py:1644 msgid "Please enter valid username to reset password" msgstr "Geef een geldige gebruikersnaam op om je wachtwoord te herstellen" -#: cps/web.py:1573 +#: cps/web.py:1651 #, python-format msgid "You are now logged in as: '%(nickname)s'" msgstr "Je bent ingelogd als: '%(nickname)s'" -#: cps/web.py:1639 cps/web.py:1688 +#: cps/web.py:1717 cps/web.py:1766 #, python-format msgid "%(name)s's profile" msgstr "%(name)ss profiel" -#: cps/web.py:1655 +#: cps/web.py:1733 msgid "Profile updated" msgstr "Profiel bijgewerkt" @@ -1323,36 +1347,36 @@ msgstr "Profiel bijgewerkt" msgid "Found no valid gmail.json file with OAuth information" msgstr "Geen geldig gmail.json bestand gevonden met OAuth informatie" -#: cps/tasks/convert.py:137 +#: cps/tasks/convert.py:154 #, python-format msgid "Calibre ebook-convert %(tool)s not found" msgstr "Calibre ebook-convert %(tool)s niet gevonden" -#: cps/tasks/convert.py:163 +#: cps/tasks/convert.py:187 #, python-format msgid "%(format)s format not found on disk" msgstr "%(format)s formaat is niet gevonden op de schijf" -#: cps/tasks/convert.py:167 +#: cps/tasks/convert.py:191 msgid "Ebook converter failed with unknown error" msgstr "E-Book converter mislukt met een onbekende foutmelding" -#: cps/tasks/convert.py:177 +#: cps/tasks/convert.py:201 #, python-format msgid "Kepubify-converter failed: %(error)s" msgstr "Kepubify-converteerder mislukt: %(error)s" -#: cps/tasks/convert.py:199 +#: cps/tasks/convert.py:223 #, python-format msgid "Converted file not found or more than one file in folder %(folder)s" msgstr "Omgezette bestand is niet gevonden of meer dan een bestand in map %(folder)s" -#: cps/tasks/convert.py:222 +#: cps/tasks/convert.py:246 #, python-format msgid "Ebook-converter failed: %(error)s" msgstr "E-boek-conversie mislukt: %(error)s" -#: cps/tasks/convert.py:245 +#: cps/tasks/convert.py:269 #, python-format msgid "Calibre failed with error: %(error)s" msgstr "Calibre mislukt met foutmelding: %(error)s" @@ -1407,7 +1431,7 @@ msgid "Edit" msgstr "Bewerken" #: cps/templates/admin.html:25 cps/templates/book_edit.html:16 -#: cps/templates/book_table.html:97 cps/templates/modal_dialogs.html:63 +#: cps/templates/book_table.html:100 cps/templates/modal_dialogs.html:63 #: cps/templates/modal_dialogs.html:116 cps/templates/user_edit.html:67 #: cps/templates/user_table.html:149 msgid "Delete" @@ -1417,180 +1441,180 @@ msgstr "Verwijderen" msgid "Public Shelf" msgstr "Openbare boekenplank" -#: cps/templates/admin.html:51 +#: cps/templates/admin.html:53 msgid "Add New User" msgstr "Gebruiker toevoegen" -#: cps/templates/admin.html:53 +#: cps/templates/admin.html:55 msgid "Import LDAP Users" msgstr "LDAP gebruikers importeren" -#: cps/templates/admin.html:60 +#: cps/templates/admin.html:62 msgid "E-mail Server Settings" msgstr "SMTP-serverinstellingen" -#: cps/templates/admin.html:65 cps/templates/email_edit.html:31 +#: cps/templates/admin.html:67 cps/templates/email_edit.html:31 msgid "SMTP Hostname" msgstr "SMTP-hostnaam (gebruik mail.example.org om wachtwoordherstel uit te schakelen)" -#: cps/templates/admin.html:69 cps/templates/email_edit.html:35 +#: cps/templates/admin.html:71 cps/templates/email_edit.html:35 msgid "SMTP Port" msgstr "SMTP-poort" -#: cps/templates/admin.html:73 cps/templates/email_edit.html:39 +#: cps/templates/admin.html:75 cps/templates/email_edit.html:39 msgid "Encryption" msgstr "Encryptie" -#: cps/templates/admin.html:77 cps/templates/email_edit.html:47 +#: cps/templates/admin.html:79 cps/templates/email_edit.html:47 msgid "SMTP Login" msgstr "SMTP-gebruikersnaam" -#: cps/templates/admin.html:81 cps/templates/admin.html:92 +#: cps/templates/admin.html:83 cps/templates/admin.html:94 #: cps/templates/email_edit.html:55 msgid "From E-mail" msgstr "Van e-mail" -#: cps/templates/admin.html:88 +#: cps/templates/admin.html:90 msgid "E-Mail Service" msgstr "E-Mail Service" -#: cps/templates/admin.html:89 +#: cps/templates/admin.html:91 msgid "Gmail via Oauth2" msgstr "Gmail via OAuth2" -#: cps/templates/admin.html:104 +#: cps/templates/admin.html:106 msgid "Configuration" msgstr "Instellingen" -#: cps/templates/admin.html:107 +#: cps/templates/admin.html:109 msgid "Calibre Database Directory" msgstr "Calibre-database locatie" -#: cps/templates/admin.html:111 cps/templates/config_edit.html:68 +#: cps/templates/admin.html:113 cps/templates/config_edit.html:68 msgid "Log Level" msgstr "Logniveau" -#: cps/templates/admin.html:115 +#: cps/templates/admin.html:117 msgid "Port" msgstr "Poort" -#: cps/templates/admin.html:120 +#: cps/templates/admin.html:122 msgid "External Port" msgstr "Externe poort" -#: cps/templates/admin.html:127 cps/templates/config_view_edit.html:28 +#: cps/templates/admin.html:129 cps/templates/config_view_edit.html:28 msgid "Books per Page" msgstr "Aantal boeken per pagina" -#: cps/templates/admin.html:131 +#: cps/templates/admin.html:133 msgid "Uploads" msgstr "Uploaden toestaan" -#: cps/templates/admin.html:135 +#: cps/templates/admin.html:137 msgid "Anonymous Browsing" msgstr "Anoniem verkennen" -#: cps/templates/admin.html:139 +#: cps/templates/admin.html:141 msgid "Public Registration" msgstr "Openbare registratie" -#: cps/templates/admin.html:143 +#: cps/templates/admin.html:145 msgid "Magic Link Remote Login" msgstr "Inloggen op afstand" -#: cps/templates/admin.html:147 +#: cps/templates/admin.html:149 msgid "Reverse Proxy Login" msgstr "Reverse Proxy Login" -#: cps/templates/admin.html:152 cps/templates/config_edit.html:173 +#: cps/templates/admin.html:154 cps/templates/config_edit.html:173 msgid "Reverse Proxy Header Name" msgstr "Reverse proxy header naam" -#: cps/templates/admin.html:157 +#: cps/templates/admin.html:159 #, fuzzy msgid "Edit Calibre Database Configuration" msgstr "Bewerk Calibre databaseconfiguratie" -#: cps/templates/admin.html:158 +#: cps/templates/admin.html:160 msgid "Edit Basic Configuration" msgstr "Bewerk basisconfiguratie" -#: cps/templates/admin.html:159 +#: cps/templates/admin.html:161 msgid "Edit UI Configuration" msgstr "Bewerk gebruikersinterface configuratie" -#: cps/templates/admin.html:164 +#: cps/templates/admin.html:166 msgid "Administration" msgstr "Systeembeheer" -#: cps/templates/admin.html:165 +#: cps/templates/admin.html:167 msgid "Download Debug Package" msgstr "Download foutopsporingspakket" -#: cps/templates/admin.html:166 +#: cps/templates/admin.html:168 msgid "View Logs" msgstr "Logboeken bekijken" -#: cps/templates/admin.html:169 +#: cps/templates/admin.html:171 msgid "Reconnect Calibre Database" msgstr "Opnieuw verbinden met Calibre database" -#: cps/templates/admin.html:170 +#: cps/templates/admin.html:172 msgid "Restart" msgstr "Calibre-Web herstarten" -#: cps/templates/admin.html:171 +#: cps/templates/admin.html:173 msgid "Shutdown" msgstr "Calibre-Web stoppen" -#: cps/templates/admin.html:176 +#: cps/templates/admin.html:178 msgid "Update" msgstr "Bijwerken" -#: cps/templates/admin.html:180 +#: cps/templates/admin.html:182 msgid "Version" msgstr "Versie" -#: cps/templates/admin.html:181 +#: cps/templates/admin.html:183 msgid "Details" msgstr "Details" -#: cps/templates/admin.html:187 +#: cps/templates/admin.html:189 msgid "Current version" msgstr "Huidige versie" -#: cps/templates/admin.html:194 +#: cps/templates/admin.html:196 msgid "Check for Update" msgstr "Controleren op updates" -#: cps/templates/admin.html:195 +#: cps/templates/admin.html:197 msgid "Perform Update" msgstr "Update uitvoeren" -#: cps/templates/admin.html:208 +#: cps/templates/admin.html:210 msgid "Are you sure you want to restart?" msgstr "Weet je zeker dat je Calibre-Web wilt herstarten?" -#: cps/templates/admin.html:213 cps/templates/admin.html:227 -#: cps/templates/admin.html:247 cps/templates/config_db.html:70 +#: cps/templates/admin.html:215 cps/templates/admin.html:229 +#: cps/templates/admin.html:249 cps/templates/config_db.html:70 msgid "OK" msgstr "Oké" -#: cps/templates/admin.html:214 cps/templates/admin.html:228 -#: cps/templates/book_edit.html:213 cps/templates/book_table.html:124 +#: cps/templates/admin.html:216 cps/templates/admin.html:230 +#: cps/templates/book_edit.html:213 cps/templates/book_table.html:127 #: cps/templates/config_db.html:54 cps/templates/config_edit.html:359 -#: cps/templates/config_view_edit.html:173 cps/templates/modal_dialogs.html:64 +#: cps/templates/config_view_edit.html:175 cps/templates/modal_dialogs.html:64 #: cps/templates/modal_dialogs.html:99 cps/templates/modal_dialogs.html:117 #: cps/templates/modal_dialogs.html:135 cps/templates/shelf_edit.html:27 #: cps/templates/user_edit.html:144 msgid "Cancel" msgstr "Annuleren" -#: cps/templates/admin.html:226 +#: cps/templates/admin.html:228 msgid "Are you sure you want to shutdown?" msgstr "Weet je zeker dat je Calibre-Web wilt stoppen?" -#: cps/templates/admin.html:238 +#: cps/templates/admin.html:240 msgid "Updating, please do not reload this page" msgstr "Bezig met bijwerken, vernieuw de pagina niet" @@ -1602,44 +1626,43 @@ msgstr "via" msgid "In Library" msgstr "In bibliotheek" -#: cps/templates/author.html:26 cps/templates/index.html:72 -#: cps/templates/search.html:29 cps/templates/shelf.html:19 +#: cps/templates/author.html:26 cps/templates/index.html:73 +#: cps/templates/search.html:30 cps/templates/shelf.html:19 msgid "Sort according to book date, newest first" msgstr "Sorteren op datum, nieuwste boeken eerst" -#: cps/templates/author.html:27 cps/templates/index.html:73 -#: cps/templates/search.html:30 cps/templates/shelf.html:20 +#: cps/templates/author.html:27 cps/templates/index.html:74 +#: cps/templates/search.html:31 cps/templates/shelf.html:20 msgid "Sort according to book date, oldest first" msgstr "Sorteren op datum, oudste boeken eerst" -#: cps/templates/author.html:28 cps/templates/index.html:74 -#: cps/templates/search.html:31 cps/templates/shelf.html:21 +#: cps/templates/author.html:28 cps/templates/index.html:75 +#: cps/templates/search.html:32 cps/templates/shelf.html:21 msgid "Sort title in alphabetical order" msgstr "Sorteren op alfabetische volgorde" -#: cps/templates/author.html:29 cps/templates/index.html:75 -#: cps/templates/search.html:32 cps/templates/shelf.html:22 +#: cps/templates/author.html:29 cps/templates/index.html:76 +#: cps/templates/search.html:33 cps/templates/shelf.html:22 msgid "Sort title in reverse alphabetical order" msgstr "Sorteren op omgekeerde alfabetische volgorde" -#: cps/templates/author.html:30 cps/templates/index.html:78 -#: cps/templates/search.html:35 cps/templates/shelf.html:25 +#: cps/templates/author.html:30 cps/templates/index.html:79 +#: cps/templates/search.html:36 cps/templates/shelf.html:25 msgid "Sort according to publishing date, newest first" msgstr "Sorteren op publicatiedatum, nieuwste boeken eerst" -#: cps/templates/author.html:31 cps/templates/index.html:79 -#: cps/templates/search.html:36 cps/templates/shelf.html:26 +#: cps/templates/author.html:31 cps/templates/index.html:80 +#: cps/templates/search.html:37 cps/templates/shelf.html:26 msgid "Sort according to publishing date, oldest first" msgstr "Sorteren op publicatiedatum, oudste boeken eerst" -#: cps/templates/author.html:57 cps/templates/author.html:117 -#: cps/templates/discover.html:30 cps/templates/index.html:29 -#: cps/templates/index.html:111 cps/templates/search.html:65 -#: cps/templates/shelf.html:54 +#: cps/templates/author.html:56 cps/templates/author.html:115 +#: cps/templates/index.html:29 cps/templates/index.html:112 +#: cps/templates/search.html:66 cps/templates/shelf.html:54 msgid "reduce" msgstr "beperken" -#: cps/templates/author.html:101 +#: cps/templates/author.html:99 msgid "More by" msgstr "Meer van" @@ -1764,7 +1787,7 @@ msgid "Fetch Metadata" msgstr "Metagegevens ophalen" #: cps/templates/book_edit.html:212 cps/templates/config_db.html:53 -#: cps/templates/config_edit.html:358 cps/templates/config_view_edit.html:172 +#: cps/templates/config_edit.html:358 cps/templates/config_view_edit.html:174 #: cps/templates/email_edit.html:65 cps/templates/shelf_edit.html:25 #: cps/templates/shelf_order.html:41 cps/templates/user_edit.html:142 msgid "Save" @@ -1893,27 +1916,35 @@ msgstr "Voer domeinnaam in" msgid "Comments" msgstr "" -#: cps/templates/book_table.html:77 cps/templates/book_table.html:79 -#: cps/templates/book_table.html:81 cps/templates/book_table.html:83 -#: cps/templates/book_table.html:87 cps/templates/book_table.html:89 -#: cps/templates/book_table.html:91 cps/templates/book_table.html:93 +#: cps/templates/book_table.html:75 +msgid "Archiv Status" +msgstr "" + +#: cps/templates/book_table.html:77 cps/templates/search_form.html:42 +msgid "Read Status" +msgstr "Lees Status" + +#: cps/templates/book_table.html:80 cps/templates/book_table.html:82 +#: cps/templates/book_table.html:84 cps/templates/book_table.html:86 +#: cps/templates/book_table.html:90 cps/templates/book_table.html:92 +#: cps/templates/book_table.html:96 #, fuzzy msgid "Enter " msgstr "Identificatoren" -#: cps/templates/book_table.html:110 cps/templates/modal_dialogs.html:46 +#: cps/templates/book_table.html:113 cps/templates/modal_dialogs.html:46 msgid "Are you really sure?" msgstr "Weet je het zeker?" -#: cps/templates/book_table.html:114 +#: cps/templates/book_table.html:117 msgid "Books with Title will be merged from:" msgstr "Boeken met de titel zullen worden samengevoegd van:" -#: cps/templates/book_table.html:118 +#: cps/templates/book_table.html:121 msgid "Into Book with Title:" msgstr "In boek met titel:" -#: cps/templates/book_table.html:123 +#: cps/templates/book_table.html:126 msgid "Merge" msgstr "Samenvoegen" @@ -2090,11 +2121,6 @@ msgstr "LDAP Server Poort" msgid "LDAP Encryption" msgstr "LDAP encryptie" -#: cps/templates/config_edit.html:204 cps/templates/config_view_edit.html:62 -#: cps/templates/email_edit.html:41 -msgid "None" -msgstr "Geen" - #: cps/templates/config_edit.html:205 msgid "TLS" msgstr "TLS" @@ -2313,11 +2339,11 @@ msgstr "Standaard zichtbaar voor nieuwe gebruikers" msgid "Show Random Books in Detail View" msgstr "Willekeurige boeken tonen in gedetailleerde weergave" -#: cps/templates/config_view_edit.html:165 cps/templates/user_edit.html:87 +#: cps/templates/config_view_edit.html:166 cps/templates/user_edit.html:87 msgid "Add Allowed/Denied Tags" msgstr "Voeg toegestane/geweigerde tags toe" -#: cps/templates/config_view_edit.html:166 +#: cps/templates/config_view_edit.html:167 msgid "Add Allowed/Denied custom column values" msgstr "Voeg toegestane/geweigerde aangepaste kolomwaarden toe" @@ -2366,13 +2392,13 @@ msgstr "Gearchiveerd" msgid "Description:" msgstr "Beschrijving:" -#: cps/templates/detail.html:256 cps/templates/search.html:14 +#: cps/templates/detail.html:256 cps/templates/search.html:15 msgid "Add to shelf" msgstr "Toevoegen aan boekenplank" #: cps/templates/detail.html:267 cps/templates/detail.html:284 #: cps/templates/feed.xml:79 cps/templates/layout.html:137 -#: cps/templates/search.html:20 +#: cps/templates/search.html:21 msgid "(Public)" msgstr "(Openbaar)" @@ -2450,10 +2476,15 @@ msgstr "Geweigerde domeinen voor registratie" msgid "Next" msgstr "Volgende" -#: cps/templates/generate_kobo_auth_url.html:5 +#: cps/templates/generate_kobo_auth_url.html:6 msgid "Open the .kobo/Kobo eReader.conf file in a text editor and add (or edit):" msgstr "Open het .kobo/Kobo eReader.conf bestand in een teksteditor en voeg toe (of bewerk):" +#: cps/templates/generate_kobo_auth_url.html:11 +#, fuzzy +msgid "Kobo Token:" +msgstr "Kobo Sync Token" + #: cps/templates/http_error.html:31 #, fuzzy msgid "Calibre-Web Instance is unconfigured, please contact your administrator" @@ -2471,29 +2502,29 @@ msgstr "Terug naar startpagina" msgid "Logout User" msgstr "Gebruiker uitloggen" -#: cps/templates/index.html:69 +#: cps/templates/index.html:70 msgid "Sort ascending according to download count" msgstr "" -#: cps/templates/index.html:70 +#: cps/templates/index.html:71 msgid "Sort descending according to download count" msgstr "" -#: cps/templates/index.html:76 cps/templates/search.html:33 +#: cps/templates/index.html:77 cps/templates/search.html:34 #: cps/templates/shelf.html:23 msgid "Sort authors in alphabetical order" msgstr "Auteurs sorteren op alfabetische volgorde" -#: cps/templates/index.html:77 cps/templates/search.html:34 +#: cps/templates/index.html:78 cps/templates/search.html:35 #: cps/templates/shelf.html:24 msgid "Sort authors in reverse alphabetical order" msgstr "Auteurs sorteren op omgekeerde alfabetische volgorde" -#: cps/templates/index.html:81 +#: cps/templates/index.html:82 msgid "Sort ascending according to series index" msgstr "Sorteer oplopend volgens de serie index" -#: cps/templates/index.html:82 +#: cps/templates/index.html:83 msgid "Sort descending according to series index" msgstr "Sorteer aflopend volgens de serie index" @@ -2929,10 +2960,6 @@ msgstr "Publicatiedatum van" msgid "Published Date To" msgstr "Publicatiedatum tot" -#: cps/templates/search_form.html:42 -msgid "Read Status" -msgstr "Lees Status" - #: cps/templates/search_form.html:59 msgid "Exclude Tags" msgstr "Labels uitsluiten" diff --git a/cps/translations/pl/LC_MESSAGES/messages.mo b/cps/translations/pl/LC_MESSAGES/messages.mo index b02cacdb..9fa13572 100644 Binary files a/cps/translations/pl/LC_MESSAGES/messages.mo and b/cps/translations/pl/LC_MESSAGES/messages.mo differ diff --git a/cps/translations/pl/LC_MESSAGES/messages.po b/cps/translations/pl/LC_MESSAGES/messages.po index af7e9bcd..ce4898e6 100644 --- a/cps/translations/pl/LC_MESSAGES/messages.po +++ b/cps/translations/pl/LC_MESSAGES/messages.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: Calibre Web - polski (POT: 2021-06-12 08:52)\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2022-01-15 09:19+0100\n" +"POT-Creation-Date: 2022-04-18 20:01+0200\n" "PO-Revision-Date: 2021-06-12 15:35+0200\n" "Last-Translator: Radosław Kierznowski \n" "Language: pl\n" @@ -17,589 +17,592 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.9.0\n" +"Generated-By: Babel 2.9.1\n" -#: cps/about.py:34 cps/about.py:49 cps/about.py:65 cps/converter.py:31 -msgid "not installed" -msgstr "nie zainstalowane" - -#: cps/about.py:47 cps/about.py:63 -msgid "installed" -msgstr "zainstalowane" - -#: cps/about.py:145 +#: cps/about.py:86 msgid "Statistics" msgstr "Statystyki" -#: cps/admin.py:144 +#: cps/admin.py:141 msgid "Server restarted, please reload page" msgstr "Serwer uruchomiony ponownie, proszę odświeżyć stronę" -#: cps/admin.py:146 +#: cps/admin.py:143 msgid "Performing shutdown of server, please close window" msgstr "Wykonano wyłączenie serwera, proszę zamknąć okno" -#: cps/admin.py:154 +#: cps/admin.py:151 msgid "Reconnect successful" msgstr "Ponowne połączenie zakończono sukcesem" -#: cps/admin.py:157 +#: cps/admin.py:154 msgid "Unknown command" msgstr "Nieznane polecenie" # ??? -#: cps/admin.py:167 cps/editbooks.py:707 cps/editbooks.py:721 -#: cps/editbooks.py:866 cps/editbooks.py:868 cps/editbooks.py:895 -#: cps/editbooks.py:911 cps/updater.py:584 cps/uploader.py:93 -#: cps/uploader.py:103 +#: cps/admin.py:176 cps/editbooks.py:713 cps/editbooks.py:892 +#: cps/editbooks.py:894 cps/editbooks.py:930 cps/editbooks.py:947 +#: cps/updater.py:608 cps/uploader.py:93 cps/uploader.py:103 msgid "Unknown" msgstr "Nieznany" -#: cps/admin.py:188 +#: cps/admin.py:197 msgid "Admin page" msgstr "Panel administratora" -#: cps/admin.py:207 +#: cps/admin.py:217 msgid "Basic Configuration" msgstr "Konfiguracja podstawowa" -#: cps/admin.py:244 +#: cps/admin.py:255 msgid "UI Configuration" msgstr "Konfiguracja Interfejsu" -#: cps/admin.py:277 cps/templates/admin.html:50 +#: cps/admin.py:289 cps/templates/admin.html:51 msgid "Edit Users" msgstr "Edytuj użytkowników" # ??? -#: cps/admin.py:318 cps/opds.py:109 cps/opds.py:198 cps/opds.py:275 -#: cps/opds.py:327 cps/templates/grid.html:13 cps/templates/languages.html:9 +#: cps/admin.py:333 cps/opds.py:529 cps/templates/grid.html:13 #: cps/templates/list.html:13 msgid "All" msgstr "Wszystko" -#: cps/admin.py:343 cps/admin.py:1615 +#: cps/admin.py:360 cps/admin.py:1648 msgid "User not found" msgstr "Nie znaleziono użytkownika" -#: cps/admin.py:357 +#: cps/admin.py:374 msgid "{} users deleted successfully" msgstr "{} użytkowników usuniętych pomyślnie" -#: cps/admin.py:379 cps/templates/config_view_edit.html:133 +#: cps/admin.py:397 cps/templates/config_view_edit.html:133 #: cps/templates/user_edit.html:45 cps/templates/user_table.html:81 msgid "Show All" msgstr "Pokaż wszystkie" -#: cps/admin.py:400 cps/admin.py:406 +#: cps/admin.py:418 cps/admin.py:424 msgid "Malformed request" msgstr "Nieprawidłowo sformułowane żądanie" -#: cps/admin.py:418 cps/admin.py:1493 +#: cps/admin.py:436 cps/admin.py:1526 msgid "Guest Name can't be changed" msgstr "Nazwa gościa nie może być zmieniona" -#: cps/admin.py:430 +#: cps/admin.py:448 msgid "Guest can't have this role" msgstr "Gość nie może pełnić tej roli" -#: cps/admin.py:442 cps/admin.py:1451 +#: cps/admin.py:460 cps/admin.py:1484 msgid "No admin user remaining, can't remove admin role" msgstr "Nie można odebrać praw administratora. Brak na serwerze innego konta z prawami administratora" -#: cps/admin.py:446 cps/admin.py:460 +#: cps/admin.py:464 cps/admin.py:478 msgid "Value has to be true or false" msgstr "Wartość musi być prawdziwa lub fałszywa" -#: cps/admin.py:448 +#: cps/admin.py:466 msgid "Invalid role" msgstr "Nieprawidłowa rola" -#: cps/admin.py:452 +#: cps/admin.py:470 msgid "Guest can't have this view" msgstr "Gość nie może tego zobaczyć" -#: cps/admin.py:462 +#: cps/admin.py:480 msgid "Invalid view" msgstr "Nieprawidłowy widok" -#: cps/admin.py:465 +#: cps/admin.py:483 msgid "Guest's Locale is determined automatically and can't be set" msgstr "Lokalizacja gościa jest określana automatycznie i nie można jej ustawić" -#: cps/admin.py:469 +#: cps/admin.py:487 msgid "No Valid Locale Given" msgstr "Nie podano prawidłowej lokalizacji" -#: cps/admin.py:480 +#: cps/admin.py:498 msgid "No Valid Book Language Given" msgstr "Nie podano obowiązującego języka książki" -#: cps/admin.py:482 +#: cps/admin.py:500 cps/editbooks.py:1267 msgid "Parameter not found" msgstr "Nie znaleziono parametru" -#: cps/admin.py:533 +#: cps/admin.py:553 #, fuzzy msgid "Invalid Read Column" msgstr "Nieprawidłowa kolumna odczytu" -#: cps/admin.py:539 +#: cps/admin.py:559 #, fuzzy msgid "Invalid Restricted Column" msgstr "Nieprawidłowa kolumna z ograniczeniami" -#: cps/admin.py:560 cps/admin.py:1323 +#: cps/admin.py:579 cps/admin.py:1355 msgid "Calibre-Web configuration updated" msgstr "Konfiguracja Calibre-Web została zaktualizowana" -#: cps/admin.py:572 +#: cps/admin.py:591 msgid "Do you really want to delete the Kobo Token?" msgstr "Czy na pewno chcesz usunąć Token Kobo?" -#: cps/admin.py:574 +#: cps/admin.py:593 msgid "Do you really want to delete this domain?" msgstr "Czy naprawdę chcesz usunąć tę domenę?" -#: cps/admin.py:576 +#: cps/admin.py:595 msgid "Do you really want to delete this user?" msgstr "Czy naprawdę chcesz usunąć tego użytkownika?" -#: cps/admin.py:578 +#: cps/admin.py:597 msgid "Are you sure you want to delete this shelf?" msgstr "Czy na pewno chcesz usunąć półkę?" -#: cps/admin.py:580 +#: cps/admin.py:599 msgid "Are you sure you want to change locales of selected user(s)?" msgstr "Czy na pewno chcesz zmienić ustawienia lokalne wybranego użytkownika(ów)?" -#: cps/admin.py:582 +#: cps/admin.py:601 msgid "Are you sure you want to change visible book languages for selected user(s)?" msgstr "Czy na pewno chcesz zmienić widoczne języki książek dla wybranego użytkownika (użytkowników)?" -#: cps/admin.py:584 +#: cps/admin.py:603 msgid "Are you sure you want to change the selected role for the selected user(s)?" msgstr "Czy na pewno chcesz zmienić wybraną rolę dla wybranego użytkownika (użytkowników)?" -#: cps/admin.py:586 +#: cps/admin.py:605 msgid "Are you sure you want to change the selected restrictions for the selected user(s)?" msgstr "Czy na pewno chcesz zmienić wybrane ograniczenia dla wybranego użytkownika(ów)?" -#: cps/admin.py:588 +#: cps/admin.py:607 msgid "Are you sure you want to change the selected visibility restrictions for the selected user(s)?" msgstr "Czy na pewno chcesz zmienić wybrane ograniczenia widoczności dla wybranego użytkownika(ów)?" -#: cps/admin.py:590 +#: cps/admin.py:610 msgid "Are you sure you want to change shelf sync behavior for the selected user(s)?" msgstr "Czy na pewno chcesz zmienić zachowanie synchronizacji półek dla wybranego użytkownika(ów)?" -#: cps/admin.py:592 +#: cps/admin.py:612 msgid "Are you sure you want to change Calibre library location?" msgstr "Czy na pewno chcesz zmienić lokalizację biblioteki Calibre?" -#: cps/admin.py:594 +#: cps/admin.py:614 msgid "Are you sure you want delete Calibre-Web's sync database to force a full sync with your Kobo Reader?" msgstr "" -#: cps/admin.py:743 +#: cps/admin.py:764 #, fuzzy msgid "Tag not found" msgstr "Nie znaleziono znacznika" -#: cps/admin.py:755 +#: cps/admin.py:776 msgid "Invalid Action" msgstr "Nieprawidłowe działanie" -#: cps/admin.py:871 cps/admin.py:877 cps/admin.py:887 cps/admin.py:897 +#: cps/admin.py:893 cps/admin.py:899 cps/admin.py:909 cps/admin.py:919 #: cps/templates/modal_dialogs.html:29 cps/templates/user_table.html:41 #: cps/templates/user_table.html:58 msgid "Deny" msgstr "Zabroń" -#: cps/admin.py:873 cps/admin.py:879 cps/admin.py:889 cps/admin.py:899 +#: cps/admin.py:895 cps/admin.py:901 cps/admin.py:911 cps/admin.py:921 #: cps/templates/modal_dialogs.html:28 cps/templates/user_table.html:44 #: cps/templates/user_table.html:61 msgid "Allow" msgstr "Zezwalaj" -#: cps/admin.py:913 +#: cps/admin.py:936 msgid "{} sync entries deleted" msgstr "" -#: cps/admin.py:1036 +#: cps/admin.py:1059 msgid "client_secrets.json Is Not Configured For Web Application" msgstr "client_secrets.json nie został skonfigurowany dla aplikacji webowej" -#: cps/admin.py:1081 +#: cps/admin.py:1104 msgid "Logfile Location is not Valid, Please Enter Correct Path" msgstr "Lokalizacja pliku dziennika jest nieprawidłowa, wprowadź poprawną ścieżkę" -#: cps/admin.py:1087 +#: cps/admin.py:1110 msgid "Access Logfile Location is not Valid, Please Enter Correct Path" msgstr "Lokalizacja pliku dziennika dostępu jest nieprawidłowa, wprowadź poprawną ścieżkę" -#: cps/admin.py:1117 +#: cps/admin.py:1140 msgid "Please Enter a LDAP Provider, Port, DN and User Object Identifier" msgstr "Wprowadź dostawcę LDAP, port, nazwę wyróżniającą i identyfikator obiektu użytkownika" -#: cps/admin.py:1123 +#: cps/admin.py:1146 msgid "Please Enter a LDAP Service Account and Password" msgstr "Proszę wprowadzić konto i hasło usługi LDAP" -#: cps/admin.py:1126 +#: cps/admin.py:1149 msgid "Please Enter a LDAP Service Account" msgstr "Proszę wprowadzić konto usługi LDAP" -#: cps/admin.py:1131 +#: cps/admin.py:1154 #, python-format msgid "LDAP Group Object Filter Needs to Have One \"%s\" Format Identifier" msgstr "Filtr obiektów grupy LDAP musi mieć jeden identyfikator formatu \"% s\"" -#: cps/admin.py:1133 +#: cps/admin.py:1156 msgid "LDAP Group Object Filter Has Unmatched Parenthesis" msgstr "Filtr obiektów grupy LDAP ma niedopasowany nawias" -#: cps/admin.py:1137 +#: cps/admin.py:1160 #, python-format msgid "LDAP User Object Filter needs to Have One \"%s\" Format Identifier" msgstr "Filtr obiektów użytkownika LDAP musi mieć jeden identyfikator formatu \"% s\"" -#: cps/admin.py:1139 +#: cps/admin.py:1162 msgid "LDAP User Object Filter Has Unmatched Parenthesis" msgstr "Filtr obiektów użytkownika LDAP ma niedopasowany nawias" -#: cps/admin.py:1146 +#: cps/admin.py:1169 #, python-format msgid "LDAP Member User Filter needs to Have One \"%s\" Format Identifier" msgstr "Filtr użytkownika członka LDAP musi mieć jedno \"%s\" identyfikator formatu" -#: cps/admin.py:1148 +#: cps/admin.py:1171 msgid "LDAP Member User Filter Has Unmatched Parenthesis" msgstr "Filtr użytkownika członka LDAP ma niedopasowane nawiasy" -#: cps/admin.py:1155 +#: cps/admin.py:1178 msgid "LDAP CACertificate, Certificate or Key Location is not Valid, Please Enter Correct Path" msgstr "Główny urząd certyfikatu LDAP, Certyfikat lub Lokalizacja Klucza nie jest prawidłowa, Proszę wprowadzić poprawną ścieżkę" -#: cps/admin.py:1197 cps/admin.py:1308 cps/admin.py:1405 cps/admin.py:1521 -#: cps/admin.py:1590 cps/shelf.py:100 cps/shelf.py:160 cps/shelf.py:203 -#: cps/shelf.py:279 cps/shelf.py:341 cps/shelf.py:376 cps/shelf.py:451 -msgid "Settings DB is not Writeable" -msgstr "Ustawienia Bazy Danych nie są zapisywalne" - -#: cps/admin.py:1208 -msgid "DB Location is not Valid, Please Enter Correct Path" -msgstr "Lokalizacja bazy danych jest nieprawidłowa, wprowadź poprawną ścieżkę" - -#: cps/admin.py:1223 -msgid "DB is not Writeable" -msgstr "Baza danych nie jest zapisywalna" - -#: cps/admin.py:1235 -msgid "Keyfile Location is not Valid, Please Enter Correct Path" -msgstr "Lokalizacja pliku klucza jest nieprawidłowa, wprowadź poprawną ścieżkę" - -#: cps/admin.py:1239 -msgid "Certfile Location is not Valid, Please Enter Correct Path" -msgstr "Lokalizacja pliku certyfikatu jest nieprawidłowa, wprowadź poprawną ścieżkę" - -#: cps/admin.py:1346 -#, fuzzy -msgid "Database Settings updated" -msgstr "Zaktualizowano ustawienia serwera poczty e-mail" - -#: cps/admin.py:1354 -msgid "Database Configuration" -msgstr "Konfiguracja bazy danych" - -#: cps/admin.py:1370 cps/web.py:1479 -msgid "Please fill out all fields!" -msgstr "Proszę wypełnić wszystkie pola!" - -#: cps/admin.py:1378 -msgid "E-mail is not from valid domain" -msgstr "E-mail nie pochodzi z prawidłowej domeny" - -#: cps/admin.py:1384 cps/admin.py:1543 -msgid "Add new user" -msgstr "Dodaj nowego użytkownika" - -#: cps/admin.py:1395 -#, python-format -msgid "User '%(user)s' created" -msgstr "Użytkownik '%(user)s' został utworzony" - -#: cps/admin.py:1401 -msgid "Found an existing account for this e-mail address or name." -msgstr "Znaleziono istniejące konto dla tego adresu e-mail lub nazwy." - -#: cps/admin.py:1430 -#, python-format -msgid "User '%(nick)s' deleted" -msgstr "Użytkownik '%(nick)s' został usunięty" - -#: cps/admin.py:1432 cps/admin.py:1433 -#, fuzzy -msgid "Can't delete Guest User" -msgstr "Nie można usunąć użytkownika gościa" - -#: cps/admin.py:1436 -msgid "No admin user remaining, can't delete user" -msgstr "Nie można usunąć użytkownika. Brak na serwerze innego konta z prawami administratora" - -#: cps/admin.py:1509 cps/admin.py:1634 -#, python-format -msgid "Edit User %(nick)s" -msgstr "Edytuj użytkownika %(nick)s" - -#: cps/admin.py:1513 -#, python-format -msgid "User '%(nick)s' updated" -msgstr "Użytkownik '%(nick)s' został zaktualizowany" - -#: cps/admin.py:1517 cps/admin.py:1649 cps/web.py:1504 cps/web.py:1564 -msgid "An unknown error occurred. Please try again later." -msgstr "Wystąpił nieznany błąd. Spróbuj ponownie później." - -#: cps/admin.py:1552 cps/templates/admin.html:98 -msgid "Edit E-mail Server Settings" -msgstr "Zmień ustawienia SMTP" - -#: cps/admin.py:1571 -msgid "Gmail Account Verification Successful" -msgstr "Weryfikacja konta Gmail przebiegła pomyślnie" - -#: cps/admin.py:1597 -#, fuzzy, python-format -msgid "Test e-mail queued for sending to %(email)s, please check Tasks for result" -msgstr "Testowy e-mail czeka w kolejce do wysłania do %(email)s, sprawdź zadania, aby uzyskać wynik" - -#: cps/admin.py:1600 -#, python-format -msgid "There was an error sending the Test e-mail: %(res)s" -msgstr "Wystąpił błąd podczas wysyłania e-maila testowego: %(res)s" - -#: cps/admin.py:1602 -msgid "Please configure your e-mail address first..." -msgstr "Najpierw skonfiguruj swój adres e-mail..." - -#: cps/admin.py:1604 -msgid "E-mail server settings updated" -msgstr "Zaktualizowano ustawienia serwera poczty e-mail" - -# ??? -#: cps/admin.py:1646 -#, python-format -msgid "Password for user %(user)s reset" -msgstr "Zrestartowano hasło użytkownika %(user)s" - -#: cps/admin.py:1652 cps/web.py:1444 -msgid "Please configure the SMTP mail settings first..." -msgstr "Proszę najpierw skonfigurować ustawienia SMTP poczty e-mail..." - -#: cps/admin.py:1663 -msgid "Logfile viewer" -msgstr "Przeglądanie dziennika" - -#: cps/admin.py:1729 -msgid "Requesting update package" -msgstr "Żądanie o pakiet aktualizacji" - -#: cps/admin.py:1730 -msgid "Downloading update package" -msgstr "Pobieranie pakietu aktualizacji" - -#: cps/admin.py:1731 -msgid "Unzipping update package" -msgstr "Rozpakowywanie pakietu aktualizacji" - -# ??? -#: cps/admin.py:1732 -msgid "Replacing files" -msgstr "Zastępowanie plików" - -#: cps/admin.py:1733 -msgid "Database connections are closed" -msgstr "Połączenia z bazą danych zostały zakończone" - -#: cps/admin.py:1734 -msgid "Stopping server" -msgstr "Zatrzymywanie serwera" - -#: cps/admin.py:1735 -msgid "Update finished, please press okay and reload page" -msgstr "Aktualizacja zakończona, proszę nacisnąć OK i odświeżyć stronę" - -#: cps/admin.py:1736 cps/admin.py:1737 cps/admin.py:1738 cps/admin.py:1739 -#: cps/admin.py:1740 cps/admin.py:1741 -msgid "Update failed:" -msgstr "Aktualizacja nieudana:" - -#: cps/admin.py:1736 cps/updater.py:385 cps/updater.py:595 cps/updater.py:597 -msgid "HTTP Error" -msgstr "Błąd HTTP" - -#: cps/admin.py:1737 cps/updater.py:387 cps/updater.py:599 -msgid "Connection error" -msgstr "Błąd połączenia" - -#: cps/admin.py:1738 cps/updater.py:389 cps/updater.py:601 -msgid "Timeout while establishing connection" -msgstr "Przekroczono limit czasu podczas nawiązywania połączenia" - -#: cps/admin.py:1739 cps/updater.py:391 cps/updater.py:603 -msgid "General error" -msgstr "Błąd ogólny" - -#: cps/admin.py:1740 -#, fuzzy -msgid "Update file could not be saved in temp dir" -msgstr "Plik aktualizacji nie mógł zostać zapisany w katalogu tymczasowym" - -#: cps/admin.py:1741 -msgid "Files could not be replaced during update" -msgstr "" - -#: cps/admin.py:1765 -#, fuzzy -msgid "Failed to extract at least One LDAP User" -msgstr "Błąd przy tworzeniu przynajmniej jednego użytkownika LDAP" - -#: cps/admin.py:1810 -msgid "Failed to Create at Least One LDAP User" -msgstr "Błąd przy tworzeniu przynajmniej jednego użytkownika LDAP" - -#: cps/admin.py:1823 -#, python-format -msgid "Error: %(ldaperror)s" -msgstr "Błąd: %(ldaperror)s" - -#: cps/admin.py:1827 -msgid "Error: No user returned in response of LDAP server" -msgstr "Błąd. LDAP nie zwrócił żadnego użytkownika" - -#: cps/admin.py:1860 -msgid "At Least One LDAP User Not Found in Database" -msgstr "Przynajmniej jeden użytkownik LDAP nie został znaleziony w bazie danych" - -#: cps/admin.py:1862 -msgid "{} User Successfully Imported" -msgstr "{} Użytkownik pomyślnie zaimportowany" - -#: cps/converter.py:30 -msgid "not configured" -msgstr "nie skonfigurowane" - -#: cps/converter.py:32 -msgid "Execution permissions missing" -msgstr "Brak uprawnienia do wykonywania pliku" - -#: cps/db.py:651 cps/web.py:667 cps/web.py:1155 -#, python-format -msgid "Custom Column No.%(column)d is not existing in calibre database" -msgstr "Niestandardowa kolumna No.%(column)d nie istnieje w bazie calibre" - -#: cps/editbooks.py:300 cps/editbooks.py:302 -msgid "Book Format Successfully Deleted" -msgstr "Plik książki w wybranym formacie został usunięty" - -#: cps/editbooks.py:309 cps/editbooks.py:311 -msgid "Book Successfully Deleted" -msgstr "Książka została usunięta" - -#: cps/editbooks.py:361 -msgid "You are missing permissions to delete books" -msgstr "" - -#: cps/editbooks.py:376 cps/editbooks.py:763 cps/web.py:523 cps/web.py:1703 -#: cps/web.py:1744 cps/web.py:1811 -msgid "Oops! Selected book title is unavailable. File does not exist or is not accessible" -msgstr "Błąd otwierania e-booka. Plik nie istnieje lub jest niedostępny" - -#: cps/editbooks.py:410 -msgid "edit metadata" -msgstr "edytuj metadane" - -#: cps/editbooks.py:458 -#, python-format -msgid "%(seriesindex)s is not a valid number, skipping" -msgstr "%(seriesindex)s nie jest poprawną liczbą, pomijanie" - -#: cps/editbooks.py:494 cps/editbooks.py:958 -#, fuzzy, python-format -msgid "'%(langname)s' is not a valid language" -msgstr "%(langname)s nie jest prawidłowym językiem" - -#: cps/editbooks.py:634 cps/editbooks.py:985 -#, python-format -msgid "File extension '%(ext)s' is not allowed to be uploaded to this server" -msgstr "Rozszerzenie pliku '%(ext)s' nie jest dozwolone do wysłania na ten serwer" - -#: cps/editbooks.py:638 cps/editbooks.py:989 -msgid "File to be uploaded must have an extension" -msgstr "Plik do wysłania musi mieć rozszerzenie" - -#: cps/editbooks.py:650 -#, python-format -msgid "Failed to create path %(path)s (Permission denied)." -msgstr "Nie udało się utworzyć łącza %(path)s (Odmowa dostępu)." - -#: cps/editbooks.py:655 -#, python-format -msgid "Failed to store file %(file)s." -msgstr "Nie można zapisać pliku %(file)s." - -#: cps/editbooks.py:673 cps/editbooks.py:1076 cps/web.py:1664 +#: cps/admin.py:1223 cps/admin.py:1339 cps/admin.py:1437 cps/admin.py:1554 +#: cps/admin.py:1623 cps/editbooks.py:678 cps/editbooks.py:882 +#: cps/editbooks.py:1130 cps/shelf.py:100 cps/shelf.py:160 cps/shelf.py:203 +#: cps/shelf.py:278 cps/shelf.py:343 cps/shelf.py:380 cps/shelf.py:456 +#: cps/web.py:1742 #, python-format msgid "Database error: %(error)s." msgstr "Błąd bazy danych: %(error)s." -#: cps/editbooks.py:678 +#: cps/admin.py:1235 +msgid "DB Location is not Valid, Please Enter Correct Path" +msgstr "Lokalizacja bazy danych jest nieprawidłowa, wprowadź poprawną ścieżkę" + +#: cps/admin.py:1253 +msgid "DB is not Writeable" +msgstr "Baza danych nie jest zapisywalna" + +#: cps/admin.py:1266 +msgid "Keyfile Location is not Valid, Please Enter Correct Path" +msgstr "Lokalizacja pliku klucza jest nieprawidłowa, wprowadź poprawną ścieżkę" + +#: cps/admin.py:1270 +msgid "Certfile Location is not Valid, Please Enter Correct Path" +msgstr "Lokalizacja pliku certyfikatu jest nieprawidłowa, wprowadź poprawną ścieżkę" + +#: cps/admin.py:1378 +#, fuzzy +msgid "Database Settings updated" +msgstr "Zaktualizowano ustawienia serwera poczty e-mail" + +#: cps/admin.py:1386 +msgid "Database Configuration" +msgstr "Konfiguracja bazy danych" + +#: cps/admin.py:1402 cps/web.py:1557 +msgid "Please fill out all fields!" +msgstr "Proszę wypełnić wszystkie pola!" + +#: cps/admin.py:1410 +msgid "E-mail is not from valid domain" +msgstr "E-mail nie pochodzi z prawidłowej domeny" + +#: cps/admin.py:1416 cps/admin.py:1576 +msgid "Add new user" +msgstr "Dodaj nowego użytkownika" + +#: cps/admin.py:1427 +#, python-format +msgid "User '%(user)s' created" +msgstr "Użytkownik '%(user)s' został utworzony" + +#: cps/admin.py:1433 +msgid "Found an existing account for this e-mail address or name." +msgstr "Znaleziono istniejące konto dla tego adresu e-mail lub nazwy." + +#: cps/admin.py:1463 +#, python-format +msgid "User '%(nick)s' deleted" +msgstr "Użytkownik '%(nick)s' został usunięty" + +#: cps/admin.py:1465 cps/admin.py:1466 +#, fuzzy +msgid "Can't delete Guest User" +msgstr "Nie można usunąć użytkownika gościa" + +#: cps/admin.py:1469 +msgid "No admin user remaining, can't delete user" +msgstr "Nie można usunąć użytkownika. Brak na serwerze innego konta z prawami administratora" + +#: cps/admin.py:1542 cps/admin.py:1667 +#, python-format +msgid "Edit User %(nick)s" +msgstr "Edytuj użytkownika %(nick)s" + +#: cps/admin.py:1546 +#, python-format +msgid "User '%(nick)s' updated" +msgstr "Użytkownik '%(nick)s' został zaktualizowany" + +#: cps/admin.py:1550 cps/admin.py:1682 cps/web.py:1582 cps/web.py:1642 +msgid "An unknown error occurred. Please try again later." +msgstr "Wystąpił nieznany błąd. Spróbuj ponownie później." + +#: cps/admin.py:1585 cps/templates/admin.html:100 +msgid "Edit E-mail Server Settings" +msgstr "Zmień ustawienia SMTP" + +#: cps/admin.py:1604 +msgid "Gmail Account Verification Successful" +msgstr "Weryfikacja konta Gmail przebiegła pomyślnie" + +#: cps/admin.py:1630 +#, fuzzy, python-format +msgid "Test e-mail queued for sending to %(email)s, please check Tasks for result" +msgstr "Testowy e-mail czeka w kolejce do wysłania do %(email)s, sprawdź zadania, aby uzyskać wynik" + +#: cps/admin.py:1633 +#, python-format +msgid "There was an error sending the Test e-mail: %(res)s" +msgstr "Wystąpił błąd podczas wysyłania e-maila testowego: %(res)s" + +#: cps/admin.py:1635 +msgid "Please configure your e-mail address first..." +msgstr "Najpierw skonfiguruj swój adres e-mail..." + +#: cps/admin.py:1637 +msgid "E-mail server settings updated" +msgstr "Zaktualizowano ustawienia serwera poczty e-mail" + +# ??? +#: cps/admin.py:1679 +#, python-format +msgid "Password for user %(user)s reset" +msgstr "Zrestartowano hasło użytkownika %(user)s" + +#: cps/admin.py:1685 cps/web.py:1522 +msgid "Please configure the SMTP mail settings first..." +msgstr "Proszę najpierw skonfigurować ustawienia SMTP poczty e-mail..." + +#: cps/admin.py:1696 +msgid "Logfile viewer" +msgstr "Przeglądanie dziennika" + +#: cps/admin.py:1762 +msgid "Requesting update package" +msgstr "Żądanie o pakiet aktualizacji" + +#: cps/admin.py:1763 +msgid "Downloading update package" +msgstr "Pobieranie pakietu aktualizacji" + +#: cps/admin.py:1764 +msgid "Unzipping update package" +msgstr "Rozpakowywanie pakietu aktualizacji" + +# ??? +#: cps/admin.py:1765 +msgid "Replacing files" +msgstr "Zastępowanie plików" + +#: cps/admin.py:1766 +msgid "Database connections are closed" +msgstr "Połączenia z bazą danych zostały zakończone" + +#: cps/admin.py:1767 +msgid "Stopping server" +msgstr "Zatrzymywanie serwera" + +#: cps/admin.py:1768 +msgid "Update finished, please press okay and reload page" +msgstr "Aktualizacja zakończona, proszę nacisnąć OK i odświeżyć stronę" + +#: cps/admin.py:1769 cps/admin.py:1770 cps/admin.py:1771 cps/admin.py:1772 +#: cps/admin.py:1773 cps/admin.py:1774 +msgid "Update failed:" +msgstr "Aktualizacja nieudana:" + +#: cps/admin.py:1769 cps/updater.py:384 cps/updater.py:619 cps/updater.py:621 +msgid "HTTP Error" +msgstr "Błąd HTTP" + +#: cps/admin.py:1770 cps/updater.py:386 cps/updater.py:623 +msgid "Connection error" +msgstr "Błąd połączenia" + +#: cps/admin.py:1771 cps/updater.py:388 cps/updater.py:625 +msgid "Timeout while establishing connection" +msgstr "Przekroczono limit czasu podczas nawiązywania połączenia" + +#: cps/admin.py:1772 cps/updater.py:390 cps/updater.py:627 +msgid "General error" +msgstr "Błąd ogólny" + +#: cps/admin.py:1773 +#, fuzzy +msgid "Update file could not be saved in temp dir" +msgstr "Plik aktualizacji nie mógł zostać zapisany w katalogu tymczasowym" + +#: cps/admin.py:1774 +msgid "Files could not be replaced during update" +msgstr "" + +#: cps/admin.py:1798 +#, fuzzy +msgid "Failed to extract at least One LDAP User" +msgstr "Błąd przy tworzeniu przynajmniej jednego użytkownika LDAP" + +#: cps/admin.py:1843 +msgid "Failed to Create at Least One LDAP User" +msgstr "Błąd przy tworzeniu przynajmniej jednego użytkownika LDAP" + +#: cps/admin.py:1856 +#, python-format +msgid "Error: %(ldaperror)s" +msgstr "Błąd: %(ldaperror)s" + +#: cps/admin.py:1860 +msgid "Error: No user returned in response of LDAP server" +msgstr "Błąd. LDAP nie zwrócił żadnego użytkownika" + +#: cps/admin.py:1893 +msgid "At Least One LDAP User Not Found in Database" +msgstr "Przynajmniej jeden użytkownik LDAP nie został znaleziony w bazie danych" + +#: cps/admin.py:1895 +msgid "{} User Successfully Imported" +msgstr "{} Użytkownik pomyślnie zaimportowany" + +#: cps/converter.py:30 +msgid "not installed" +msgstr "nie zainstalowane" + +#: cps/converter.py:31 +msgid "Execution permissions missing" +msgstr "Brak uprawnienia do wykonywania pliku" + +#: cps/db.py:674 cps/web.py:710 cps/web.py:1222 +#, python-format +msgid "Custom Column No.%(column)d is not existing in calibre database" +msgstr "Niestandardowa kolumna No.%(column)d nie istnieje w bazie calibre" + +#: cps/db.py:917 cps/templates/config_edit.html:204 +#: cps/templates/config_view_edit.html:62 cps/templates/email_edit.html:41 +#: cps/web.py:551 cps/web.py:585 cps/web.py:646 cps/web.py:671 cps/web.py:1003 +#: cps/web.py:1032 cps/web.py:1066 cps/web.py:1093 cps/web.py:1132 +msgid "None" +msgstr "Brak" + +#: cps/editbooks.py:295 cps/editbooks.py:297 +msgid "Book Format Successfully Deleted" +msgstr "Plik książki w wybranym formacie został usunięty" + +#: cps/editbooks.py:304 cps/editbooks.py:306 +msgid "Book Successfully Deleted" +msgstr "Książka została usunięta" + +#: cps/editbooks.py:358 +msgid "You are missing permissions to delete books" +msgstr "" + +#: cps/editbooks.py:373 cps/editbooks.py:765 cps/web.py:518 cps/web.py:1783 +#: cps/web.py:1825 cps/web.py:1870 +msgid "Oops! Selected book title is unavailable. File does not exist or is not accessible" +msgstr "Błąd otwierania e-booka. Plik nie istnieje lub jest niedostępny" + +#: cps/editbooks.py:408 +msgid "edit metadata" +msgstr "edytuj metadane" + +#: cps/editbooks.py:457 +#, python-format +msgid "%(seriesindex)s is not a valid number, skipping" +msgstr "%(seriesindex)s nie jest poprawną liczbą, pomijanie" + +#: cps/editbooks.py:493 cps/editbooks.py:1001 +#, fuzzy, python-format +msgid "'%(langname)s' is not a valid language" +msgstr "%(langname)s nie jest prawidłowym językiem" + +#: cps/editbooks.py:634 +msgid "User has no rights to upload additional file formats" +msgstr "" + +#: cps/editbooks.py:639 cps/editbooks.py:1029 +#, python-format +msgid "File extension '%(ext)s' is not allowed to be uploaded to this server" +msgstr "Rozszerzenie pliku '%(ext)s' nie jest dozwolone do wysłania na ten serwer" + +#: cps/editbooks.py:643 cps/editbooks.py:1033 +msgid "File to be uploaded must have an extension" +msgstr "Plik do wysłania musi mieć rozszerzenie" + +#: cps/editbooks.py:655 +#, python-format +msgid "Failed to create path %(path)s (Permission denied)." +msgstr "Nie udało się utworzyć łącza %(path)s (Odmowa dostępu)." + +#: cps/editbooks.py:660 +#, python-format +msgid "Failed to store file %(file)s." +msgstr "Nie można zapisać pliku %(file)s." + +#: cps/editbooks.py:683 #, python-format msgid "File format %(ext)s added to %(book)s" msgstr "Format pliku %(ext)s dodany do %(book)s" -#: cps/editbooks.py:814 +#: cps/editbooks.py:697 cps/editbooks.py:809 +msgid "User has no rights to upload cover" +msgstr "" + +#: cps/editbooks.py:828 msgid "Identifiers are not Case Sensitive, Overwriting Old Identifier" msgstr "W identyfikatorach nie jest rozróżniana wielkość liter, nadpisywanie starego identyfikatora" -#: cps/editbooks.py:848 +#: cps/editbooks.py:869 msgid "Metadata successfully updated" msgstr "Metadane zostały pomyślnie zaktualizowane" -#: cps/editbooks.py:861 -msgid "Error editing book, please check logfile for details" -msgstr "Błąd podczas edycji książki, sprawdź plik dziennika, aby uzyskać szczegółowe informacje" +#: cps/editbooks.py:887 +msgid "Error editing book: {}" +msgstr "" -#: cps/editbooks.py:899 +#: cps/editbooks.py:951 msgid "Uploaded book probably exists in the library, consider to change before upload new: " msgstr "Wysłana książka prawdopodobnie istnieje w bibliotece, rozważ zmianę przed przesłaniem nowej: " -#: cps/editbooks.py:997 +#: cps/editbooks.py:1041 #, python-format msgid "File %(filename)s could not saved to temp dir" msgstr "Nie można zapisać pliku %(filename)s w katalogu tymczasowym" -#: cps/editbooks.py:1016 +#: cps/editbooks.py:1061 #, python-format msgid "Failed to Move Cover File %(file)s: %(error)s" msgstr "Nie udało się przenieść pliku okładki %(file)s:%(error)s" -#: cps/editbooks.py:1063 +#: cps/editbooks.py:1117 #, python-format msgid "File %(file)s uploaded" msgstr "Wysłano plik %(file)s" -#: cps/editbooks.py:1088 +#: cps/editbooks.py:1143 msgid "Source or destination format for conversion missing" msgstr "Brak formatu źródłowego lub docelowego do konwersji" -#: cps/editbooks.py:1096 +#: cps/editbooks.py:1151 #, python-format msgid "Book successfully queued for converting to %(book_format)s" msgstr "Książka została pomyślnie umieszczona w zadaniach do konwersji %(book_format)s" -#: cps/editbooks.py:1100 +#: cps/editbooks.py:1155 #, python-format msgid "There was an error converting this book: %(res)s" msgstr "Podczas konwersji książki wystąpił błąd: %(res)s" @@ -612,176 +615,193 @@ msgstr "Konfiguracja Google Drive nie została zakończona, spróbuj dezaktywowa msgid "Callback domain is not verified, please follow steps to verify domain in google developer console" msgstr "Zwrotna domena nie jest zweryfikowana, proszę zweryfikowania domenę w konsoli deweloperskiej google" -#: cps/helper.py:77 +#: cps/helper.py:81 #, python-format msgid "%(format)s format not found for book id: %(book)d" msgstr "Nie znaleziono formatu %(format)s dla id książki: %(book)d" -#: cps/helper.py:83 cps/tasks/convert.py:73 +#: cps/helper.py:87 cps/tasks/convert.py:75 #, python-format msgid "%(format)s not found on Google Drive: %(fn)s" msgstr "Nie znaleziono %(format)s na Google Drive: %(fn)s" -#: cps/helper.py:88 +#: cps/helper.py:92 #, python-format msgid "%(format)s not found: %(fn)s" msgstr "%(format)s nie znaleziono: %(fn)s" -#: cps/helper.py:93 cps/helper.py:217 cps/templates/detail.html:41 +#: cps/helper.py:97 cps/helper.py:221 cps/templates/detail.html:41 #: cps/templates/detail.html:45 msgid "Send to Kindle" msgstr "Wyślij do Kindle" -#: cps/helper.py:94 cps/helper.py:111 cps/helper.py:219 +#: cps/helper.py:98 cps/helper.py:115 cps/helper.py:223 msgid "This e-mail has been sent via Calibre-Web." msgstr "Ten e-mail został wysłany za pośrednictwem Calibre-Web." -#: cps/helper.py:109 +#: cps/helper.py:113 msgid "Calibre-Web test e-mail" msgstr "Testowy e-mail Calibre-Web" -#: cps/helper.py:110 +#: cps/helper.py:114 msgid "Test e-mail" msgstr "Testowy e-mail" # ??? -#: cps/helper.py:127 +#: cps/helper.py:131 msgid "Get Started with Calibre-Web" msgstr "Zacznij korzystać z Calibre-Web" -#: cps/helper.py:132 +#: cps/helper.py:136 #, python-format msgid "Registration e-mail for user: %(name)s" msgstr "Rejestracja e-mail dla użytkownika: %(name)s" -#: cps/helper.py:143 cps/helper.py:149 +#: cps/helper.py:147 cps/helper.py:153 #, python-format msgid "Convert %(orig)s to %(format)s and send to Kindle" msgstr "Konwertuj %(orig)s do %(format)s i wyślij do Kindle" -#: cps/helper.py:168 cps/helper.py:172 cps/helper.py:176 +#: cps/helper.py:172 cps/helper.py:176 cps/helper.py:180 #, python-format msgid "Send %(format)s to Kindle" msgstr "Wyślij %(format)s do Kindle" -#: cps/helper.py:216 cps/tasks/convert.py:90 +#: cps/helper.py:220 cps/tasks/convert.py:92 #, fuzzy, python-format msgid "%(book)s send to Kindle" msgstr "Wyślij do Kindle" # ??? -#: cps/helper.py:221 +#: cps/helper.py:225 msgid "The requested file could not be read. Maybe wrong permissions?" msgstr "Żądany plik nie mógł zostać odczytany. Może brakuje uprawnień?" -#: cps/helper.py:313 +#: cps/helper.py:353 +msgid "Read status could not set: {}" +msgstr "" + +#: cps/helper.py:376 #, python-format msgid "Deleting bookfolder for book %(id)s failed, path has subfolders: %(path)s" msgstr "Usuwanie folderu książki dla książki %(id)s nie powiodło się, ścieżka ma podfoldery: %(path)s" -#: cps/helper.py:319 +#: cps/helper.py:382 #, python-format msgid "Deleting book %(id)s failed: %(message)s" msgstr "Usuwanie książki %(id)s zakończyło się błędem: %(message)s" -#: cps/helper.py:330 +#: cps/helper.py:393 #, fuzzy, python-format msgid "Deleting book %(id)s from database only, book path in database not valid: %(path)s" msgstr "Usuwanie książki %(id)s, ścieżka książki jest niepoprawna: %(path)s" -#: cps/helper.py:385 -#, python-format -msgid "Rename title from: '%(src)s' to '%(dest)s' failed with error: %(error)s" +#: cps/helper.py:458 +#, fuzzy, python-format +msgid "Rename author from: '%(src)s' to '%(dest)s' failed with error: %(error)s" msgstr "Zmiana nazwy tytułu z: „%(src)s” na „%(dest)s” zakończyła się błędem: %(error)s" -#: cps/helper.py:400 -#, python-format -msgid "Rename file in path '%(src)s' to '%(dest)s' failed with error: %(error)s" -msgstr "Zmiana nazwy pliku w ścieżce '%(src)s' na '%(dest)s' zakończyło się błędem: %(error)s" - -#: cps/helper.py:425 cps/helper.py:435 cps/helper.py:443 +#: cps/helper.py:529 cps/helper.py:538 #, python-format msgid "File %(file)s not found on Google Drive" msgstr "Nie znaleziono pliku %(file)s na Google Drive" -#: cps/helper.py:464 +#: cps/helper.py:572 +#, python-format +msgid "Rename title from: '%(src)s' to '%(dest)s' failed with error: %(error)s" +msgstr "Zmiana nazwy tytułu z: „%(src)s” na „%(dest)s” zakończyła się błędem: %(error)s" + +#: cps/helper.py:592 +msgid "Error in rename file in path: {}" +msgstr "" + +#: cps/helper.py:610 #, python-format msgid "Book path %(path)s not found on Google Drive" msgstr "Nie znaleziono ścieżki do książki %(path)s na Google Drive" -#: cps/helper.py:504 cps/web.py:1659 +#: cps/helper.py:651 cps/web.py:1737 msgid "Found an existing account for this e-mail address" msgstr "Znaleziono istniejące konto dla tego adresu e-mail" -#: cps/helper.py:512 +#: cps/helper.py:659 msgid "This username is already taken" msgstr "Nazwa użytkownika jest już zajęta" -#: cps/helper.py:522 +#: cps/helper.py:669 msgid "Invalid e-mail address format" msgstr "Nieprawidłowy format adresu e-mail" -#: cps/helper.py:595 +#: cps/helper.py:754 +msgid "Python modul 'advocate' is not installed but is needed for cover downloads" +msgstr "" + +#: cps/helper.py:767 msgid "Error Downloading Cover" msgstr "Błąd przy pobieraniu okładki" -#: cps/helper.py:598 +#: cps/helper.py:770 msgid "Cover Format Error" msgstr "Błędny format okładki" -#: cps/helper.py:608 +#: cps/helper.py:773 +msgid "You are not allowed to access localhost or the local network for cover uploads" +msgstr "" + +#: cps/helper.py:783 msgid "Failed to create path for cover" msgstr "Nie udało się utworzyć ścieżki dla okładki" -#: cps/helper.py:624 +#: cps/helper.py:799 msgid "Cover-file is not a valid image file, or could not be stored" msgstr "Plik okładki nie jest poprawnym plikiem obrazu lub nie mógł zostać zapisany" -#: cps/helper.py:635 +#: cps/helper.py:810 msgid "Only jpg/jpeg/png/webp/bmp files are supported as coverfile" msgstr "Jako plik okładki obsługiwane są tylko pliki jpg/jpeg/png/webp/bmp" -#: cps/helper.py:648 +#: cps/helper.py:822 msgid "Invalid cover file content" msgstr "" -#: cps/helper.py:652 +#: cps/helper.py:826 msgid "Only jpg/jpeg files are supported as coverfile" msgstr "Jako plik okładki dopuszczalne są jedynie pliki jpg/jpeg" -#: cps/helper.py:704 +#: cps/helper.py:878 msgid "Unrar binary file not found" msgstr "Plik wykonywalny programu unrar nie znaleziony" -#: cps/helper.py:715 +#: cps/helper.py:889 msgid "Error excecuting UnRar" msgstr "Błąd przy wykonywaniu unrar" -#: cps/helper.py:763 +#: cps/helper.py:937 msgid "Waiting" msgstr "Oczekiwanie" -#: cps/helper.py:765 +#: cps/helper.py:939 msgid "Failed" msgstr "Nieudane" -#: cps/helper.py:767 +#: cps/helper.py:941 msgid "Started" msgstr "Rozpoczynanie" -#: cps/helper.py:769 +#: cps/helper.py:943 msgid "Finished" msgstr "Zakończone" -#: cps/helper.py:771 +#: cps/helper.py:945 msgid "Unknown Status" msgstr "Ststus nieznany" -#: cps/kobo_auth.py:127 -msgid "PLease access calibre-web from non localhost to get valid api_endpoint for kobo device" +#: cps/kobo_auth.py:128 +#, fuzzy +msgid "Please access Calibre-Web from non localhost to get valid api_endpoint for kobo device" msgstr "Aby uzyskać prawidłowy api_endpoint dla urządzenia Kobo, należy skorzystać z dostępu do calibre-web spoza localhost" -#: cps/kobo_auth.py:130 cps/kobo_auth.py:158 +#: cps/kobo_auth.py:154 msgid "Kobo Setup" msgstr "Konfiguracja Kobo" @@ -791,7 +811,7 @@ msgstr "Konfiguracja Kobo" msgid "Register with %(provider)s" msgstr "Zarejestruj się %(provider)s" -#: cps/oauth_bb.py:138 cps/remotelogin.py:133 cps/web.py:1535 +#: cps/oauth_bb.py:138 cps/remotelogin.py:130 cps/web.py:1613 #, python-format msgid "you are now logged in as: '%(nickname)s'" msgstr "zalogowałeś się jako: '%(nickname)s'" @@ -852,163 +872,163 @@ msgstr "Błąd Google Oauth, proszę spróbować później." msgid "Google Oauth error: {}" msgstr "Błąd Google Oauth: {}" -#: cps/opds.py:384 +#: cps/opds.py:298 msgid "{} Stars" msgstr "{} Gwiazdek" -#: cps/remotelogin.py:65 cps/templates/layout.html:84 -#: cps/templates/login.html:4 cps/templates/login.html:21 cps/web.py:1584 +#: cps/remotelogin.py:62 cps/templates/layout.html:84 +#: cps/templates/login.html:4 cps/templates/login.html:21 cps/web.py:1662 msgid "Login" msgstr "Zaloguj się" -#: cps/remotelogin.py:77 cps/remotelogin.py:111 +#: cps/remotelogin.py:74 cps/remotelogin.py:108 msgid "Token not found" msgstr "Nie znaleziono tokenu" -#: cps/remotelogin.py:86 cps/remotelogin.py:119 +#: cps/remotelogin.py:83 cps/remotelogin.py:116 msgid "Token has expired" msgstr "Token wygasł" -#: cps/remotelogin.py:95 +#: cps/remotelogin.py:92 msgid "Success! Please return to your device" msgstr "Powodzenie! Wróć do swojego urządzenia" -#: cps/render_template.py:39 cps/web.py:416 +#: cps/render_template.py:41 cps/web.py:407 msgid "Books" msgstr "Książki" -#: cps/render_template.py:41 +#: cps/render_template.py:43 msgid "Show recent books" msgstr "Pokaż menu ostatnio dodanych książek" -#: cps/render_template.py:42 cps/templates/index.xml:25 +#: cps/render_template.py:44 cps/templates/index.xml:25 msgid "Hot Books" msgstr "Najpopularniejsze" -#: cps/render_template.py:44 +#: cps/render_template.py:46 msgid "Show Hot Books" msgstr "Pokaż menu najpopularniejszych książek" -#: cps/render_template.py:46 cps/render_template.py:51 +#: cps/render_template.py:48 cps/render_template.py:53 msgid "Downloaded Books" msgstr "Pobrane książki" -#: cps/render_template.py:48 cps/render_template.py:53 +#: cps/render_template.py:50 cps/render_template.py:55 #: cps/templates/user_table.html:167 msgid "Show Downloaded Books" msgstr "Pokaż pobrane książki" -#: cps/render_template.py:56 cps/templates/index.xml:32 cps/web.py:430 +#: cps/render_template.py:58 cps/templates/index.xml:32 cps/web.py:422 msgid "Top Rated Books" msgstr "Najwyżej ocenione" -#: cps/render_template.py:58 cps/templates/user_table.html:161 +#: cps/render_template.py:60 cps/templates/user_table.html:161 msgid "Show Top Rated Books" msgstr "Pokaż menu najwyżej ocenionych książek" -#: cps/render_template.py:59 cps/templates/index.xml:54 -#: cps/templates/index.xml:58 cps/web.py:676 +#: cps/render_template.py:61 cps/templates/index.xml:54 +#: cps/templates/index.xml:58 cps/web.py:729 msgid "Read Books" msgstr "Przeczytane" -#: cps/render_template.py:61 +#: cps/render_template.py:63 msgid "Show read and unread" msgstr "Pokaż menu przeczytane i nieprzeczytane" -#: cps/render_template.py:63 cps/templates/index.xml:61 -#: cps/templates/index.xml:65 cps/web.py:679 +#: cps/render_template.py:65 cps/templates/index.xml:61 +#: cps/templates/index.xml:65 cps/web.py:732 msgid "Unread Books" msgstr "Nieprzeczytane" -#: cps/render_template.py:65 +#: cps/render_template.py:67 msgid "Show unread" msgstr "Pokaż nieprzeczytane" -#: cps/render_template.py:66 +#: cps/render_template.py:68 msgid "Discover" msgstr "Odkrywaj" -#: cps/render_template.py:68 cps/templates/index.xml:50 +#: cps/render_template.py:70 cps/templates/index.xml:50 #: cps/templates/user_table.html:162 msgid "Show Random Books" msgstr "Pokazuj losowe książki" -#: cps/render_template.py:69 cps/templates/book_table.html:67 -#: cps/templates/index.xml:83 cps/web.py:1041 +#: cps/render_template.py:71 cps/templates/book_table.html:67 +#: cps/templates/index.xml:83 cps/web.py:1135 msgid "Categories" msgstr "Kategorie" -#: cps/render_template.py:71 cps/templates/user_table.html:158 +#: cps/render_template.py:73 cps/templates/user_table.html:158 msgid "Show category selection" msgstr "Pokaż menu wyboru kategorii" -#: cps/render_template.py:72 cps/templates/book_edit.html:90 +#: cps/render_template.py:74 cps/templates/book_edit.html:90 #: cps/templates/book_table.html:68 cps/templates/index.xml:90 -#: cps/templates/search_form.html:69 cps/web.py:948 cps/web.py:959 +#: cps/templates/search_form.html:69 cps/web.py:1034 cps/web.py:1041 msgid "Series" msgstr "Cykle" -#: cps/render_template.py:74 cps/templates/user_table.html:157 +#: cps/render_template.py:76 cps/templates/user_table.html:157 msgid "Show series selection" msgstr "Pokaż menu wyboru cyklu" -#: cps/render_template.py:75 cps/templates/book_table.html:66 +#: cps/render_template.py:77 cps/templates/book_table.html:66 #: cps/templates/index.xml:69 msgid "Authors" msgstr "Autorzy" -#: cps/render_template.py:77 cps/templates/user_table.html:160 +#: cps/render_template.py:79 cps/templates/user_table.html:160 msgid "Show author selection" msgstr "Pokaż menu wyboru autora" -#: cps/render_template.py:79 cps/templates/book_table.html:72 -#: cps/templates/index.xml:76 cps/web.py:925 +#: cps/render_template.py:81 cps/templates/book_table.html:72 +#: cps/templates/index.xml:76 cps/web.py:1006 msgid "Publishers" msgstr "Wydawcy" -#: cps/render_template.py:81 cps/templates/user_table.html:163 +#: cps/render_template.py:83 cps/templates/user_table.html:163 msgid "Show publisher selection" msgstr "Pokaż menu wyboru wydawcy" -#: cps/render_template.py:82 cps/templates/book_table.html:70 +#: cps/render_template.py:84 cps/templates/book_table.html:70 #: cps/templates/index.xml:97 cps/templates/search_form.html:107 -#: cps/web.py:1018 +#: cps/web.py:1108 msgid "Languages" msgstr "Języki" -#: cps/render_template.py:85 cps/templates/user_table.html:155 +#: cps/render_template.py:87 cps/templates/user_table.html:155 msgid "Show language selection" msgstr "Pokaż menu wyboru języka" -#: cps/render_template.py:86 cps/templates/index.xml:104 +#: cps/render_template.py:88 cps/templates/index.xml:104 msgid "Ratings" msgstr "Oceny" -#: cps/render_template.py:88 cps/templates/user_table.html:164 +#: cps/render_template.py:90 cps/templates/user_table.html:164 msgid "Show ratings selection" msgstr "Pokaż menu listy ocen" -#: cps/render_template.py:89 cps/templates/index.xml:112 +#: cps/render_template.py:91 cps/templates/index.xml:112 msgid "File formats" msgstr "Formaty plików" -#: cps/render_template.py:91 cps/templates/user_table.html:165 +#: cps/render_template.py:93 cps/templates/user_table.html:165 msgid "Show file formats selection" msgstr "Pokaż menu formatu plików" -#: cps/render_template.py:93 cps/web.py:703 +#: cps/render_template.py:95 cps/web.py:755 msgid "Archived Books" msgstr "Zarchiwizowane książki" -#: cps/render_template.py:95 cps/templates/user_table.html:166 +#: cps/render_template.py:97 cps/templates/user_table.html:166 msgid "Show archived books" msgstr "Pokaż zarchiwizowane książki" -#: cps/render_template.py:97 cps/web.py:780 +#: cps/render_template.py:100 cps/web.py:837 msgid "Books List" msgstr "Lista książek" -#: cps/render_template.py:99 cps/templates/user_table.html:168 +#: cps/render_template.py:102 cps/templates/user_table.html:168 msgid "Show Books List" msgstr "Pokaż listę książek" @@ -1063,263 +1083,267 @@ msgstr "" msgid "Create a Shelf" msgstr "Utwórz półkę" -#: cps/shelf.py:237 +#: cps/shelf.py:236 #, fuzzy msgid "Sorry you are not allowed to edit this shelf" msgstr "Niestety nie możesz usunąć książki z tej półki %(sname)s" -#: cps/shelf.py:239 +#: cps/shelf.py:238 msgid "Edit a shelf" msgstr "Edytuj półkę" -#: cps/shelf.py:249 +#: cps/shelf.py:248 msgid "Sorry you are not allowed to create a public shelf" msgstr "" -#: cps/shelf.py:266 +#: cps/shelf.py:265 #, python-format msgid "Shelf %(title)s created" msgstr "Półka %(title)s została utworzona" -#: cps/shelf.py:269 +#: cps/shelf.py:268 #, python-format msgid "Shelf %(title)s changed" msgstr "Półka %(title)s została zmieniona" -#: cps/shelf.py:283 +#: cps/shelf.py:282 msgid "There was an error" msgstr "Wystąpił błąd" -#: cps/shelf.py:305 +#: cps/shelf.py:304 #, python-format msgid "A public shelf with the name '%(title)s' already exists." msgstr "Publiczna półka o nazwie '%(title)s' już istnieje." -#: cps/shelf.py:316 +#: cps/shelf.py:315 #, python-format msgid "A private shelf with the name '%(title)s' already exists." msgstr "Prywatna półka o nazwie '%(title)s' już istnieje." #: cps/shelf.py:337 +msgid "Error deleting Shelf" +msgstr "" + +#: cps/shelf.py:339 #, fuzzy msgid "Shelf successfully deleted" msgstr "Książka została usunięta" -#: cps/shelf.py:386 +#: cps/shelf.py:389 #, python-format msgid "Change order of Shelf: '%(name)s'" msgstr "Zmieniono kolejność półki: '%(name)s'" -#: cps/shelf.py:456 +#: cps/shelf.py:461 #, python-format msgid "Shelf: '%(name)s'" msgstr "Półka: „%(name)s”" -#: cps/shelf.py:460 +#: cps/shelf.py:465 msgid "Error opening shelf. Shelf does not exist or is not accessible" msgstr "Błąd otwierania półki. Półka nie istnieje lub jest niedostępna" -#: cps/updater.py:403 cps/updater.py:414 cps/updater.py:514 cps/updater.py:529 +#: cps/updater.py:426 cps/updater.py:437 cps/updater.py:538 cps/updater.py:553 msgid "Unexpected data while reading update information" msgstr "Nieoczekiwane dane podczas odczytywania informacji o aktualizacji" -#: cps/updater.py:410 cps/updater.py:521 +#: cps/updater.py:433 cps/updater.py:545 msgid "No update available. You already have the latest version installed" msgstr "Brak dostępnej aktualizacji. Masz już zainstalowaną najnowszą wersję" -#: cps/updater.py:428 +#: cps/updater.py:451 msgid "A new update is available. Click on the button below to update to the latest version." msgstr "Dostępna jest nowa aktualizacja. Kliknij przycisk poniżej, aby zaktualizować do najnowszej wersji." -#: cps/updater.py:446 +#: cps/updater.py:469 msgid "Could not fetch update information" msgstr "Nie można pobrać informacji o aktualizacji" -#: cps/updater.py:456 +#: cps/updater.py:479 msgid "Click on the button below to update to the latest stable version." msgstr "Kliknij przycisk poniżej, aby zaktualizować do najnowszej stabilnej wersji." -#: cps/updater.py:465 cps/updater.py:479 cps/updater.py:490 +#: cps/updater.py:488 cps/updater.py:502 cps/updater.py:513 #, python-format msgid "A new update is available. Click on the button below to update to version: %(version)s" msgstr "Dostępna jest nowa aktualizacja. Kliknij przycisk poniżej, aby zaktualizować do wersji: %(version)s" -#: cps/updater.py:507 +#: cps/updater.py:531 msgid "No release information available" msgstr "Brak dostępnych informacji o wersji" -#: cps/templates/index.html:5 cps/web.py:440 +#: cps/templates/index.html:5 cps/web.py:434 msgid "Discover (Random Books)" msgstr "Odkrywaj (losowe książki)" -#: cps/web.py:471 +#: cps/web.py:470 msgid "Hot Books (Most Downloaded)" msgstr "Najpopularniejsze książki (najczęściej pobierane)" -#: cps/web.py:507 +#: cps/web.py:501 #, python-format msgid "Downloaded books by %(user)s" msgstr "Książki pobrane przez %(user)s" -#: cps/web.py:539 +#: cps/web.py:534 #, python-format msgid "Author: %(name)s" msgstr "Autor: %(name)s" -#: cps/web.py:554 +#: cps/web.py:570 #, python-format msgid "Publisher: %(name)s" msgstr "Wydawca: %(name)s" -#: cps/web.py:569 +#: cps/web.py:598 #, python-format msgid "Series: %(serie)s" msgstr "Cykl: %(serie)s" -#: cps/web.py:582 +#: cps/web.py:610 #, python-format msgid "Rating: %(rating)s stars" msgstr "Ocena: %(rating)s gwiazdek" -#: cps/web.py:597 +#: cps/web.py:626 #, python-format msgid "File format: %(format)s" msgstr "Format pliku: %(format)s" -#: cps/web.py:615 +#: cps/web.py:663 #, python-format msgid "Category: %(name)s" msgstr "Kategoria: %(name)s" -#: cps/web.py:631 +#: cps/web.py:690 #, python-format msgid "Language: %(name)s" msgstr "Język: %(name)s" -#: cps/templates/layout.html:56 cps/web.py:737 cps/web.py:1371 +#: cps/templates/layout.html:56 cps/web.py:789 cps/web.py:1444 msgid "Advanced Search" msgstr "Wyszukiwanie" #: cps/templates/book_edit.html:235 cps/templates/feed.xml:33 #: cps/templates/index.xml:11 cps/templates/layout.html:45 #: cps/templates/layout.html:48 cps/templates/search_form.html:226 -#: cps/web.py:750 cps/web.py:1077 +#: cps/web.py:807 cps/web.py:1164 msgid "Search" msgstr "Szukaj" -#: cps/templates/admin.html:16 cps/web.py:903 +#: cps/templates/admin.html:16 cps/web.py:979 msgid "Downloads" msgstr "DLS" -#: cps/web.py:980 +#: cps/web.py:1068 msgid "Ratings list" msgstr "Lista z ocenami" -#: cps/web.py:1001 +#: cps/web.py:1095 msgid "File formats list" msgstr "Lista formatów" -#: cps/templates/layout.html:73 cps/templates/tasks.html:7 cps/web.py:1055 +#: cps/templates/layout.html:73 cps/templates/tasks.html:7 cps/web.py:1149 msgid "Tasks" msgstr "Zadania" -#: cps/web.py:1215 +#: cps/web.py:1286 msgid "Published after " msgstr "Opublikowane po " -#: cps/web.py:1222 +#: cps/web.py:1293 msgid "Published before " msgstr "Opublikowane przed " -#: cps/web.py:1244 +#: cps/web.py:1315 #, python-format msgid "Rating <= %(rating)s" msgstr "Ocena <= %(rating)s" -#: cps/web.py:1246 +#: cps/web.py:1317 #, python-format msgid "Rating >= %(rating)s" msgstr "Ocena >= %(rating)s" -#: cps/web.py:1248 +#: cps/web.py:1319 #, python-format msgid "Read Status = %(status)s" msgstr "Status przeczytania = %(status)s" -#: cps/web.py:1353 +#: cps/web.py:1425 #, fuzzy msgid "Error on search for custom columns, please restart Calibre-Web" msgstr "Błąd podczas wyszukiwania kolumn niestandardowych, proszę zrestartować Calibre-Web" -#: cps/web.py:1449 +#: cps/web.py:1527 #, python-format msgid "Book successfully queued for sending to %(kindlemail)s" msgstr "Książka została umieszczona w kolejce do wysłania do %(kindlemail)s" -#: cps/web.py:1453 +#: cps/web.py:1531 #, python-format msgid "Oops! There was an error sending this book: %(res)s" msgstr "Wystąpił błąd podczas wysyłania tej książki: %(res)s" -#: cps/web.py:1455 +#: cps/web.py:1533 msgid "Please update your profile with a valid Send to Kindle E-mail Address." msgstr "Najpierw skonfiguruj adres e-mail Kindle..." -#: cps/web.py:1472 +#: cps/web.py:1550 msgid "E-Mail server is not configured, please contact your administrator!" msgstr "Serwer e-mail nie jest skonfigurowany, skontaktuj się z administratorem!" -#: cps/templates/layout.html:85 cps/templates/register.html:17 cps/web.py:1473 -#: cps/web.py:1480 cps/web.py:1486 cps/web.py:1505 cps/web.py:1509 -#: cps/web.py:1515 +#: cps/templates/layout.html:85 cps/templates/register.html:17 cps/web.py:1551 +#: cps/web.py:1558 cps/web.py:1564 cps/web.py:1583 cps/web.py:1587 +#: cps/web.py:1593 msgid "Register" msgstr "Zarejestruj się" -#: cps/web.py:1507 +#: cps/web.py:1585 msgid "Your e-mail is not allowed to register" msgstr "Twój e-mail nie może się zarejestrować" -#: cps/web.py:1510 +#: cps/web.py:1588 msgid "Confirmation e-mail was send to your e-mail account." msgstr "Wiadomość e-mail z potwierdzeniem została wysłana na Twoje konto e-mail." -#: cps/web.py:1524 +#: cps/web.py:1602 msgid "Cannot activate LDAP authentication" msgstr "Nie można aktywować uwierzytelniania LDAP" -#: cps/web.py:1543 +#: cps/web.py:1621 #, python-format msgid "Fallback Login as: '%(nickname)s', LDAP Server not reachable, or user not known" msgstr "Fallback Login as: '%(nickname)s', LDAP Server not reachable, or user not known" -#: cps/web.py:1549 +#: cps/web.py:1627 #, python-format msgid "Could not login: %(message)s" msgstr "Nie można zalogować: %(message)s" -#: cps/web.py:1553 cps/web.py:1578 +#: cps/web.py:1631 cps/web.py:1656 msgid "Wrong Username or Password" msgstr "Błędna nazwa użytkownika lub hasło" -#: cps/web.py:1560 +#: cps/web.py:1638 msgid "New Password was send to your email address" msgstr "Nowe hasło zostało wysłane na Twój adres e-mail" -#: cps/web.py:1566 +#: cps/web.py:1644 msgid "Please enter valid username to reset password" msgstr "Wprowadź prawidłową nazwę użytkownika, aby zresetować hasło" -#: cps/web.py:1573 +#: cps/web.py:1651 #, python-format msgid "You are now logged in as: '%(nickname)s'" msgstr "Jesteś teraz zalogowany jako: '%(nickname)s'" -#: cps/web.py:1639 cps/web.py:1688 +#: cps/web.py:1717 cps/web.py:1766 #, python-format msgid "%(name)s's profile" msgstr "Profil użytkownika %(name)s" -#: cps/web.py:1655 +#: cps/web.py:1733 msgid "Profile updated" msgstr "Zaktualizowano profil" @@ -1327,36 +1351,36 @@ msgstr "Zaktualizowano profil" msgid "Found no valid gmail.json file with OAuth information" msgstr "Nie znaleziono poprawnego pliku gmail.json z informacjami OAuth" -#: cps/tasks/convert.py:137 +#: cps/tasks/convert.py:154 #, python-format msgid "Calibre ebook-convert %(tool)s not found" msgstr "Nie znaleziono narzędzia calibre %(tool)s do konwertowania" -#: cps/tasks/convert.py:163 +#: cps/tasks/convert.py:187 #, python-format msgid "%(format)s format not found on disk" msgstr "Nie znaleziono na dysku formatu %(format)s" -#: cps/tasks/convert.py:167 +#: cps/tasks/convert.py:191 msgid "Ebook converter failed with unknown error" msgstr "Konwertowanie ebooka zakończyło się niepowodzeniem z nieznanego powodu" -#: cps/tasks/convert.py:177 +#: cps/tasks/convert.py:201 #, python-format msgid "Kepubify-converter failed: %(error)s" msgstr "Kepubify-converter spowodowało błąd: %(error)s" -#: cps/tasks/convert.py:199 +#: cps/tasks/convert.py:223 #, python-format msgid "Converted file not found or more than one file in folder %(folder)s" msgstr "Konwertowany plik nie został znaleziony, lub więcej niż jeden plik w folderze %(folder)s" -#: cps/tasks/convert.py:222 +#: cps/tasks/convert.py:246 #, python-format msgid "Ebook-converter failed: %(error)s" msgstr "Konwertowanie nie powiodło się: %(error)s" -#: cps/tasks/convert.py:245 +#: cps/tasks/convert.py:269 #, fuzzy, python-format msgid "Calibre failed with error: %(error)s" msgstr "Calibre nie powiodło się z błędem: %(error)s" @@ -1414,7 +1438,7 @@ msgstr "Edycja" # ??? #: cps/templates/admin.html:25 cps/templates/book_edit.html:16 -#: cps/templates/book_table.html:97 cps/templates/modal_dialogs.html:63 +#: cps/templates/book_table.html:100 cps/templates/modal_dialogs.html:63 #: cps/templates/modal_dialogs.html:116 cps/templates/user_edit.html:67 #: cps/templates/user_table.html:149 msgid "Delete" @@ -1424,179 +1448,179 @@ msgstr "Usuń" msgid "Public Shelf" msgstr "Półka publiczna" -#: cps/templates/admin.html:51 +#: cps/templates/admin.html:53 msgid "Add New User" msgstr "Dodaj nowego użytkownika" -#: cps/templates/admin.html:53 +#: cps/templates/admin.html:55 msgid "Import LDAP Users" msgstr "Importuj użytkowników LDAP" -#: cps/templates/admin.html:60 +#: cps/templates/admin.html:62 msgid "E-mail Server Settings" msgstr "Ustawienia serwera e-mail SMTP" -#: cps/templates/admin.html:65 cps/templates/email_edit.html:31 +#: cps/templates/admin.html:67 cps/templates/email_edit.html:31 msgid "SMTP Hostname" msgstr "Adres serwera SMTP" -#: cps/templates/admin.html:69 cps/templates/email_edit.html:35 +#: cps/templates/admin.html:71 cps/templates/email_edit.html:35 msgid "SMTP Port" msgstr "Port serwera SMTP" -#: cps/templates/admin.html:73 cps/templates/email_edit.html:39 +#: cps/templates/admin.html:75 cps/templates/email_edit.html:39 msgid "Encryption" msgstr "SSL" -#: cps/templates/admin.html:77 cps/templates/email_edit.html:47 +#: cps/templates/admin.html:79 cps/templates/email_edit.html:47 msgid "SMTP Login" msgstr "Nazwa użytkownika SMTP" -#: cps/templates/admin.html:81 cps/templates/admin.html:92 +#: cps/templates/admin.html:83 cps/templates/admin.html:94 #: cps/templates/email_edit.html:55 msgid "From E-mail" msgstr "Wyślij z adresu e-mail" -#: cps/templates/admin.html:88 +#: cps/templates/admin.html:90 msgid "E-Mail Service" msgstr "Usługa e-mail" -#: cps/templates/admin.html:89 +#: cps/templates/admin.html:91 msgid "Gmail via Oauth2" msgstr "Gmail przez Oauth2" -#: cps/templates/admin.html:104 +#: cps/templates/admin.html:106 msgid "Configuration" msgstr "Konfiguracja" -#: cps/templates/admin.html:107 +#: cps/templates/admin.html:109 msgid "Calibre Database Directory" msgstr "Folder bazy danych Calibre" -#: cps/templates/admin.html:111 cps/templates/config_edit.html:68 +#: cps/templates/admin.html:113 cps/templates/config_edit.html:68 msgid "Log Level" msgstr "Poziom dziennika" -#: cps/templates/admin.html:115 +#: cps/templates/admin.html:117 msgid "Port" msgstr "Port" -#: cps/templates/admin.html:120 +#: cps/templates/admin.html:122 msgid "External Port" msgstr "Port zewnętrzny" -#: cps/templates/admin.html:127 cps/templates/config_view_edit.html:28 +#: cps/templates/admin.html:129 cps/templates/config_view_edit.html:28 msgid "Books per Page" msgstr "Liczba książek na stronie" -#: cps/templates/admin.html:131 +#: cps/templates/admin.html:133 msgid "Uploads" msgstr "Wysyłanie" -#: cps/templates/admin.html:135 +#: cps/templates/admin.html:137 msgid "Anonymous Browsing" msgstr "Anonimowe przeglądanie" -#: cps/templates/admin.html:139 +#: cps/templates/admin.html:141 msgid "Public Registration" msgstr "Publiczna rejestracja" -#: cps/templates/admin.html:143 +#: cps/templates/admin.html:145 msgid "Magic Link Remote Login" msgstr "Zdalne logowanie (Magic Link)" -#: cps/templates/admin.html:147 +#: cps/templates/admin.html:149 msgid "Reverse Proxy Login" msgstr "Logowanie reverse proxy" -#: cps/templates/admin.html:152 cps/templates/config_edit.html:173 +#: cps/templates/admin.html:154 cps/templates/config_edit.html:173 msgid "Reverse Proxy Header Name" msgstr "Nazwa nagłowka reverse proxy" -#: cps/templates/admin.html:157 +#: cps/templates/admin.html:159 msgid "Edit Calibre Database Configuration" msgstr "Edytuj konfigurację bazy danych Calibre" -#: cps/templates/admin.html:158 +#: cps/templates/admin.html:160 msgid "Edit Basic Configuration" msgstr "Edytuj podstawową konfigurację" -#: cps/templates/admin.html:159 +#: cps/templates/admin.html:161 msgid "Edit UI Configuration" msgstr "Edytuj konfigurację interfejsu" -#: cps/templates/admin.html:164 +#: cps/templates/admin.html:166 msgid "Administration" msgstr "Zarządzanie" -#: cps/templates/admin.html:165 +#: cps/templates/admin.html:167 msgid "Download Debug Package" msgstr "Pobierz pakiet Debug" -#: cps/templates/admin.html:166 +#: cps/templates/admin.html:168 msgid "View Logs" msgstr "Podgląd dziennika" -#: cps/templates/admin.html:169 +#: cps/templates/admin.html:171 msgid "Reconnect Calibre Database" msgstr "Połącz ponownie z bazą danych Calibre" -#: cps/templates/admin.html:170 +#: cps/templates/admin.html:172 msgid "Restart" msgstr "Uruchom ponownie Calibre Web" -#: cps/templates/admin.html:171 +#: cps/templates/admin.html:173 msgid "Shutdown" msgstr "Zatrzymaj Calibre Web" -#: cps/templates/admin.html:176 +#: cps/templates/admin.html:178 msgid "Update" msgstr "Update (aktualizacja)" -#: cps/templates/admin.html:180 +#: cps/templates/admin.html:182 msgid "Version" msgstr "Wersja" -#: cps/templates/admin.html:181 +#: cps/templates/admin.html:183 msgid "Details" msgstr "Szczegóły" -#: cps/templates/admin.html:187 +#: cps/templates/admin.html:189 msgid "Current version" msgstr "Bieżąca wersja" -#: cps/templates/admin.html:194 +#: cps/templates/admin.html:196 msgid "Check for Update" msgstr "Sprawdź aktualizacje" -#: cps/templates/admin.html:195 +#: cps/templates/admin.html:197 msgid "Perform Update" msgstr "Wykonaj aktualizację" -#: cps/templates/admin.html:208 +#: cps/templates/admin.html:210 msgid "Are you sure you want to restart?" msgstr "Na pewno chcesz uruchomić ponownie Calibre Web?" -#: cps/templates/admin.html:213 cps/templates/admin.html:227 -#: cps/templates/admin.html:247 cps/templates/config_db.html:70 +#: cps/templates/admin.html:215 cps/templates/admin.html:229 +#: cps/templates/admin.html:249 cps/templates/config_db.html:70 msgid "OK" msgstr "OK" -#: cps/templates/admin.html:214 cps/templates/admin.html:228 -#: cps/templates/book_edit.html:213 cps/templates/book_table.html:124 +#: cps/templates/admin.html:216 cps/templates/admin.html:230 +#: cps/templates/book_edit.html:213 cps/templates/book_table.html:127 #: cps/templates/config_db.html:54 cps/templates/config_edit.html:359 -#: cps/templates/config_view_edit.html:173 cps/templates/modal_dialogs.html:64 +#: cps/templates/config_view_edit.html:175 cps/templates/modal_dialogs.html:64 #: cps/templates/modal_dialogs.html:99 cps/templates/modal_dialogs.html:117 #: cps/templates/modal_dialogs.html:135 cps/templates/shelf_edit.html:27 #: cps/templates/user_edit.html:144 msgid "Cancel" msgstr "Anuluj" -#: cps/templates/admin.html:226 +#: cps/templates/admin.html:228 msgid "Are you sure you want to shutdown?" msgstr "Na pewno chcesz zatrzymać Calibre Web?" -#: cps/templates/admin.html:238 +#: cps/templates/admin.html:240 msgid "Updating, please do not reload this page" msgstr "Aktualizowanie, proszę nie odświeżać strony" @@ -1608,44 +1632,43 @@ msgstr "przez" msgid "In Library" msgstr "W Bibliotece" -#: cps/templates/author.html:26 cps/templates/index.html:72 -#: cps/templates/search.html:29 cps/templates/shelf.html:19 +#: cps/templates/author.html:26 cps/templates/index.html:73 +#: cps/templates/search.html:30 cps/templates/shelf.html:19 msgid "Sort according to book date, newest first" msgstr "Sortuj książki według daty, najnowsze jako pierwsze" -#: cps/templates/author.html:27 cps/templates/index.html:73 -#: cps/templates/search.html:30 cps/templates/shelf.html:20 +#: cps/templates/author.html:27 cps/templates/index.html:74 +#: cps/templates/search.html:31 cps/templates/shelf.html:20 msgid "Sort according to book date, oldest first" msgstr "Sortuj książki według daty, najstarsze jako pierwsze" -#: cps/templates/author.html:28 cps/templates/index.html:74 -#: cps/templates/search.html:31 cps/templates/shelf.html:21 +#: cps/templates/author.html:28 cps/templates/index.html:75 +#: cps/templates/search.html:32 cps/templates/shelf.html:21 msgid "Sort title in alphabetical order" msgstr "Sortuj tytuły w porządku alfabetycznym" -#: cps/templates/author.html:29 cps/templates/index.html:75 -#: cps/templates/search.html:32 cps/templates/shelf.html:22 +#: cps/templates/author.html:29 cps/templates/index.html:76 +#: cps/templates/search.html:33 cps/templates/shelf.html:22 msgid "Sort title in reverse alphabetical order" msgstr "Sortuj tytuły w odwrotnym porządku alfabetycznym" -#: cps/templates/author.html:30 cps/templates/index.html:78 -#: cps/templates/search.html:35 cps/templates/shelf.html:25 +#: cps/templates/author.html:30 cps/templates/index.html:79 +#: cps/templates/search.html:36 cps/templates/shelf.html:25 msgid "Sort according to publishing date, newest first" msgstr "Sortuj według daty publikacji, najnowsze jako pierwsze" -#: cps/templates/author.html:31 cps/templates/index.html:79 -#: cps/templates/search.html:36 cps/templates/shelf.html:26 +#: cps/templates/author.html:31 cps/templates/index.html:80 +#: cps/templates/search.html:37 cps/templates/shelf.html:26 msgid "Sort according to publishing date, oldest first" msgstr "Sortuj według daty publikacji, najstarsze jako pierwsze" -#: cps/templates/author.html:57 cps/templates/author.html:117 -#: cps/templates/discover.html:30 cps/templates/index.html:29 -#: cps/templates/index.html:111 cps/templates/search.html:65 -#: cps/templates/shelf.html:54 +#: cps/templates/author.html:56 cps/templates/author.html:115 +#: cps/templates/index.html:29 cps/templates/index.html:112 +#: cps/templates/search.html:66 cps/templates/shelf.html:54 msgid "reduce" msgstr "zwiń" -#: cps/templates/author.html:101 +#: cps/templates/author.html:99 msgid "More by" msgstr "Więcej według" @@ -1771,7 +1794,7 @@ msgid "Fetch Metadata" msgstr "Uzyskaj metadane" #: cps/templates/book_edit.html:212 cps/templates/config_db.html:53 -#: cps/templates/config_edit.html:358 cps/templates/config_view_edit.html:172 +#: cps/templates/config_edit.html:358 cps/templates/config_view_edit.html:174 #: cps/templates/email_edit.html:65 cps/templates/shelf_edit.html:25 #: cps/templates/shelf_order.html:41 cps/templates/user_edit.html:142 msgid "Save" @@ -1902,29 +1925,37 @@ msgstr "Podaj nazwę domeny" msgid "Comments" msgstr "" -#: cps/templates/book_table.html:77 cps/templates/book_table.html:79 -#: cps/templates/book_table.html:81 cps/templates/book_table.html:83 -#: cps/templates/book_table.html:87 cps/templates/book_table.html:89 -#: cps/templates/book_table.html:91 cps/templates/book_table.html:93 +#: cps/templates/book_table.html:75 +msgid "Archiv Status" +msgstr "" + +#: cps/templates/book_table.html:77 cps/templates/search_form.html:42 +msgid "Read Status" +msgstr "Status odczytu" + +#: cps/templates/book_table.html:80 cps/templates/book_table.html:82 +#: cps/templates/book_table.html:84 cps/templates/book_table.html:86 +#: cps/templates/book_table.html:90 cps/templates/book_table.html:92 +#: cps/templates/book_table.html:96 #, fuzzy msgid "Enter " msgstr "Identyfikatory" -#: cps/templates/book_table.html:110 cps/templates/modal_dialogs.html:46 +#: cps/templates/book_table.html:113 cps/templates/modal_dialogs.html:46 msgid "Are you really sure?" msgstr "Czy jesteś pewny?" -#: cps/templates/book_table.html:114 +#: cps/templates/book_table.html:117 #, fuzzy msgid "Books with Title will be merged from:" msgstr "Książki z tytułem będą łączone z:" -#: cps/templates/book_table.html:118 +#: cps/templates/book_table.html:121 #, fuzzy msgid "Into Book with Title:" msgstr "Into Book with Title:" -#: cps/templates/book_table.html:123 +#: cps/templates/book_table.html:126 msgid "Merge" msgstr "Połącz" @@ -2102,11 +2133,6 @@ msgstr "Port serwera LDAP" msgid "LDAP Encryption" msgstr "Szyfrowanie LDAP" -#: cps/templates/config_edit.html:204 cps/templates/config_view_edit.html:62 -#: cps/templates/email_edit.html:41 -msgid "None" -msgstr "Brak" - #: cps/templates/config_edit.html:205 msgid "TLS" msgstr "TLS" @@ -2325,11 +2351,11 @@ msgstr "Domyślne ustawienia widoku dla nowych użytkowników" msgid "Show Random Books in Detail View" msgstr "Pokaz losowe książki w widoku szczegółowym" -#: cps/templates/config_view_edit.html:165 cps/templates/user_edit.html:87 +#: cps/templates/config_view_edit.html:166 cps/templates/user_edit.html:87 msgid "Add Allowed/Denied Tags" msgstr "Dodaj dozwolone/zabronione etykiety" -#: cps/templates/config_view_edit.html:166 +#: cps/templates/config_view_edit.html:167 msgid "Add Allowed/Denied custom column values" msgstr "Dodaj dozwolone/zabronione wartości własnych kolumn" @@ -2378,13 +2404,13 @@ msgstr "Zarchiwizowane" msgid "Description:" msgstr "Opis:" -#: cps/templates/detail.html:256 cps/templates/search.html:14 +#: cps/templates/detail.html:256 cps/templates/search.html:15 msgid "Add to shelf" msgstr "Dodaj do półki" #: cps/templates/detail.html:267 cps/templates/detail.html:284 #: cps/templates/feed.xml:79 cps/templates/layout.html:137 -#: cps/templates/search.html:20 +#: cps/templates/search.html:21 msgid "(Public)" msgstr "(publiczna)" @@ -2462,10 +2488,15 @@ msgstr "Domeny zabronione (czarna lista)" msgid "Next" msgstr "Następne" -#: cps/templates/generate_kobo_auth_url.html:5 +#: cps/templates/generate_kobo_auth_url.html:6 msgid "Open the .kobo/Kobo eReader.conf file in a text editor and add (or edit):" msgstr "Otwórz plik .kobo/Kobo eReader.conf w edytorze tekstu i dodaj (lub edytuj):" +#: cps/templates/generate_kobo_auth_url.html:11 +#, fuzzy +msgid "Kobo Token:" +msgstr "Token Kobo Sync" + #: cps/templates/http_error.html:31 msgid "Calibre-Web Instance is unconfigured, please contact your administrator" msgstr "Instancja Calibre-Web jest nieskonfigurowana, proszę skontaktować się z administratorem" @@ -2485,29 +2516,29 @@ msgstr "Powrót do głównego menu" msgid "Logout User" msgstr "Wyloguj użytkownika" -#: cps/templates/index.html:69 +#: cps/templates/index.html:70 msgid "Sort ascending according to download count" msgstr "" -#: cps/templates/index.html:70 +#: cps/templates/index.html:71 msgid "Sort descending according to download count" msgstr "" -#: cps/templates/index.html:76 cps/templates/search.html:33 +#: cps/templates/index.html:77 cps/templates/search.html:34 #: cps/templates/shelf.html:23 msgid "Sort authors in alphabetical order" msgstr "Sortuj autorów w porządku alfabetycznym" -#: cps/templates/index.html:77 cps/templates/search.html:34 +#: cps/templates/index.html:78 cps/templates/search.html:35 #: cps/templates/shelf.html:24 msgid "Sort authors in reverse alphabetical order" msgstr "Posortuj autorów w odwrotnym porządku alfabetycznym" -#: cps/templates/index.html:81 +#: cps/templates/index.html:82 msgid "Sort ascending according to series index" msgstr "Sortuj rosnąco według indeksu serii" -#: cps/templates/index.html:82 +#: cps/templates/index.html:83 msgid "Sort descending according to series index" msgstr "Sortuj malejąco według indeksu serii" @@ -2945,10 +2976,6 @@ msgstr "Data publikacji od" msgid "Published Date To" msgstr "Data publikacji do" -#: cps/templates/search_form.html:42 -msgid "Read Status" -msgstr "Status odczytu" - #: cps/templates/search_form.html:59 msgid "Exclude Tags" msgstr "Wyklucz etykiety" diff --git a/cps/translations/pt_BR/LC_MESSAGES/messages.mo b/cps/translations/pt_BR/LC_MESSAGES/messages.mo index a440798e..b7052210 100644 Binary files a/cps/translations/pt_BR/LC_MESSAGES/messages.mo and b/cps/translations/pt_BR/LC_MESSAGES/messages.mo differ diff --git a/cps/translations/pt_BR/LC_MESSAGES/messages.po b/cps/translations/pt_BR/LC_MESSAGES/messages.po index af21e9c1..2431ffae 100644 --- a/cps/translations/pt_BR/LC_MESSAGES/messages.po +++ b/cps/translations/pt_BR/LC_MESSAGES/messages.po @@ -4,7 +4,7 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2022-01-15 09:19+0100\n" +"POT-Creation-Date: 2022-04-18 20:01+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: br\n" @@ -13,590 +13,593 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.9.0\n" +"Generated-By: Babel 2.9.1\n" -#: cps/about.py:34 cps/about.py:49 cps/about.py:65 cps/converter.py:31 -msgid "not installed" -msgstr "não instalado" - -#: cps/about.py:47 cps/about.py:63 -msgid "installed" -msgstr "instalado" - -#: cps/about.py:145 +#: cps/about.py:86 msgid "Statistics" msgstr "Estatística" -#: cps/admin.py:144 +#: cps/admin.py:141 msgid "Server restarted, please reload page" msgstr "Servidor reiniciado, por favor recarregue a página" -#: cps/admin.py:146 +#: cps/admin.py:143 msgid "Performing shutdown of server, please close window" msgstr "Executando o desligamento do servidor, por favor, feche a janela" -#: cps/admin.py:154 +#: cps/admin.py:151 msgid "Reconnect successful" msgstr "Reconexão bem-sucedida" -#: cps/admin.py:157 +#: cps/admin.py:154 msgid "Unknown command" msgstr "Comando desconhecido" -#: cps/admin.py:167 cps/editbooks.py:707 cps/editbooks.py:721 -#: cps/editbooks.py:866 cps/editbooks.py:868 cps/editbooks.py:895 -#: cps/editbooks.py:911 cps/updater.py:584 cps/uploader.py:93 -#: cps/uploader.py:103 +#: cps/admin.py:176 cps/editbooks.py:713 cps/editbooks.py:892 +#: cps/editbooks.py:894 cps/editbooks.py:930 cps/editbooks.py:947 +#: cps/updater.py:608 cps/uploader.py:93 cps/uploader.py:103 msgid "Unknown" msgstr "Desconhecido" -#: cps/admin.py:188 +#: cps/admin.py:197 msgid "Admin page" msgstr "Página de administração" -#: cps/admin.py:207 +#: cps/admin.py:217 msgid "Basic Configuration" msgstr "Configuração Básica" -#: cps/admin.py:244 +#: cps/admin.py:255 msgid "UI Configuration" msgstr "Configuração de UI" -#: cps/admin.py:277 cps/templates/admin.html:50 +#: cps/admin.py:289 cps/templates/admin.html:51 #, fuzzy msgid "Edit Users" msgstr "Usuário Admin" -#: cps/admin.py:318 cps/opds.py:109 cps/opds.py:198 cps/opds.py:275 -#: cps/opds.py:327 cps/templates/grid.html:13 cps/templates/languages.html:9 +#: cps/admin.py:333 cps/opds.py:529 cps/templates/grid.html:13 #: cps/templates/list.html:13 msgid "All" msgstr "Todos" -#: cps/admin.py:343 cps/admin.py:1615 +#: cps/admin.py:360 cps/admin.py:1648 msgid "User not found" msgstr "Usuário não encontrado" -#: cps/admin.py:357 +#: cps/admin.py:374 #, fuzzy msgid "{} users deleted successfully" msgstr "{} Usuário Importado com Sucesso" -#: cps/admin.py:379 cps/templates/config_view_edit.html:133 +#: cps/admin.py:397 cps/templates/config_view_edit.html:133 #: cps/templates/user_edit.html:45 cps/templates/user_table.html:81 msgid "Show All" msgstr "Mostrar tudo" -#: cps/admin.py:400 cps/admin.py:406 +#: cps/admin.py:418 cps/admin.py:424 msgid "Malformed request" msgstr "" -#: cps/admin.py:418 cps/admin.py:1493 +#: cps/admin.py:436 cps/admin.py:1526 msgid "Guest Name can't be changed" msgstr "" -#: cps/admin.py:430 +#: cps/admin.py:448 msgid "Guest can't have this role" msgstr "" -#: cps/admin.py:442 cps/admin.py:1451 +#: cps/admin.py:460 cps/admin.py:1484 msgid "No admin user remaining, can't remove admin role" msgstr "Nenhum usuário administrador restante, não pode remover a função de administrador" -#: cps/admin.py:446 cps/admin.py:460 +#: cps/admin.py:464 cps/admin.py:478 msgid "Value has to be true or false" msgstr "" -#: cps/admin.py:448 +#: cps/admin.py:466 msgid "Invalid role" msgstr "" -#: cps/admin.py:452 +#: cps/admin.py:470 msgid "Guest can't have this view" msgstr "" -#: cps/admin.py:462 +#: cps/admin.py:480 msgid "Invalid view" msgstr "" -#: cps/admin.py:465 +#: cps/admin.py:483 msgid "Guest's Locale is determined automatically and can't be set" msgstr "" -#: cps/admin.py:469 +#: cps/admin.py:487 msgid "No Valid Locale Given" msgstr "" -#: cps/admin.py:480 +#: cps/admin.py:498 msgid "No Valid Book Language Given" msgstr "" -#: cps/admin.py:482 +#: cps/admin.py:500 cps/editbooks.py:1267 msgid "Parameter not found" msgstr "" -#: cps/admin.py:533 +#: cps/admin.py:553 msgid "Invalid Read Column" msgstr "" -#: cps/admin.py:539 +#: cps/admin.py:559 msgid "Invalid Restricted Column" msgstr "" -#: cps/admin.py:560 cps/admin.py:1323 +#: cps/admin.py:579 cps/admin.py:1355 msgid "Calibre-Web configuration updated" msgstr "Configuração do Calibre-Web atualizada" -#: cps/admin.py:572 +#: cps/admin.py:591 msgid "Do you really want to delete the Kobo Token?" msgstr "Você realmente quer excluir o Kobo Token?" -#: cps/admin.py:574 +#: cps/admin.py:593 msgid "Do you really want to delete this domain?" msgstr "Você realmente quer excluir este domínio?" -#: cps/admin.py:576 +#: cps/admin.py:595 msgid "Do you really want to delete this user?" msgstr "Você realmente quer excluir este usuário?" -#: cps/admin.py:578 +#: cps/admin.py:597 msgid "Are you sure you want to delete this shelf?" msgstr "Tem certeza que quer apagar essa estante?" -#: cps/admin.py:580 +#: cps/admin.py:599 #, fuzzy msgid "Are you sure you want to change locales of selected user(s)?" msgstr "Tem certeza que quer apagar essa estante?" -#: cps/admin.py:582 +#: cps/admin.py:601 msgid "Are you sure you want to change visible book languages for selected user(s)?" msgstr "" -#: cps/admin.py:584 +#: cps/admin.py:603 msgid "Are you sure you want to change the selected role for the selected user(s)?" msgstr "" -#: cps/admin.py:586 +#: cps/admin.py:605 #, fuzzy msgid "Are you sure you want to change the selected restrictions for the selected user(s)?" msgstr "Tem certeza que quer apagar essa estante?" -#: cps/admin.py:588 +#: cps/admin.py:607 msgid "Are you sure you want to change the selected visibility restrictions for the selected user(s)?" msgstr "" -#: cps/admin.py:590 +#: cps/admin.py:610 #, fuzzy msgid "Are you sure you want to change shelf sync behavior for the selected user(s)?" msgstr "Tem certeza que quer apagar essa estante?" -#: cps/admin.py:592 +#: cps/admin.py:612 #, fuzzy msgid "Are you sure you want to change Calibre library location?" msgstr "Tens a certeza que queres fechar?" -#: cps/admin.py:594 +#: cps/admin.py:614 msgid "Are you sure you want delete Calibre-Web's sync database to force a full sync with your Kobo Reader?" msgstr "" -#: cps/admin.py:743 +#: cps/admin.py:764 msgid "Tag not found" msgstr "" -#: cps/admin.py:755 +#: cps/admin.py:776 msgid "Invalid Action" msgstr "" -#: cps/admin.py:871 cps/admin.py:877 cps/admin.py:887 cps/admin.py:897 +#: cps/admin.py:893 cps/admin.py:899 cps/admin.py:909 cps/admin.py:919 #: cps/templates/modal_dialogs.html:29 cps/templates/user_table.html:41 #: cps/templates/user_table.html:58 msgid "Deny" msgstr "Negar" -#: cps/admin.py:873 cps/admin.py:879 cps/admin.py:889 cps/admin.py:899 +#: cps/admin.py:895 cps/admin.py:901 cps/admin.py:911 cps/admin.py:921 #: cps/templates/modal_dialogs.html:28 cps/templates/user_table.html:44 #: cps/templates/user_table.html:61 msgid "Allow" msgstr "Permita" -#: cps/admin.py:913 +#: cps/admin.py:936 msgid "{} sync entries deleted" msgstr "" -#: cps/admin.py:1036 +#: cps/admin.py:1059 msgid "client_secrets.json Is Not Configured For Web Application" msgstr "client_secrets.json não está configurado para aplicativo da web" -#: cps/admin.py:1081 +#: cps/admin.py:1104 msgid "Logfile Location is not Valid, Please Enter Correct Path" msgstr "A localização do arquivo de log não é válida, digite o caminho correto" -#: cps/admin.py:1087 +#: cps/admin.py:1110 msgid "Access Logfile Location is not Valid, Please Enter Correct Path" msgstr "A localização do arquivo de log de acesso não é válida, digite o caminho correto" -#: cps/admin.py:1117 +#: cps/admin.py:1140 msgid "Please Enter a LDAP Provider, Port, DN and User Object Identifier" msgstr "Digite um provedor LDAP, porta, DN e identificador de objeto do usuário" -#: cps/admin.py:1123 +#: cps/admin.py:1146 #, fuzzy msgid "Please Enter a LDAP Service Account and Password" msgstr "Por favor, digite um nome de usuário válido para redefinir a senha" -#: cps/admin.py:1126 +#: cps/admin.py:1149 msgid "Please Enter a LDAP Service Account" msgstr "" -#: cps/admin.py:1131 +#: cps/admin.py:1154 #, python-format msgid "LDAP Group Object Filter Needs to Have One \"%s\" Format Identifier" msgstr "O filtro de objeto de grupo LDAP precisa ter um identificador de formato \"%s\"" -#: cps/admin.py:1133 +#: cps/admin.py:1156 msgid "LDAP Group Object Filter Has Unmatched Parenthesis" msgstr "Filtro de objeto de grupo LDAP tem parênteses incomparáveis" -#: cps/admin.py:1137 +#: cps/admin.py:1160 #, python-format msgid "LDAP User Object Filter needs to Have One \"%s\" Format Identifier" msgstr "O filtro de objeto de usuário LDAP precisa ter um identificador de formato \"%s\"" -#: cps/admin.py:1139 +#: cps/admin.py:1162 msgid "LDAP User Object Filter Has Unmatched Parenthesis" msgstr "Filtro de objeto de usuário LDAP tem parênteses incomparáveis" -#: cps/admin.py:1146 +#: cps/admin.py:1169 #, python-format msgid "LDAP Member User Filter needs to Have One \"%s\" Format Identifier" msgstr "O filtro de usuário membro do LDAP precisa ter um identificador de formato \"%s\"" -#: cps/admin.py:1148 +#: cps/admin.py:1171 msgid "LDAP Member User Filter Has Unmatched Parenthesis" msgstr "Filtro de usuário de membro LDAP tem parênteses incomparáveis" -#: cps/admin.py:1155 +#: cps/admin.py:1178 msgid "LDAP CACertificate, Certificate or Key Location is not Valid, Please Enter Correct Path" msgstr "LDAP CACertificate, Certificados ou chave de localização não é válida, Insira o caminho correto" -#: cps/admin.py:1197 cps/admin.py:1308 cps/admin.py:1405 cps/admin.py:1521 -#: cps/admin.py:1590 cps/shelf.py:100 cps/shelf.py:160 cps/shelf.py:203 -#: cps/shelf.py:279 cps/shelf.py:341 cps/shelf.py:376 cps/shelf.py:451 -msgid "Settings DB is not Writeable" -msgstr "O banco de dados de configurações não é gravável" - -#: cps/admin.py:1208 -msgid "DB Location is not Valid, Please Enter Correct Path" -msgstr "A localização do banco de dados não é válida, digite o caminho correto" - -#: cps/admin.py:1223 -msgid "DB is not Writeable" -msgstr "DB não é gravável" - -#: cps/admin.py:1235 -msgid "Keyfile Location is not Valid, Please Enter Correct Path" -msgstr "A localização do arquivo-chave não é válida, por favor insira o caminho correto" - -#: cps/admin.py:1239 -msgid "Certfile Location is not Valid, Please Enter Correct Path" -msgstr "A localização do arquivo de certificação não é válida, digite o caminho correto" - -#: cps/admin.py:1346 -#, fuzzy -msgid "Database Settings updated" -msgstr "Atualização das configurações do servidor de e-mail" - -#: cps/admin.py:1354 -#, fuzzy -msgid "Database Configuration" -msgstr "Configuração das Características" - -#: cps/admin.py:1370 cps/web.py:1479 -msgid "Please fill out all fields!" -msgstr "Por favor, preencha todos os campos!" - -#: cps/admin.py:1378 -msgid "E-mail is not from valid domain" -msgstr "O e-mail não é de um domínio válido" - -#: cps/admin.py:1384 cps/admin.py:1543 -msgid "Add new user" -msgstr "Adicionar novo usuário" - -#: cps/admin.py:1395 -#, python-format -msgid "User '%(user)s' created" -msgstr "Usuário '%(user)s' criado" - -#: cps/admin.py:1401 -#, fuzzy -msgid "Found an existing account for this e-mail address or name." -msgstr "Encontrei uma conta existente para este endereço de e-mail ou apelido." - -#: cps/admin.py:1430 -#, python-format -msgid "User '%(nick)s' deleted" -msgstr "Usuário '%(nick)s' excluído" - -#: cps/admin.py:1432 cps/admin.py:1433 -msgid "Can't delete Guest User" -msgstr "" - -#: cps/admin.py:1436 -msgid "No admin user remaining, can't delete user" -msgstr "Nenhum usuário administrador restante, não é possível excluir o usuário" - -#: cps/admin.py:1509 cps/admin.py:1634 -#, python-format -msgid "Edit User %(nick)s" -msgstr "Editar usuário %(nick)s" - -#: cps/admin.py:1513 -#, python-format -msgid "User '%(nick)s' updated" -msgstr "Usuário '%(nick)s' atualizado" - -#: cps/admin.py:1517 cps/admin.py:1649 cps/web.py:1504 cps/web.py:1564 -msgid "An unknown error occurred. Please try again later." -msgstr "Ocorreu um erro desconhecido. Por favor, tente novamente mais tarde." - -#: cps/admin.py:1552 cps/templates/admin.html:98 -msgid "Edit E-mail Server Settings" -msgstr "Editar configurações do servidor de e-mail" - -#: cps/admin.py:1571 -msgid "Gmail Account Verification Successful" -msgstr "" - -#: cps/admin.py:1597 -#, python-format -msgid "Test e-mail queued for sending to %(email)s, please check Tasks for result" -msgstr "" - -#: cps/admin.py:1600 -#, python-format -msgid "There was an error sending the Test e-mail: %(res)s" -msgstr "Ocorreu um erro ao enviar o e-mail de teste: %(res)s" - -#: cps/admin.py:1602 -msgid "Please configure your e-mail address first..." -msgstr "Por favor, configure seu endereço de e-mail primeiro..." - -#: cps/admin.py:1604 -msgid "E-mail server settings updated" -msgstr "Atualização das configurações do servidor de e-mail" - -#: cps/admin.py:1646 -#, python-format -msgid "Password for user %(user)s reset" -msgstr "Senha para redefinição do usuário %(user)s" - -#: cps/admin.py:1652 cps/web.py:1444 -msgid "Please configure the SMTP mail settings first..." -msgstr "Por favor, configure primeiro as configurações de correio SMTP..." - -#: cps/admin.py:1663 -msgid "Logfile viewer" -msgstr "visualizador de arquivo de registro" - -#: cps/admin.py:1729 -msgid "Requesting update package" -msgstr "Solicitação de pacote de atualização" - -#: cps/admin.py:1730 -msgid "Downloading update package" -msgstr "Download do pacote de atualização" - -#: cps/admin.py:1731 -msgid "Unzipping update package" -msgstr "Descompactação de pacote de atualização" - -#: cps/admin.py:1732 -msgid "Replacing files" -msgstr "Substituição de arquivos" - -#: cps/admin.py:1733 -msgid "Database connections are closed" -msgstr "As ligações à base de dados estão fechadas" - -#: cps/admin.py:1734 -msgid "Stopping server" -msgstr "Parar servidor" - -#: cps/admin.py:1735 -msgid "Update finished, please press okay and reload page" -msgstr "Atualização concluída, pressione okay e recarregue a página" - -#: cps/admin.py:1736 cps/admin.py:1737 cps/admin.py:1738 cps/admin.py:1739 -#: cps/admin.py:1740 cps/admin.py:1741 -msgid "Update failed:" -msgstr "Atualização falhou:" - -#: cps/admin.py:1736 cps/updater.py:385 cps/updater.py:595 cps/updater.py:597 -msgid "HTTP Error" -msgstr "Erro HTTP" - -#: cps/admin.py:1737 cps/updater.py:387 cps/updater.py:599 -msgid "Connection error" -msgstr "Erro de conexão" - -#: cps/admin.py:1738 cps/updater.py:389 cps/updater.py:601 -msgid "Timeout while establishing connection" -msgstr "Tempo limite durante o estabelecimento da conexão" - -#: cps/admin.py:1739 cps/updater.py:391 cps/updater.py:603 -msgid "General error" -msgstr "Erro geral" - -#: cps/admin.py:1740 -#, fuzzy -msgid "Update file could not be saved in temp dir" -msgstr "Arquivo de atualização não pôde ser salvo no diretório temporário" - -#: cps/admin.py:1741 -msgid "Files could not be replaced during update" -msgstr "" - -#: cps/admin.py:1765 -#, fuzzy -msgid "Failed to extract at least One LDAP User" -msgstr "Falha na criação no mínimo de um usuário LDAP" - -#: cps/admin.py:1810 -msgid "Failed to Create at Least One LDAP User" -msgstr "Falha na criação no mínimo de um usuário LDAP" - -#: cps/admin.py:1823 -#, python-format -msgid "Error: %(ldaperror)s" -msgstr "Erro: %(ldaperror)s" - -#: cps/admin.py:1827 -msgid "Error: No user returned in response of LDAP server" -msgstr "Erro: Nenhum usuário retornado em resposta do servidor LDAP" - -#: cps/admin.py:1860 -msgid "At Least One LDAP User Not Found in Database" -msgstr "No mínimo um usuário LDAP não encontrado no banco de dados" - -#: cps/admin.py:1862 -msgid "{} User Successfully Imported" -msgstr "{} Usuário Importado com Sucesso" - -#: cps/converter.py:30 -msgid "not configured" -msgstr "não configurado" - -#: cps/converter.py:32 -msgid "Execution permissions missing" -msgstr "Faltam as permissões de execução" - -#: cps/db.py:651 cps/web.py:667 cps/web.py:1155 -#, python-format -msgid "Custom Column No.%(column)d is not existing in calibre database" -msgstr "A coluna personalizada No.%(column)d não existe no banco de dados do calibre" - -#: cps/editbooks.py:300 cps/editbooks.py:302 -msgid "Book Format Successfully Deleted" -msgstr "Formato do Livro Eliminado com Sucesso" - -#: cps/editbooks.py:309 cps/editbooks.py:311 -msgid "Book Successfully Deleted" -msgstr "Livro Eliminado com Sucesso" - -#: cps/editbooks.py:361 -msgid "You are missing permissions to delete books" -msgstr "" - -#: cps/editbooks.py:376 cps/editbooks.py:763 cps/web.py:523 cps/web.py:1703 -#: cps/web.py:1744 cps/web.py:1811 -msgid "Oops! Selected book title is unavailable. File does not exist or is not accessible" -msgstr "Oops! O título do livro seleccionado não está disponível. O arquivo não existe ou não é acessível" - -#: cps/editbooks.py:410 -msgid "edit metadata" -msgstr "editar metadados" - -#: cps/editbooks.py:458 -#, python-format -msgid "%(seriesindex)s is not a valid number, skipping" -msgstr "" - -#: cps/editbooks.py:494 cps/editbooks.py:958 -#, fuzzy, python-format -msgid "'%(langname)s' is not a valid language" -msgstr "%(langname)s não é um idioma válido" - -#: cps/editbooks.py:634 cps/editbooks.py:985 -#, python-format -msgid "File extension '%(ext)s' is not allowed to be uploaded to this server" -msgstr "A extensão de arquivo '%(ext)s' não pode ser enviada para este servidor" - -#: cps/editbooks.py:638 cps/editbooks.py:989 -msgid "File to be uploaded must have an extension" -msgstr "O arquivo a ser carregado deve ter uma extensão" - -#: cps/editbooks.py:650 -#, python-format -msgid "Failed to create path %(path)s (Permission denied)." -msgstr "Falha ao criar o caminho %(path)s (Permission denied)." - -#: cps/editbooks.py:655 -#, python-format -msgid "Failed to store file %(file)s." -msgstr "Falha ao armazenar o arquivo %(file)s." - -#: cps/editbooks.py:673 cps/editbooks.py:1076 cps/web.py:1664 +#: cps/admin.py:1223 cps/admin.py:1339 cps/admin.py:1437 cps/admin.py:1554 +#: cps/admin.py:1623 cps/editbooks.py:678 cps/editbooks.py:882 +#: cps/editbooks.py:1130 cps/shelf.py:100 cps/shelf.py:160 cps/shelf.py:203 +#: cps/shelf.py:278 cps/shelf.py:343 cps/shelf.py:380 cps/shelf.py:456 +#: cps/web.py:1742 #, python-format msgid "Database error: %(error)s." msgstr "Erro de banco de dados: %(error)s." -#: cps/editbooks.py:678 +#: cps/admin.py:1235 +msgid "DB Location is not Valid, Please Enter Correct Path" +msgstr "A localização do banco de dados não é válida, digite o caminho correto" + +#: cps/admin.py:1253 +msgid "DB is not Writeable" +msgstr "DB não é gravável" + +#: cps/admin.py:1266 +msgid "Keyfile Location is not Valid, Please Enter Correct Path" +msgstr "A localização do arquivo-chave não é válida, por favor insira o caminho correto" + +#: cps/admin.py:1270 +msgid "Certfile Location is not Valid, Please Enter Correct Path" +msgstr "A localização do arquivo de certificação não é válida, digite o caminho correto" + +#: cps/admin.py:1378 +#, fuzzy +msgid "Database Settings updated" +msgstr "Atualização das configurações do servidor de e-mail" + +#: cps/admin.py:1386 +#, fuzzy +msgid "Database Configuration" +msgstr "Configuração das Características" + +#: cps/admin.py:1402 cps/web.py:1557 +msgid "Please fill out all fields!" +msgstr "Por favor, preencha todos os campos!" + +#: cps/admin.py:1410 +msgid "E-mail is not from valid domain" +msgstr "O e-mail não é de um domínio válido" + +#: cps/admin.py:1416 cps/admin.py:1576 +msgid "Add new user" +msgstr "Adicionar novo usuário" + +#: cps/admin.py:1427 +#, python-format +msgid "User '%(user)s' created" +msgstr "Usuário '%(user)s' criado" + +#: cps/admin.py:1433 +#, fuzzy +msgid "Found an existing account for this e-mail address or name." +msgstr "Encontrei uma conta existente para este endereço de e-mail ou apelido." + +#: cps/admin.py:1463 +#, python-format +msgid "User '%(nick)s' deleted" +msgstr "Usuário '%(nick)s' excluído" + +#: cps/admin.py:1465 cps/admin.py:1466 +msgid "Can't delete Guest User" +msgstr "" + +#: cps/admin.py:1469 +msgid "No admin user remaining, can't delete user" +msgstr "Nenhum usuário administrador restante, não é possível excluir o usuário" + +#: cps/admin.py:1542 cps/admin.py:1667 +#, python-format +msgid "Edit User %(nick)s" +msgstr "Editar usuário %(nick)s" + +#: cps/admin.py:1546 +#, python-format +msgid "User '%(nick)s' updated" +msgstr "Usuário '%(nick)s' atualizado" + +#: cps/admin.py:1550 cps/admin.py:1682 cps/web.py:1582 cps/web.py:1642 +msgid "An unknown error occurred. Please try again later." +msgstr "Ocorreu um erro desconhecido. Por favor, tente novamente mais tarde." + +#: cps/admin.py:1585 cps/templates/admin.html:100 +msgid "Edit E-mail Server Settings" +msgstr "Editar configurações do servidor de e-mail" + +#: cps/admin.py:1604 +msgid "Gmail Account Verification Successful" +msgstr "" + +#: cps/admin.py:1630 +#, python-format +msgid "Test e-mail queued for sending to %(email)s, please check Tasks for result" +msgstr "" + +#: cps/admin.py:1633 +#, python-format +msgid "There was an error sending the Test e-mail: %(res)s" +msgstr "Ocorreu um erro ao enviar o e-mail de teste: %(res)s" + +#: cps/admin.py:1635 +msgid "Please configure your e-mail address first..." +msgstr "Por favor, configure seu endereço de e-mail primeiro..." + +#: cps/admin.py:1637 +msgid "E-mail server settings updated" +msgstr "Atualização das configurações do servidor de e-mail" + +#: cps/admin.py:1679 +#, python-format +msgid "Password for user %(user)s reset" +msgstr "Senha para redefinição do usuário %(user)s" + +#: cps/admin.py:1685 cps/web.py:1522 +msgid "Please configure the SMTP mail settings first..." +msgstr "Por favor, configure primeiro as configurações de correio SMTP..." + +#: cps/admin.py:1696 +msgid "Logfile viewer" +msgstr "visualizador de arquivo de registro" + +#: cps/admin.py:1762 +msgid "Requesting update package" +msgstr "Solicitação de pacote de atualização" + +#: cps/admin.py:1763 +msgid "Downloading update package" +msgstr "Download do pacote de atualização" + +#: cps/admin.py:1764 +msgid "Unzipping update package" +msgstr "Descompactação de pacote de atualização" + +#: cps/admin.py:1765 +msgid "Replacing files" +msgstr "Substituição de arquivos" + +#: cps/admin.py:1766 +msgid "Database connections are closed" +msgstr "As ligações à base de dados estão fechadas" + +#: cps/admin.py:1767 +msgid "Stopping server" +msgstr "Parar servidor" + +#: cps/admin.py:1768 +msgid "Update finished, please press okay and reload page" +msgstr "Atualização concluída, pressione okay e recarregue a página" + +#: cps/admin.py:1769 cps/admin.py:1770 cps/admin.py:1771 cps/admin.py:1772 +#: cps/admin.py:1773 cps/admin.py:1774 +msgid "Update failed:" +msgstr "Atualização falhou:" + +#: cps/admin.py:1769 cps/updater.py:384 cps/updater.py:619 cps/updater.py:621 +msgid "HTTP Error" +msgstr "Erro HTTP" + +#: cps/admin.py:1770 cps/updater.py:386 cps/updater.py:623 +msgid "Connection error" +msgstr "Erro de conexão" + +#: cps/admin.py:1771 cps/updater.py:388 cps/updater.py:625 +msgid "Timeout while establishing connection" +msgstr "Tempo limite durante o estabelecimento da conexão" + +#: cps/admin.py:1772 cps/updater.py:390 cps/updater.py:627 +msgid "General error" +msgstr "Erro geral" + +#: cps/admin.py:1773 +#, fuzzy +msgid "Update file could not be saved in temp dir" +msgstr "Arquivo de atualização não pôde ser salvo no diretório temporário" + +#: cps/admin.py:1774 +msgid "Files could not be replaced during update" +msgstr "" + +#: cps/admin.py:1798 +#, fuzzy +msgid "Failed to extract at least One LDAP User" +msgstr "Falha na criação no mínimo de um usuário LDAP" + +#: cps/admin.py:1843 +msgid "Failed to Create at Least One LDAP User" +msgstr "Falha na criação no mínimo de um usuário LDAP" + +#: cps/admin.py:1856 +#, python-format +msgid "Error: %(ldaperror)s" +msgstr "Erro: %(ldaperror)s" + +#: cps/admin.py:1860 +msgid "Error: No user returned in response of LDAP server" +msgstr "Erro: Nenhum usuário retornado em resposta do servidor LDAP" + +#: cps/admin.py:1893 +msgid "At Least One LDAP User Not Found in Database" +msgstr "No mínimo um usuário LDAP não encontrado no banco de dados" + +#: cps/admin.py:1895 +msgid "{} User Successfully Imported" +msgstr "{} Usuário Importado com Sucesso" + +#: cps/converter.py:30 +msgid "not installed" +msgstr "não instalado" + +#: cps/converter.py:31 +msgid "Execution permissions missing" +msgstr "Faltam as permissões de execução" + +#: cps/db.py:674 cps/web.py:710 cps/web.py:1222 +#, python-format +msgid "Custom Column No.%(column)d is not existing in calibre database" +msgstr "A coluna personalizada No.%(column)d não existe no banco de dados do calibre" + +#: cps/db.py:917 cps/templates/config_edit.html:204 +#: cps/templates/config_view_edit.html:62 cps/templates/email_edit.html:41 +#: cps/web.py:551 cps/web.py:585 cps/web.py:646 cps/web.py:671 cps/web.py:1003 +#: cps/web.py:1032 cps/web.py:1066 cps/web.py:1093 cps/web.py:1132 +msgid "None" +msgstr "Nenhum" + +#: cps/editbooks.py:295 cps/editbooks.py:297 +msgid "Book Format Successfully Deleted" +msgstr "Formato do Livro Eliminado com Sucesso" + +#: cps/editbooks.py:304 cps/editbooks.py:306 +msgid "Book Successfully Deleted" +msgstr "Livro Eliminado com Sucesso" + +#: cps/editbooks.py:358 +msgid "You are missing permissions to delete books" +msgstr "" + +#: cps/editbooks.py:373 cps/editbooks.py:765 cps/web.py:518 cps/web.py:1783 +#: cps/web.py:1825 cps/web.py:1870 +msgid "Oops! Selected book title is unavailable. File does not exist or is not accessible" +msgstr "Oops! O título do livro seleccionado não está disponível. O arquivo não existe ou não é acessível" + +#: cps/editbooks.py:408 +msgid "edit metadata" +msgstr "editar metadados" + +#: cps/editbooks.py:457 +#, python-format +msgid "%(seriesindex)s is not a valid number, skipping" +msgstr "" + +#: cps/editbooks.py:493 cps/editbooks.py:1001 +#, fuzzy, python-format +msgid "'%(langname)s' is not a valid language" +msgstr "%(langname)s não é um idioma válido" + +#: cps/editbooks.py:634 +msgid "User has no rights to upload additional file formats" +msgstr "" + +#: cps/editbooks.py:639 cps/editbooks.py:1029 +#, python-format +msgid "File extension '%(ext)s' is not allowed to be uploaded to this server" +msgstr "A extensão de arquivo '%(ext)s' não pode ser enviada para este servidor" + +#: cps/editbooks.py:643 cps/editbooks.py:1033 +msgid "File to be uploaded must have an extension" +msgstr "O arquivo a ser carregado deve ter uma extensão" + +#: cps/editbooks.py:655 +#, python-format +msgid "Failed to create path %(path)s (Permission denied)." +msgstr "Falha ao criar o caminho %(path)s (Permission denied)." + +#: cps/editbooks.py:660 +#, python-format +msgid "Failed to store file %(file)s." +msgstr "Falha ao armazenar o arquivo %(file)s." + +#: cps/editbooks.py:683 #, python-format msgid "File format %(ext)s added to %(book)s" msgstr "Formato de arquivo %(ext)s adicionado a %(book)s" -#: cps/editbooks.py:814 +#: cps/editbooks.py:697 cps/editbooks.py:809 +msgid "User has no rights to upload cover" +msgstr "" + +#: cps/editbooks.py:828 msgid "Identifiers are not Case Sensitive, Overwriting Old Identifier" msgstr "Os identificadores não são sensíveis a maiúsculas ou minúsculas, mas sim a maiúsculas e minúsculas" -#: cps/editbooks.py:848 +#: cps/editbooks.py:869 msgid "Metadata successfully updated" msgstr "Metadados atualizados com sucesso" -#: cps/editbooks.py:861 -msgid "Error editing book, please check logfile for details" -msgstr "Livro de edição de erros, por favor verifique o ficheiro de registo para mais detalhes" +#: cps/editbooks.py:887 +msgid "Error editing book: {}" +msgstr "" -#: cps/editbooks.py:899 +#: cps/editbooks.py:951 msgid "Uploaded book probably exists in the library, consider to change before upload new: " msgstr "O livro carregado provavelmente existe na biblioteca, considere mudar antes de carregar novo: " -#: cps/editbooks.py:997 +#: cps/editbooks.py:1041 #, python-format msgid "File %(filename)s could not saved to temp dir" msgstr "O arquivo %(filename)s não pôde ser salvo no diretório temporário" -#: cps/editbooks.py:1016 +#: cps/editbooks.py:1061 #, python-format msgid "Failed to Move Cover File %(file)s: %(error)s" msgstr "Falha ao mover arquivo de capa %(file)s: %(error)s" -#: cps/editbooks.py:1063 +#: cps/editbooks.py:1117 #, python-format msgid "File %(file)s uploaded" msgstr "Arquivo %(file)s enviado" -#: cps/editbooks.py:1088 +#: cps/editbooks.py:1143 msgid "Source or destination format for conversion missing" msgstr "Falta o formato de origem ou destino para a conversão" -#: cps/editbooks.py:1096 +#: cps/editbooks.py:1151 #, python-format msgid "Book successfully queued for converting to %(book_format)s" msgstr "Livro enfileirado com sucesso para conversão em %(book_format)s" -#: cps/editbooks.py:1100 +#: cps/editbooks.py:1155 #, python-format msgid "There was an error converting this book: %(res)s" msgstr "Ocorreu um erro ao converter este livro: %(res)s" @@ -609,175 +612,192 @@ msgstr "Configuração do Google Drive não concluída, tente desativar e ativar msgid "Callback domain is not verified, please follow steps to verify domain in google developer console" msgstr "O domínio Callback não é verificado, por favor siga os passos para verificar o domínio no console do desenvolvedor do google" -#: cps/helper.py:77 +#: cps/helper.py:81 #, python-format msgid "%(format)s format not found for book id: %(book)d" msgstr "Formato %(format)s não encontrado para o id do livro: %(book)d" -#: cps/helper.py:83 cps/tasks/convert.py:73 +#: cps/helper.py:87 cps/tasks/convert.py:75 #, python-format msgid "%(format)s not found on Google Drive: %(fn)s" msgstr "%(format)s não encontrado no Google Drive: %(fn)s" -#: cps/helper.py:88 +#: cps/helper.py:92 #, python-format msgid "%(format)s not found: %(fn)s" msgstr "%(format)s não encontrado: %(fn)s" -#: cps/helper.py:93 cps/helper.py:217 cps/templates/detail.html:41 +#: cps/helper.py:97 cps/helper.py:221 cps/templates/detail.html:41 #: cps/templates/detail.html:45 msgid "Send to Kindle" msgstr "Enviar para Kindle" -#: cps/helper.py:94 cps/helper.py:111 cps/helper.py:219 +#: cps/helper.py:98 cps/helper.py:115 cps/helper.py:223 msgid "This e-mail has been sent via Calibre-Web." msgstr "Este e-mail foi enviado via Calibre-Web." -#: cps/helper.py:109 +#: cps/helper.py:113 msgid "Calibre-Web test e-mail" msgstr "E-mail de teste do Calibre-Web" -#: cps/helper.py:110 +#: cps/helper.py:114 msgid "Test e-mail" msgstr "E-mail de teste" -#: cps/helper.py:127 +#: cps/helper.py:131 msgid "Get Started with Calibre-Web" msgstr "Comece a usar o calibre-web" -#: cps/helper.py:132 +#: cps/helper.py:136 #, python-format msgid "Registration e-mail for user: %(name)s" msgstr "E-mail de registro do usuário: %(name)s" -#: cps/helper.py:143 cps/helper.py:149 +#: cps/helper.py:147 cps/helper.py:153 #, python-format msgid "Convert %(orig)s to %(format)s and send to Kindle" msgstr "Converta %(orig)s em %(format)s e envie para o Kindle" -#: cps/helper.py:168 cps/helper.py:172 cps/helper.py:176 +#: cps/helper.py:172 cps/helper.py:176 cps/helper.py:180 #, python-format msgid "Send %(format)s to Kindle" msgstr "Envie %(format)s para o Kindle" -#: cps/helper.py:216 cps/tasks/convert.py:90 +#: cps/helper.py:220 cps/tasks/convert.py:92 #, fuzzy, python-format msgid "%(book)s send to Kindle" msgstr "Enviar para Kindle" -#: cps/helper.py:221 +#: cps/helper.py:225 msgid "The requested file could not be read. Maybe wrong permissions?" msgstr "O arquivo solicitado não pôde ser lido. Talvez permissões erradas?" -#: cps/helper.py:313 +#: cps/helper.py:353 +msgid "Read status could not set: {}" +msgstr "" + +#: cps/helper.py:376 #, python-format msgid "Deleting bookfolder for book %(id)s failed, path has subfolders: %(path)s" msgstr "A exclusão da pasta de livros do livro %(id)s falhou, o caminho tem subpastas: %(path)s" -#: cps/helper.py:319 +#: cps/helper.py:382 #, python-format msgid "Deleting book %(id)s failed: %(message)s" msgstr "Falha ao excluir livro %(id)s: %(message)s" -#: cps/helper.py:330 +#: cps/helper.py:393 #, fuzzy, python-format msgid "Deleting book %(id)s from database only, book path in database not valid: %(path)s" msgstr "Excluindo livro %(id)s, caminho do livro inválido: %(path)s" -#: cps/helper.py:385 -#, python-format -msgid "Rename title from: '%(src)s' to '%(dest)s' failed with error: %(error)s" +#: cps/helper.py:458 +#, fuzzy, python-format +msgid "Rename author from: '%(src)s' to '%(dest)s' failed with error: %(error)s" msgstr "Renomear título de: '%(src)s' para '%(dest)s' falhou com o erro: %(error)s" -#: cps/helper.py:400 -#, python-format -msgid "Rename file in path '%(src)s' to '%(dest)s' failed with error: %(error)s" -msgstr "Renomear arquivo no caminho '%(src)s' para '%(dest)s' falhou com o erro: %(error)s" - -#: cps/helper.py:425 cps/helper.py:435 cps/helper.py:443 +#: cps/helper.py:529 cps/helper.py:538 #, python-format msgid "File %(file)s not found on Google Drive" msgstr "Arquivo %(file)s não encontrado no Google Drive" -#: cps/helper.py:464 +#: cps/helper.py:572 +#, python-format +msgid "Rename title from: '%(src)s' to '%(dest)s' failed with error: %(error)s" +msgstr "Renomear título de: '%(src)s' para '%(dest)s' falhou com o erro: %(error)s" + +#: cps/helper.py:592 +msgid "Error in rename file in path: {}" +msgstr "" + +#: cps/helper.py:610 #, python-format msgid "Book path %(path)s not found on Google Drive" msgstr "Caminho do livro %(path)s não encontrado no Google Drive" -#: cps/helper.py:504 cps/web.py:1659 +#: cps/helper.py:651 cps/web.py:1737 #, fuzzy msgid "Found an existing account for this e-mail address" msgstr "Encontrado uma conta existente para este endereço de e-mail." -#: cps/helper.py:512 +#: cps/helper.py:659 msgid "This username is already taken" msgstr "Este nome de usuário já está registrado" -#: cps/helper.py:522 +#: cps/helper.py:669 msgid "Invalid e-mail address format" msgstr "Formato de endereço de e-mail inválido" -#: cps/helper.py:595 +#: cps/helper.py:754 +msgid "Python modul 'advocate' is not installed but is needed for cover downloads" +msgstr "" + +#: cps/helper.py:767 msgid "Error Downloading Cover" msgstr "Erro ao Baixar a capa" -#: cps/helper.py:598 +#: cps/helper.py:770 msgid "Cover Format Error" msgstr "Erro de Formato da Capa" -#: cps/helper.py:608 +#: cps/helper.py:773 +msgid "You are not allowed to access localhost or the local network for cover uploads" +msgstr "" + +#: cps/helper.py:783 msgid "Failed to create path for cover" msgstr "Falha em criar caminho para a capa" -#: cps/helper.py:624 +#: cps/helper.py:799 msgid "Cover-file is not a valid image file, or could not be stored" msgstr "O arquivo de capa não é um arquivo de imagem válido, ou não pôde ser armazenado" -#: cps/helper.py:635 +#: cps/helper.py:810 msgid "Only jpg/jpeg/png/webp/bmp files are supported as coverfile" msgstr "Apenas ficheiros jpg/jpeg/png/webp/bmp são suportados como arquivos de capa" -#: cps/helper.py:648 +#: cps/helper.py:822 msgid "Invalid cover file content" msgstr "" -#: cps/helper.py:652 +#: cps/helper.py:826 msgid "Only jpg/jpeg files are supported as coverfile" msgstr "Apenas arquivos jpg/jpeg são suportados como arquivos de capa" -#: cps/helper.py:704 +#: cps/helper.py:878 msgid "Unrar binary file not found" msgstr "Unrar arquivo binário não encontrado" -#: cps/helper.py:715 +#: cps/helper.py:889 msgid "Error excecuting UnRar" msgstr "Erro excecutando UnRar" -#: cps/helper.py:763 +#: cps/helper.py:937 msgid "Waiting" msgstr "Aguardando" -#: cps/helper.py:765 +#: cps/helper.py:939 msgid "Failed" msgstr "Falha" -#: cps/helper.py:767 +#: cps/helper.py:941 msgid "Started" msgstr "Iniciado em" -#: cps/helper.py:769 +#: cps/helper.py:943 msgid "Finished" msgstr "Concluído" -#: cps/helper.py:771 +#: cps/helper.py:945 msgid "Unknown Status" msgstr "Status Desconhecido" -#: cps/kobo_auth.py:127 -msgid "PLease access calibre-web from non localhost to get valid api_endpoint for kobo device" +#: cps/kobo_auth.py:128 +#, fuzzy +msgid "Please access Calibre-Web from non localhost to get valid api_endpoint for kobo device" msgstr "Por favor, acesse o calibre-web de um host não local para obter um api_endpoint válido para o dispositivo kobo" -#: cps/kobo_auth.py:130 cps/kobo_auth.py:158 +#: cps/kobo_auth.py:154 msgid "Kobo Setup" msgstr "Configuração Kobo" @@ -786,7 +806,7 @@ msgstr "Configuração Kobo" msgid "Register with %(provider)s" msgstr "Registre-se com %(provider)s" -#: cps/oauth_bb.py:138 cps/remotelogin.py:133 cps/web.py:1535 +#: cps/oauth_bb.py:138 cps/remotelogin.py:130 cps/web.py:1613 #, python-format msgid "you are now logged in as: '%(nickname)s'" msgstr "agora você está logado como: '%(nickname)s'" @@ -847,163 +867,163 @@ msgstr "Erro no Google Oauth, por favor tente novamente mais tarde." msgid "Google Oauth error: {}" msgstr "" -#: cps/opds.py:384 +#: cps/opds.py:298 msgid "{} Stars" msgstr "" -#: cps/remotelogin.py:65 cps/templates/layout.html:84 -#: cps/templates/login.html:4 cps/templates/login.html:21 cps/web.py:1584 +#: cps/remotelogin.py:62 cps/templates/layout.html:84 +#: cps/templates/login.html:4 cps/templates/login.html:21 cps/web.py:1662 msgid "Login" msgstr "Login" -#: cps/remotelogin.py:77 cps/remotelogin.py:111 +#: cps/remotelogin.py:74 cps/remotelogin.py:108 msgid "Token not found" msgstr "Token não encontrado" -#: cps/remotelogin.py:86 cps/remotelogin.py:119 +#: cps/remotelogin.py:83 cps/remotelogin.py:116 msgid "Token has expired" msgstr "O Token expirou" -#: cps/remotelogin.py:95 +#: cps/remotelogin.py:92 msgid "Success! Please return to your device" msgstr "Sucesso! Por favor, volte ao seu aparelho" -#: cps/render_template.py:39 cps/web.py:416 +#: cps/render_template.py:41 cps/web.py:407 msgid "Books" msgstr "Livros" -#: cps/render_template.py:41 +#: cps/render_template.py:43 msgid "Show recent books" msgstr "Mostrar livros recentes" -#: cps/render_template.py:42 cps/templates/index.xml:25 +#: cps/render_template.py:44 cps/templates/index.xml:25 msgid "Hot Books" msgstr "Livros Quentes" -#: cps/render_template.py:44 +#: cps/render_template.py:46 msgid "Show Hot Books" msgstr "Mostrar Livros Quentes" -#: cps/render_template.py:46 cps/render_template.py:51 +#: cps/render_template.py:48 cps/render_template.py:53 msgid "Downloaded Books" msgstr "Livros descarregados" -#: cps/render_template.py:48 cps/render_template.py:53 +#: cps/render_template.py:50 cps/render_template.py:55 #: cps/templates/user_table.html:167 msgid "Show Downloaded Books" msgstr "Mostrar Livros Descarregados" -#: cps/render_template.py:56 cps/templates/index.xml:32 cps/web.py:430 +#: cps/render_template.py:58 cps/templates/index.xml:32 cps/web.py:422 msgid "Top Rated Books" msgstr "Livros Mais Bem Avaliados" -#: cps/render_template.py:58 cps/templates/user_table.html:161 +#: cps/render_template.py:60 cps/templates/user_table.html:161 msgid "Show Top Rated Books" msgstr "Mostrar os melhores livros avaliados" -#: cps/render_template.py:59 cps/templates/index.xml:54 -#: cps/templates/index.xml:58 cps/web.py:676 +#: cps/render_template.py:61 cps/templates/index.xml:54 +#: cps/templates/index.xml:58 cps/web.py:729 msgid "Read Books" msgstr "Livros Lidos" -#: cps/render_template.py:61 +#: cps/render_template.py:63 msgid "Show read and unread" msgstr "Mostrar lido e não lido" -#: cps/render_template.py:63 cps/templates/index.xml:61 -#: cps/templates/index.xml:65 cps/web.py:679 +#: cps/render_template.py:65 cps/templates/index.xml:61 +#: cps/templates/index.xml:65 cps/web.py:732 msgid "Unread Books" msgstr "Livros Não Lidos" -#: cps/render_template.py:65 +#: cps/render_template.py:67 msgid "Show unread" msgstr "Mostrar não lido" -#: cps/render_template.py:66 +#: cps/render_template.py:68 msgid "Discover" msgstr "Descubra" -#: cps/render_template.py:68 cps/templates/index.xml:50 +#: cps/render_template.py:70 cps/templates/index.xml:50 #: cps/templates/user_table.html:162 msgid "Show Random Books" msgstr "Mostrar Livros Aleatórios" -#: cps/render_template.py:69 cps/templates/book_table.html:67 -#: cps/templates/index.xml:83 cps/web.py:1041 +#: cps/render_template.py:71 cps/templates/book_table.html:67 +#: cps/templates/index.xml:83 cps/web.py:1135 msgid "Categories" msgstr "Categorias" -#: cps/render_template.py:71 cps/templates/user_table.html:158 +#: cps/render_template.py:73 cps/templates/user_table.html:158 msgid "Show category selection" msgstr "Mostrar seleção de categoria" -#: cps/render_template.py:72 cps/templates/book_edit.html:90 +#: cps/render_template.py:74 cps/templates/book_edit.html:90 #: cps/templates/book_table.html:68 cps/templates/index.xml:90 -#: cps/templates/search_form.html:69 cps/web.py:948 cps/web.py:959 +#: cps/templates/search_form.html:69 cps/web.py:1034 cps/web.py:1041 msgid "Series" msgstr "Série" -#: cps/render_template.py:74 cps/templates/user_table.html:157 +#: cps/render_template.py:76 cps/templates/user_table.html:157 msgid "Show series selection" msgstr "Mostrar selecção de séries" -#: cps/render_template.py:75 cps/templates/book_table.html:66 +#: cps/render_template.py:77 cps/templates/book_table.html:66 #: cps/templates/index.xml:69 msgid "Authors" msgstr "Autores" -#: cps/render_template.py:77 cps/templates/user_table.html:160 +#: cps/render_template.py:79 cps/templates/user_table.html:160 msgid "Show author selection" msgstr "Mostrar selecção de autor" -#: cps/render_template.py:79 cps/templates/book_table.html:72 -#: cps/templates/index.xml:76 cps/web.py:925 +#: cps/render_template.py:81 cps/templates/book_table.html:72 +#: cps/templates/index.xml:76 cps/web.py:1006 msgid "Publishers" msgstr "Editores" -#: cps/render_template.py:81 cps/templates/user_table.html:163 +#: cps/render_template.py:83 cps/templates/user_table.html:163 msgid "Show publisher selection" msgstr "Mostrar selecção de editores" -#: cps/render_template.py:82 cps/templates/book_table.html:70 +#: cps/render_template.py:84 cps/templates/book_table.html:70 #: cps/templates/index.xml:97 cps/templates/search_form.html:107 -#: cps/web.py:1018 +#: cps/web.py:1108 msgid "Languages" msgstr "Idiomas" -#: cps/render_template.py:85 cps/templates/user_table.html:155 +#: cps/render_template.py:87 cps/templates/user_table.html:155 msgid "Show language selection" msgstr "Mostrar seleção de idioma" -#: cps/render_template.py:86 cps/templates/index.xml:104 +#: cps/render_template.py:88 cps/templates/index.xml:104 msgid "Ratings" msgstr "Classificações" -#: cps/render_template.py:88 cps/templates/user_table.html:164 +#: cps/render_template.py:90 cps/templates/user_table.html:164 msgid "Show ratings selection" msgstr "Mostrar selecção de classificações" -#: cps/render_template.py:89 cps/templates/index.xml:112 +#: cps/render_template.py:91 cps/templates/index.xml:112 msgid "File formats" msgstr "Formatos de arquivo" -#: cps/render_template.py:91 cps/templates/user_table.html:165 +#: cps/render_template.py:93 cps/templates/user_table.html:165 msgid "Show file formats selection" msgstr "Mostrar seleção de formatos de arquivo" -#: cps/render_template.py:93 cps/web.py:703 +#: cps/render_template.py:95 cps/web.py:755 msgid "Archived Books" msgstr "Livros Arquivados" -#: cps/render_template.py:95 cps/templates/user_table.html:166 +#: cps/render_template.py:97 cps/templates/user_table.html:166 msgid "Show archived books" msgstr "Mostrar livros arquivados" -#: cps/render_template.py:97 cps/web.py:780 +#: cps/render_template.py:100 cps/web.py:837 msgid "Books List" msgstr "Lista de Livros" -#: cps/render_template.py:99 cps/templates/user_table.html:168 +#: cps/render_template.py:102 cps/templates/user_table.html:168 msgid "Show Books List" msgstr "Mostrar Lista de Livros" @@ -1058,262 +1078,266 @@ msgstr "" msgid "Create a Shelf" msgstr "Crie uma estante" -#: cps/shelf.py:237 +#: cps/shelf.py:236 #, fuzzy msgid "Sorry you are not allowed to edit this shelf" msgstr "Desculpe, você não tem permissão para remover um livro desta estante: %(sname)s" -#: cps/shelf.py:239 +#: cps/shelf.py:238 msgid "Edit a shelf" msgstr "Editar uma estante" -#: cps/shelf.py:249 +#: cps/shelf.py:248 msgid "Sorry you are not allowed to create a public shelf" msgstr "" -#: cps/shelf.py:266 +#: cps/shelf.py:265 #, python-format msgid "Shelf %(title)s created" msgstr "Estante %(title)s criada" -#: cps/shelf.py:269 +#: cps/shelf.py:268 #, python-format msgid "Shelf %(title)s changed" msgstr "Estante %(title)s alterada" -#: cps/shelf.py:283 +#: cps/shelf.py:282 msgid "There was an error" msgstr "Houve um erro" -#: cps/shelf.py:305 +#: cps/shelf.py:304 #, python-format msgid "A public shelf with the name '%(title)s' already exists." msgstr "Já existe uma estante pública com o nome '%(title)s' ." -#: cps/shelf.py:316 +#: cps/shelf.py:315 #, python-format msgid "A private shelf with the name '%(title)s' already exists." msgstr "Já existe uma estante privada com o nome'%(title)s' ." #: cps/shelf.py:337 +msgid "Error deleting Shelf" +msgstr "" + +#: cps/shelf.py:339 #, fuzzy msgid "Shelf successfully deleted" msgstr "Livro Eliminado com Sucesso" -#: cps/shelf.py:386 +#: cps/shelf.py:389 #, python-format msgid "Change order of Shelf: '%(name)s'" msgstr "Alterar ordem da Estante: '%(name)s'" -#: cps/shelf.py:456 +#: cps/shelf.py:461 #, python-format msgid "Shelf: '%(name)s'" msgstr "Estante: '%(name)s'" -#: cps/shelf.py:460 +#: cps/shelf.py:465 msgid "Error opening shelf. Shelf does not exist or is not accessible" msgstr "Erro ao abrir estante. A estante não existe ou não está acessível" -#: cps/updater.py:403 cps/updater.py:414 cps/updater.py:514 cps/updater.py:529 +#: cps/updater.py:426 cps/updater.py:437 cps/updater.py:538 cps/updater.py:553 msgid "Unexpected data while reading update information" msgstr "Dados inesperados ao ler informações de atualização" -#: cps/updater.py:410 cps/updater.py:521 +#: cps/updater.py:433 cps/updater.py:545 msgid "No update available. You already have the latest version installed" msgstr "Não há atualização disponível. Você já tem a última versão instalada" -#: cps/updater.py:428 +#: cps/updater.py:451 msgid "A new update is available. Click on the button below to update to the latest version." msgstr "Uma nova atualização está disponível. Clique no botão abaixo para atualizar para a versão mais recente." -#: cps/updater.py:446 +#: cps/updater.py:469 msgid "Could not fetch update information" msgstr "Não consegui obter informações actualizadas" -#: cps/updater.py:456 +#: cps/updater.py:479 msgid "Click on the button below to update to the latest stable version." msgstr "Clique no botão abaixo para atualizar para a última versão estável." -#: cps/updater.py:465 cps/updater.py:479 cps/updater.py:490 +#: cps/updater.py:488 cps/updater.py:502 cps/updater.py:513 #, python-format msgid "A new update is available. Click on the button below to update to version: %(version)s" msgstr "Uma nova atualização está disponível. Clique no botão abaixo para atualizar para a versão: %(version)s" -#: cps/updater.py:507 +#: cps/updater.py:531 msgid "No release information available" msgstr "Não há informações de lançamento disponíveis" -#: cps/templates/index.html:5 cps/web.py:440 +#: cps/templates/index.html:5 cps/web.py:434 msgid "Discover (Random Books)" msgstr "Descobrir (Livros Aleatórios)" -#: cps/web.py:471 +#: cps/web.py:470 msgid "Hot Books (Most Downloaded)" msgstr "Hot Books (Os Mais Descarregados)" -#: cps/web.py:507 +#: cps/web.py:501 #, python-format msgid "Downloaded books by %(user)s" msgstr "Livros baixados por %(user)s" -#: cps/web.py:539 +#: cps/web.py:534 #, python-format msgid "Author: %(name)s" msgstr "Autor: %(name)s" -#: cps/web.py:554 +#: cps/web.py:570 #, python-format msgid "Publisher: %(name)s" msgstr "Editor: %(name)s" -#: cps/web.py:569 +#: cps/web.py:598 #, python-format msgid "Series: %(serie)s" msgstr "Série: %(serie)s" -#: cps/web.py:582 +#: cps/web.py:610 #, python-format msgid "Rating: %(rating)s stars" msgstr "Avaliação: %(rating)s estrelas" -#: cps/web.py:597 +#: cps/web.py:626 #, python-format msgid "File format: %(format)s" msgstr "Formato do arquivo: %(format)s" -#: cps/web.py:615 +#: cps/web.py:663 #, python-format msgid "Category: %(name)s" msgstr "Categoria: %(name)s" -#: cps/web.py:631 +#: cps/web.py:690 #, python-format msgid "Language: %(name)s" msgstr "Idioma: %(name)s" -#: cps/templates/layout.html:56 cps/web.py:737 cps/web.py:1371 +#: cps/templates/layout.html:56 cps/web.py:789 cps/web.py:1444 msgid "Advanced Search" msgstr "Pesquisa Avançada" #: cps/templates/book_edit.html:235 cps/templates/feed.xml:33 #: cps/templates/index.xml:11 cps/templates/layout.html:45 #: cps/templates/layout.html:48 cps/templates/search_form.html:226 -#: cps/web.py:750 cps/web.py:1077 +#: cps/web.py:807 cps/web.py:1164 msgid "Search" msgstr "Pesquisa" -#: cps/templates/admin.html:16 cps/web.py:903 +#: cps/templates/admin.html:16 cps/web.py:979 msgid "Downloads" msgstr "Downloads" -#: cps/web.py:980 +#: cps/web.py:1068 msgid "Ratings list" msgstr "Lista de classificações" -#: cps/web.py:1001 +#: cps/web.py:1095 msgid "File formats list" msgstr "Lista de formatos de arquivo" -#: cps/templates/layout.html:73 cps/templates/tasks.html:7 cps/web.py:1055 +#: cps/templates/layout.html:73 cps/templates/tasks.html:7 cps/web.py:1149 msgid "Tasks" msgstr "Tarefas" -#: cps/web.py:1215 +#: cps/web.py:1286 msgid "Published after " msgstr "Publicado depois de " -#: cps/web.py:1222 +#: cps/web.py:1293 msgid "Published before " msgstr "Publicado antes de " -#: cps/web.py:1244 +#: cps/web.py:1315 #, python-format msgid "Rating <= %(rating)s" msgstr "Avaliação <= %(rating)s" -#: cps/web.py:1246 +#: cps/web.py:1317 #, python-format msgid "Rating >= %(rating)s" msgstr "Avaliação >= %(rating)s" -#: cps/web.py:1248 +#: cps/web.py:1319 #, python-format msgid "Read Status = %(status)s" msgstr "Status de leitura = %(status)s" -#: cps/web.py:1353 +#: cps/web.py:1425 msgid "Error on search for custom columns, please restart Calibre-Web" msgstr "" -#: cps/web.py:1449 +#: cps/web.py:1527 #, python-format msgid "Book successfully queued for sending to %(kindlemail)s" msgstr "Livro enfileirado com sucesso para envio para %(kindlemail)s" -#: cps/web.py:1453 +#: cps/web.py:1531 #, python-format msgid "Oops! There was an error sending this book: %(res)s" msgstr "Ups! Ocorreu um erro ao enviar este livro: %(res)s" -#: cps/web.py:1455 +#: cps/web.py:1533 msgid "Please update your profile with a valid Send to Kindle E-mail Address." msgstr "Por favor, atualize seu perfil com um endereço de e-mail válido para Kindle." -#: cps/web.py:1472 +#: cps/web.py:1550 msgid "E-Mail server is not configured, please contact your administrator!" msgstr "O servidor de E-Mail não está configurado, por favor contacte o seu administrador!" -#: cps/templates/layout.html:85 cps/templates/register.html:17 cps/web.py:1473 -#: cps/web.py:1480 cps/web.py:1486 cps/web.py:1505 cps/web.py:1509 -#: cps/web.py:1515 +#: cps/templates/layout.html:85 cps/templates/register.html:17 cps/web.py:1551 +#: cps/web.py:1558 cps/web.py:1564 cps/web.py:1583 cps/web.py:1587 +#: cps/web.py:1593 msgid "Register" msgstr "Registe-se" -#: cps/web.py:1507 +#: cps/web.py:1585 msgid "Your e-mail is not allowed to register" msgstr "Seu e-mail não tem permissão para registrar" -#: cps/web.py:1510 +#: cps/web.py:1588 msgid "Confirmation e-mail was send to your e-mail account." msgstr "O e-mail de confirmação foi enviado para a sua conta de e-mail." -#: cps/web.py:1524 +#: cps/web.py:1602 msgid "Cannot activate LDAP authentication" msgstr "Não é possível ativar a autenticação LDAP" -#: cps/web.py:1543 +#: cps/web.py:1621 #, python-format msgid "Fallback Login as: '%(nickname)s', LDAP Server not reachable, or user not known" msgstr "Login de reserva como:'%(nickname)s', servidor LDAP não acessível ou usuário desconhecido" -#: cps/web.py:1549 +#: cps/web.py:1627 #, python-format msgid "Could not login: %(message)s" msgstr "Não foi possível fazer o login: %(message)s" -#: cps/web.py:1553 cps/web.py:1578 +#: cps/web.py:1631 cps/web.py:1656 msgid "Wrong Username or Password" msgstr "Nome de usuário ou senha incorretos" -#: cps/web.py:1560 +#: cps/web.py:1638 msgid "New Password was send to your email address" msgstr "Nova senha foi enviada para seu endereço de e-mail" -#: cps/web.py:1566 +#: cps/web.py:1644 msgid "Please enter valid username to reset password" msgstr "Por favor, digite um nome de usuário válido para redefinir a senha" -#: cps/web.py:1573 +#: cps/web.py:1651 #, python-format msgid "You are now logged in as: '%(nickname)s'" msgstr "Você agora está logado como: '%(nickname)s'" -#: cps/web.py:1639 cps/web.py:1688 +#: cps/web.py:1717 cps/web.py:1766 #, python-format msgid "%(name)s's profile" msgstr "Perfil de %(name)s's" -#: cps/web.py:1655 +#: cps/web.py:1733 msgid "Profile updated" msgstr "Perfil atualizado" @@ -1321,36 +1345,36 @@ msgstr "Perfil atualizado" msgid "Found no valid gmail.json file with OAuth information" msgstr "" -#: cps/tasks/convert.py:137 +#: cps/tasks/convert.py:154 #, python-format msgid "Calibre ebook-convert %(tool)s not found" msgstr "Calibre ebook-convert %(tool)s não encontrado" -#: cps/tasks/convert.py:163 +#: cps/tasks/convert.py:187 #, python-format msgid "%(format)s format not found on disk" msgstr "Formato %(format)s não encontrado no disco" -#: cps/tasks/convert.py:167 +#: cps/tasks/convert.py:191 msgid "Ebook converter failed with unknown error" msgstr "O conversor de Ebook falhou com erro desconhecido" -#: cps/tasks/convert.py:177 +#: cps/tasks/convert.py:201 #, python-format msgid "Kepubify-converter failed: %(error)s" msgstr "O conversor de Kepubify falhou: %(error)s" -#: cps/tasks/convert.py:199 +#: cps/tasks/convert.py:223 #, python-format msgid "Converted file not found or more than one file in folder %(folder)s" msgstr "Arquivo convertido não encontrado ou mais de um arquivo na pasta %(folder)s" -#: cps/tasks/convert.py:222 +#: cps/tasks/convert.py:246 #, python-format msgid "Ebook-converter failed: %(error)s" msgstr "Conversor de ebook falhou: %(error)s" -#: cps/tasks/convert.py:245 +#: cps/tasks/convert.py:269 #, python-format msgid "Calibre failed with error: %(error)s" msgstr "Calibre falhou com erro: %(error)s" @@ -1405,7 +1429,7 @@ msgid "Edit" msgstr "Editar" #: cps/templates/admin.html:25 cps/templates/book_edit.html:16 -#: cps/templates/book_table.html:97 cps/templates/modal_dialogs.html:63 +#: cps/templates/book_table.html:100 cps/templates/modal_dialogs.html:63 #: cps/templates/modal_dialogs.html:116 cps/templates/user_edit.html:67 #: cps/templates/user_table.html:149 msgid "Delete" @@ -1415,180 +1439,180 @@ msgstr "Eliminar" msgid "Public Shelf" msgstr "Estante Pública" -#: cps/templates/admin.html:51 +#: cps/templates/admin.html:53 msgid "Add New User" msgstr "Adicionar Novo Usuário" -#: cps/templates/admin.html:53 +#: cps/templates/admin.html:55 msgid "Import LDAP Users" msgstr "Importar usuários LDAP" -#: cps/templates/admin.html:60 +#: cps/templates/admin.html:62 msgid "E-mail Server Settings" msgstr "Configurações do servidor de e-mail" -#: cps/templates/admin.html:65 cps/templates/email_edit.html:31 +#: cps/templates/admin.html:67 cps/templates/email_edit.html:31 msgid "SMTP Hostname" msgstr "SMTP Nome do anfitrião" -#: cps/templates/admin.html:69 cps/templates/email_edit.html:35 +#: cps/templates/admin.html:71 cps/templates/email_edit.html:35 msgid "SMTP Port" msgstr "Porto SMTP" -#: cps/templates/admin.html:73 cps/templates/email_edit.html:39 +#: cps/templates/admin.html:75 cps/templates/email_edit.html:39 msgid "Encryption" msgstr "Criptografia" -#: cps/templates/admin.html:77 cps/templates/email_edit.html:47 +#: cps/templates/admin.html:79 cps/templates/email_edit.html:47 msgid "SMTP Login" msgstr "Login SMTP" -#: cps/templates/admin.html:81 cps/templates/admin.html:92 +#: cps/templates/admin.html:83 cps/templates/admin.html:94 #: cps/templates/email_edit.html:55 msgid "From E-mail" msgstr "Do E-mail" -#: cps/templates/admin.html:88 +#: cps/templates/admin.html:90 msgid "E-Mail Service" msgstr "" -#: cps/templates/admin.html:89 +#: cps/templates/admin.html:91 msgid "Gmail via Oauth2" msgstr "" -#: cps/templates/admin.html:104 +#: cps/templates/admin.html:106 msgid "Configuration" msgstr "Configuração" -#: cps/templates/admin.html:107 +#: cps/templates/admin.html:109 msgid "Calibre Database Directory" msgstr "Diretório do Banco de Dados de Calibres" -#: cps/templates/admin.html:111 cps/templates/config_edit.html:68 +#: cps/templates/admin.html:113 cps/templates/config_edit.html:68 msgid "Log Level" msgstr "Nível de registo" -#: cps/templates/admin.html:115 +#: cps/templates/admin.html:117 msgid "Port" msgstr "Porto" -#: cps/templates/admin.html:120 +#: cps/templates/admin.html:122 msgid "External Port" msgstr "Porto externo" -#: cps/templates/admin.html:127 cps/templates/config_view_edit.html:28 +#: cps/templates/admin.html:129 cps/templates/config_view_edit.html:28 msgid "Books per Page" msgstr "Livros por página" -#: cps/templates/admin.html:131 +#: cps/templates/admin.html:133 msgid "Uploads" msgstr "Uploads" -#: cps/templates/admin.html:135 +#: cps/templates/admin.html:137 msgid "Anonymous Browsing" msgstr "Navegação Anónima" -#: cps/templates/admin.html:139 +#: cps/templates/admin.html:141 msgid "Public Registration" msgstr "Inscrição Pública" -#: cps/templates/admin.html:143 +#: cps/templates/admin.html:145 msgid "Magic Link Remote Login" msgstr "Login remoto Magic Link" -#: cps/templates/admin.html:147 +#: cps/templates/admin.html:149 msgid "Reverse Proxy Login" msgstr "Login de Proxy Reversa" -#: cps/templates/admin.html:152 cps/templates/config_edit.html:173 +#: cps/templates/admin.html:154 cps/templates/config_edit.html:173 msgid "Reverse Proxy Header Name" msgstr "Nome do cabeçalho do Proxy Reverso" -#: cps/templates/admin.html:157 +#: cps/templates/admin.html:159 #, fuzzy msgid "Edit Calibre Database Configuration" msgstr "Editar Configuração Básica" -#: cps/templates/admin.html:158 +#: cps/templates/admin.html:160 msgid "Edit Basic Configuration" msgstr "Editar Configuração Básica" -#: cps/templates/admin.html:159 +#: cps/templates/admin.html:161 msgid "Edit UI Configuration" msgstr "Editar configuração da IU" -#: cps/templates/admin.html:164 +#: cps/templates/admin.html:166 msgid "Administration" msgstr "Administração" -#: cps/templates/admin.html:165 +#: cps/templates/admin.html:167 msgid "Download Debug Package" msgstr "Download do Pacote de Depuração" -#: cps/templates/admin.html:166 +#: cps/templates/admin.html:168 msgid "View Logs" msgstr "Ver Logs" -#: cps/templates/admin.html:169 +#: cps/templates/admin.html:171 msgid "Reconnect Calibre Database" msgstr "Reconectar base de dados de calibração" -#: cps/templates/admin.html:170 +#: cps/templates/admin.html:172 msgid "Restart" msgstr "Reinicie" -#: cps/templates/admin.html:171 +#: cps/templates/admin.html:173 msgid "Shutdown" msgstr "Encerramento" -#: cps/templates/admin.html:176 +#: cps/templates/admin.html:178 msgid "Update" msgstr "Atualização" -#: cps/templates/admin.html:180 +#: cps/templates/admin.html:182 msgid "Version" msgstr "Versão" -#: cps/templates/admin.html:181 +#: cps/templates/admin.html:183 msgid "Details" msgstr "Detalhes" -#: cps/templates/admin.html:187 +#: cps/templates/admin.html:189 msgid "Current version" msgstr "Versão atual" -#: cps/templates/admin.html:194 +#: cps/templates/admin.html:196 msgid "Check for Update" msgstr "Verificar Atualizações" -#: cps/templates/admin.html:195 +#: cps/templates/admin.html:197 msgid "Perform Update" msgstr "Realizar Atualizações" -#: cps/templates/admin.html:208 +#: cps/templates/admin.html:210 msgid "Are you sure you want to restart?" msgstr "Tem a certeza que quer recomeçar?" -#: cps/templates/admin.html:213 cps/templates/admin.html:227 -#: cps/templates/admin.html:247 cps/templates/config_db.html:70 +#: cps/templates/admin.html:215 cps/templates/admin.html:229 +#: cps/templates/admin.html:249 cps/templates/config_db.html:70 msgid "OK" msgstr "Ok" -#: cps/templates/admin.html:214 cps/templates/admin.html:228 -#: cps/templates/book_edit.html:213 cps/templates/book_table.html:124 +#: cps/templates/admin.html:216 cps/templates/admin.html:230 +#: cps/templates/book_edit.html:213 cps/templates/book_table.html:127 #: cps/templates/config_db.html:54 cps/templates/config_edit.html:359 -#: cps/templates/config_view_edit.html:173 cps/templates/modal_dialogs.html:64 +#: cps/templates/config_view_edit.html:175 cps/templates/modal_dialogs.html:64 #: cps/templates/modal_dialogs.html:99 cps/templates/modal_dialogs.html:117 #: cps/templates/modal_dialogs.html:135 cps/templates/shelf_edit.html:27 #: cps/templates/user_edit.html:144 msgid "Cancel" msgstr "Cancelar" -#: cps/templates/admin.html:226 +#: cps/templates/admin.html:228 msgid "Are you sure you want to shutdown?" msgstr "Tens a certeza que queres fechar?" -#: cps/templates/admin.html:238 +#: cps/templates/admin.html:240 msgid "Updating, please do not reload this page" msgstr "Atualizando, por favor, não recarregue esta página" @@ -1600,44 +1624,43 @@ msgstr "via" msgid "In Library" msgstr "Na Biblioteca" -#: cps/templates/author.html:26 cps/templates/index.html:72 -#: cps/templates/search.html:29 cps/templates/shelf.html:19 +#: cps/templates/author.html:26 cps/templates/index.html:73 +#: cps/templates/search.html:30 cps/templates/shelf.html:19 msgid "Sort according to book date, newest first" msgstr "Classificar de acordo com a data do livro, o mais recente primeiro" -#: cps/templates/author.html:27 cps/templates/index.html:73 -#: cps/templates/search.html:30 cps/templates/shelf.html:20 +#: cps/templates/author.html:27 cps/templates/index.html:74 +#: cps/templates/search.html:31 cps/templates/shelf.html:20 msgid "Sort according to book date, oldest first" msgstr "Classificar de acordo com a data do livro, o mais antigo primeiro" -#: cps/templates/author.html:28 cps/templates/index.html:74 -#: cps/templates/search.html:31 cps/templates/shelf.html:21 +#: cps/templates/author.html:28 cps/templates/index.html:75 +#: cps/templates/search.html:32 cps/templates/shelf.html:21 msgid "Sort title in alphabetical order" msgstr "Classificar título em ordem alfabética" -#: cps/templates/author.html:29 cps/templates/index.html:75 -#: cps/templates/search.html:32 cps/templates/shelf.html:22 +#: cps/templates/author.html:29 cps/templates/index.html:76 +#: cps/templates/search.html:33 cps/templates/shelf.html:22 msgid "Sort title in reverse alphabetical order" msgstr "Classificar título em ordem alfabética inversa" -#: cps/templates/author.html:30 cps/templates/index.html:78 -#: cps/templates/search.html:35 cps/templates/shelf.html:25 +#: cps/templates/author.html:30 cps/templates/index.html:79 +#: cps/templates/search.html:36 cps/templates/shelf.html:25 msgid "Sort according to publishing date, newest first" msgstr "Classificar de acordo com a data de publicação, o mais novo primeiro" -#: cps/templates/author.html:31 cps/templates/index.html:79 -#: cps/templates/search.html:36 cps/templates/shelf.html:26 +#: cps/templates/author.html:31 cps/templates/index.html:80 +#: cps/templates/search.html:37 cps/templates/shelf.html:26 msgid "Sort according to publishing date, oldest first" msgstr "Classificar de acordo com a data de publicação, primeiro mais antigo" -#: cps/templates/author.html:57 cps/templates/author.html:117 -#: cps/templates/discover.html:30 cps/templates/index.html:29 -#: cps/templates/index.html:111 cps/templates/search.html:65 -#: cps/templates/shelf.html:54 +#: cps/templates/author.html:56 cps/templates/author.html:115 +#: cps/templates/index.html:29 cps/templates/index.html:112 +#: cps/templates/search.html:66 cps/templates/shelf.html:54 msgid "reduce" msgstr "reduzir" -#: cps/templates/author.html:101 +#: cps/templates/author.html:99 msgid "More by" msgstr "Mais por" @@ -1762,7 +1785,7 @@ msgid "Fetch Metadata" msgstr "Buscar Metadados" #: cps/templates/book_edit.html:212 cps/templates/config_db.html:53 -#: cps/templates/config_edit.html:358 cps/templates/config_view_edit.html:172 +#: cps/templates/config_edit.html:358 cps/templates/config_view_edit.html:174 #: cps/templates/email_edit.html:65 cps/templates/shelf_edit.html:25 #: cps/templates/shelf_order.html:41 cps/templates/user_edit.html:142 msgid "Save" @@ -1891,27 +1914,35 @@ msgstr "Digite o nome do domínio" msgid "Comments" msgstr "" -#: cps/templates/book_table.html:77 cps/templates/book_table.html:79 -#: cps/templates/book_table.html:81 cps/templates/book_table.html:83 -#: cps/templates/book_table.html:87 cps/templates/book_table.html:89 -#: cps/templates/book_table.html:91 cps/templates/book_table.html:93 +#: cps/templates/book_table.html:75 +msgid "Archiv Status" +msgstr "" + +#: cps/templates/book_table.html:77 cps/templates/search_form.html:42 +msgid "Read Status" +msgstr "Ler Estado" + +#: cps/templates/book_table.html:80 cps/templates/book_table.html:82 +#: cps/templates/book_table.html:84 cps/templates/book_table.html:86 +#: cps/templates/book_table.html:90 cps/templates/book_table.html:92 +#: cps/templates/book_table.html:96 #, fuzzy msgid "Enter " msgstr "Identificadores" -#: cps/templates/book_table.html:110 cps/templates/modal_dialogs.html:46 +#: cps/templates/book_table.html:113 cps/templates/modal_dialogs.html:46 msgid "Are you really sure?" msgstr "Tens mesmo a certeza?" -#: cps/templates/book_table.html:114 +#: cps/templates/book_table.html:117 msgid "Books with Title will be merged from:" msgstr "Os livros com título serão fundidos a partir de:" -#: cps/templates/book_table.html:118 +#: cps/templates/book_table.html:121 msgid "Into Book with Title:" msgstr "Into Book with Title:" -#: cps/templates/book_table.html:123 +#: cps/templates/book_table.html:126 msgid "Merge" msgstr "Fundir" @@ -2088,11 +2119,6 @@ msgstr "Porta do servidor LDAP" msgid "LDAP Encryption" msgstr "Criptografia LDAP" -#: cps/templates/config_edit.html:204 cps/templates/config_view_edit.html:62 -#: cps/templates/email_edit.html:41 -msgid "None" -msgstr "Nenhum" - #: cps/templates/config_edit.html:205 msgid "TLS" msgstr "TLS" @@ -2311,11 +2337,11 @@ msgstr "Visibilidades por defeito para novos utilizadores" msgid "Show Random Books in Detail View" msgstr "Mostrar Livros Aleatórios em Vista de Detalhe" -#: cps/templates/config_view_edit.html:165 cps/templates/user_edit.html:87 +#: cps/templates/config_view_edit.html:166 cps/templates/user_edit.html:87 msgid "Add Allowed/Denied Tags" msgstr "Adicionar Etiquetas permitidas/negadas" -#: cps/templates/config_view_edit.html:166 +#: cps/templates/config_view_edit.html:167 msgid "Add Allowed/Denied custom column values" msgstr "Adicionar valores permitidos/negados da coluna personalizada" @@ -2364,13 +2390,13 @@ msgstr "Arquivado em" msgid "Description:" msgstr "Descrição:" -#: cps/templates/detail.html:256 cps/templates/search.html:14 +#: cps/templates/detail.html:256 cps/templates/search.html:15 msgid "Add to shelf" msgstr "Adicionar à estante" #: cps/templates/detail.html:267 cps/templates/detail.html:284 #: cps/templates/feed.xml:79 cps/templates/layout.html:137 -#: cps/templates/search.html:20 +#: cps/templates/search.html:21 msgid "(Public)" msgstr "(Público)" @@ -2448,10 +2474,15 @@ msgstr "Domínios negados (Blacklist)" msgid "Next" msgstr "Próximo" -#: cps/templates/generate_kobo_auth_url.html:5 +#: cps/templates/generate_kobo_auth_url.html:6 msgid "Open the .kobo/Kobo eReader.conf file in a text editor and add (or edit):" msgstr "Abra o arquivo .kobo/Kobo eReader.conf em um editor de texto e adicione (ou edite):" +#: cps/templates/generate_kobo_auth_url.html:11 +#, fuzzy +msgid "Kobo Token:" +msgstr "Kobo Sync Token" + #: cps/templates/http_error.html:31 #, fuzzy msgid "Calibre-Web Instance is unconfigured, please contact your administrator" @@ -2469,29 +2500,29 @@ msgstr "Voltar para casa" msgid "Logout User" msgstr "" -#: cps/templates/index.html:69 +#: cps/templates/index.html:70 msgid "Sort ascending according to download count" msgstr "" -#: cps/templates/index.html:70 +#: cps/templates/index.html:71 msgid "Sort descending according to download count" msgstr "" -#: cps/templates/index.html:76 cps/templates/search.html:33 +#: cps/templates/index.html:77 cps/templates/search.html:34 #: cps/templates/shelf.html:23 msgid "Sort authors in alphabetical order" msgstr "Ordenar os autores em ordem alfabética" -#: cps/templates/index.html:77 cps/templates/search.html:34 +#: cps/templates/index.html:78 cps/templates/search.html:35 #: cps/templates/shelf.html:24 msgid "Sort authors in reverse alphabetical order" msgstr "Ordenar os autores em ordem alfabética inversa" -#: cps/templates/index.html:81 +#: cps/templates/index.html:82 msgid "Sort ascending according to series index" msgstr "Ordenar ascendente de acordo com o índice de série" -#: cps/templates/index.html:82 +#: cps/templates/index.html:83 msgid "Sort descending according to series index" msgstr "Ordenação decrescente de acordo com o índice de série" @@ -2927,10 +2958,6 @@ msgstr "Data de Publicação de" msgid "Published Date To" msgstr "Data de Publicação Até" -#: cps/templates/search_form.html:42 -msgid "Read Status" -msgstr "Ler Estado" - #: cps/templates/search_form.html:59 msgid "Exclude Tags" msgstr "Excluir Etiquetas" diff --git a/cps/translations/ru/LC_MESSAGES/messages.mo b/cps/translations/ru/LC_MESSAGES/messages.mo index 4a468171..68a9eb31 100644 Binary files a/cps/translations/ru/LC_MESSAGES/messages.mo and b/cps/translations/ru/LC_MESSAGES/messages.mo differ diff --git a/cps/translations/ru/LC_MESSAGES/messages.po b/cps/translations/ru/LC_MESSAGES/messages.po index 7e698243..a9077290 100644 --- a/cps/translations/ru/LC_MESSAGES/messages.po +++ b/cps/translations/ru/LC_MESSAGES/messages.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: Calibre-Web\n" "Report-Msgid-Bugs-To: https://github.com/janeczku/Calibre-Web\n" -"POT-Creation-Date: 2022-01-15 09:19+0100\n" +"POT-Creation-Date: 2022-04-18 20:01+0200\n" "PO-Revision-Date: 2020-04-29 01:20+0400\n" "Last-Translator: ZIZA\n" "Language: ru\n" @@ -17,589 +17,592 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.9.0\n" +"Generated-By: Babel 2.9.1\n" -#: cps/about.py:34 cps/about.py:49 cps/about.py:65 cps/converter.py:31 -msgid "not installed" -msgstr "не установлено" - -#: cps/about.py:47 cps/about.py:63 -msgid "installed" -msgstr "установлено" - -#: cps/about.py:145 +#: cps/about.py:86 msgid "Statistics" msgstr "Статистика" -#: cps/admin.py:144 +#: cps/admin.py:141 msgid "Server restarted, please reload page" msgstr "Сервер перезагружен, пожалуйста, обновите страницу" -#: cps/admin.py:146 +#: cps/admin.py:143 msgid "Performing shutdown of server, please close window" msgstr "Производится остановка сервера, пожалуйста, закройте окно" -#: cps/admin.py:154 +#: cps/admin.py:151 msgid "Reconnect successful" msgstr "Успешно переподключено" -#: cps/admin.py:157 +#: cps/admin.py:154 msgid "Unknown command" msgstr "Неизвестная команда" -#: cps/admin.py:167 cps/editbooks.py:707 cps/editbooks.py:721 -#: cps/editbooks.py:866 cps/editbooks.py:868 cps/editbooks.py:895 -#: cps/editbooks.py:911 cps/updater.py:584 cps/uploader.py:93 -#: cps/uploader.py:103 +#: cps/admin.py:176 cps/editbooks.py:713 cps/editbooks.py:892 +#: cps/editbooks.py:894 cps/editbooks.py:930 cps/editbooks.py:947 +#: cps/updater.py:608 cps/uploader.py:93 cps/uploader.py:103 msgid "Unknown" msgstr "Неизвестно" -#: cps/admin.py:188 +#: cps/admin.py:197 msgid "Admin page" msgstr "Администрирование" -#: cps/admin.py:207 +#: cps/admin.py:217 msgid "Basic Configuration" msgstr "Настройки сервера" -#: cps/admin.py:244 +#: cps/admin.py:255 msgid "UI Configuration" msgstr "Настройка интерфейса" -#: cps/admin.py:277 cps/templates/admin.html:50 +#: cps/admin.py:289 cps/templates/admin.html:51 #, fuzzy msgid "Edit Users" msgstr "Управление сервером" -#: cps/admin.py:318 cps/opds.py:109 cps/opds.py:198 cps/opds.py:275 -#: cps/opds.py:327 cps/templates/grid.html:13 cps/templates/languages.html:9 +#: cps/admin.py:333 cps/opds.py:529 cps/templates/grid.html:13 #: cps/templates/list.html:13 msgid "All" msgstr "Все" -#: cps/admin.py:343 cps/admin.py:1615 +#: cps/admin.py:360 cps/admin.py:1648 msgid "User not found" msgstr "" -#: cps/admin.py:357 +#: cps/admin.py:374 msgid "{} users deleted successfully" msgstr "" -#: cps/admin.py:379 cps/templates/config_view_edit.html:133 +#: cps/admin.py:397 cps/templates/config_view_edit.html:133 #: cps/templates/user_edit.html:45 cps/templates/user_table.html:81 msgid "Show All" msgstr "Показать все" -#: cps/admin.py:400 cps/admin.py:406 +#: cps/admin.py:418 cps/admin.py:424 msgid "Malformed request" msgstr "" -#: cps/admin.py:418 cps/admin.py:1493 +#: cps/admin.py:436 cps/admin.py:1526 msgid "Guest Name can't be changed" msgstr "" -#: cps/admin.py:430 +#: cps/admin.py:448 msgid "Guest can't have this role" msgstr "" -#: cps/admin.py:442 cps/admin.py:1451 +#: cps/admin.py:460 cps/admin.py:1484 msgid "No admin user remaining, can't remove admin role" msgstr "" -#: cps/admin.py:446 cps/admin.py:460 +#: cps/admin.py:464 cps/admin.py:478 msgid "Value has to be true or false" msgstr "" -#: cps/admin.py:448 +#: cps/admin.py:466 msgid "Invalid role" msgstr "" -#: cps/admin.py:452 +#: cps/admin.py:470 msgid "Guest can't have this view" msgstr "" -#: cps/admin.py:462 +#: cps/admin.py:480 msgid "Invalid view" msgstr "" -#: cps/admin.py:465 +#: cps/admin.py:483 msgid "Guest's Locale is determined automatically and can't be set" msgstr "" -#: cps/admin.py:469 +#: cps/admin.py:487 msgid "No Valid Locale Given" msgstr "" -#: cps/admin.py:480 +#: cps/admin.py:498 msgid "No Valid Book Language Given" msgstr "" -#: cps/admin.py:482 +#: cps/admin.py:500 cps/editbooks.py:1267 msgid "Parameter not found" msgstr "" -#: cps/admin.py:533 +#: cps/admin.py:553 msgid "Invalid Read Column" msgstr "" -#: cps/admin.py:539 +#: cps/admin.py:559 msgid "Invalid Restricted Column" msgstr "" -#: cps/admin.py:560 cps/admin.py:1323 +#: cps/admin.py:579 cps/admin.py:1355 msgid "Calibre-Web configuration updated" msgstr "Конфигурация Calibre-Web обновлена" -#: cps/admin.py:572 +#: cps/admin.py:591 msgid "Do you really want to delete the Kobo Token?" msgstr "Вы действительно хотите удалить Kobo Token ?" -#: cps/admin.py:574 +#: cps/admin.py:593 msgid "Do you really want to delete this domain?" msgstr "" -#: cps/admin.py:576 +#: cps/admin.py:595 msgid "Do you really want to delete this user?" msgstr "" -#: cps/admin.py:578 +#: cps/admin.py:597 msgid "Are you sure you want to delete this shelf?" msgstr "Вы действительно хотите удалить эту книжную полку?" -#: cps/admin.py:580 +#: cps/admin.py:599 #, fuzzy msgid "Are you sure you want to change locales of selected user(s)?" msgstr "Вы действительно хотите удалить эту книжную полку?" -#: cps/admin.py:582 +#: cps/admin.py:601 msgid "Are you sure you want to change visible book languages for selected user(s)?" msgstr "" -#: cps/admin.py:584 +#: cps/admin.py:603 msgid "Are you sure you want to change the selected role for the selected user(s)?" msgstr "" -#: cps/admin.py:586 +#: cps/admin.py:605 #, fuzzy msgid "Are you sure you want to change the selected restrictions for the selected user(s)?" msgstr "Вы действительно хотите удалить эту книжную полку?" -#: cps/admin.py:588 +#: cps/admin.py:607 msgid "Are you sure you want to change the selected visibility restrictions for the selected user(s)?" msgstr "" -#: cps/admin.py:590 +#: cps/admin.py:610 #, fuzzy msgid "Are you sure you want to change shelf sync behavior for the selected user(s)?" msgstr "Вы действительно хотите удалить эту книжную полку?" -#: cps/admin.py:592 +#: cps/admin.py:612 #, fuzzy msgid "Are you sure you want to change Calibre library location?" msgstr "Вы действительно хотите остановить Calibre-Web?" -#: cps/admin.py:594 +#: cps/admin.py:614 msgid "Are you sure you want delete Calibre-Web's sync database to force a full sync with your Kobo Reader?" msgstr "" -#: cps/admin.py:743 +#: cps/admin.py:764 msgid "Tag not found" msgstr "" -#: cps/admin.py:755 +#: cps/admin.py:776 msgid "Invalid Action" msgstr "" -#: cps/admin.py:871 cps/admin.py:877 cps/admin.py:887 cps/admin.py:897 +#: cps/admin.py:893 cps/admin.py:899 cps/admin.py:909 cps/admin.py:919 #: cps/templates/modal_dialogs.html:29 cps/templates/user_table.html:41 #: cps/templates/user_table.html:58 msgid "Deny" msgstr "Запретить" -#: cps/admin.py:873 cps/admin.py:879 cps/admin.py:889 cps/admin.py:899 +#: cps/admin.py:895 cps/admin.py:901 cps/admin.py:911 cps/admin.py:921 #: cps/templates/modal_dialogs.html:28 cps/templates/user_table.html:44 #: cps/templates/user_table.html:61 msgid "Allow" msgstr "Разрешить" -#: cps/admin.py:913 +#: cps/admin.py:936 msgid "{} sync entries deleted" msgstr "" -#: cps/admin.py:1036 +#: cps/admin.py:1059 msgid "client_secrets.json Is Not Configured For Web Application" msgstr "client_secrets.json не настроен для веб-приложения" -#: cps/admin.py:1081 +#: cps/admin.py:1104 msgid "Logfile Location is not Valid, Please Enter Correct Path" msgstr "Неправильное расположение файла журнала, пожалуйста, введите правильный путь." -#: cps/admin.py:1087 +#: cps/admin.py:1110 msgid "Access Logfile Location is not Valid, Please Enter Correct Path" msgstr "Недопустимое расположение файла журнала доступа, пожалуйста, введите правильный путь" -#: cps/admin.py:1117 +#: cps/admin.py:1140 msgid "Please Enter a LDAP Provider, Port, DN and User Object Identifier" msgstr "Пожалуйста, введите провайдера LDAP, порт, DN и идентификатор объекта пользователя" -#: cps/admin.py:1123 +#: cps/admin.py:1146 #, fuzzy msgid "Please Enter a LDAP Service Account and Password" msgstr "Пожалуйста, введите действительное имя пользователя для сброса пароля" -#: cps/admin.py:1126 +#: cps/admin.py:1149 msgid "Please Enter a LDAP Service Account" msgstr "" -#: cps/admin.py:1131 +#: cps/admin.py:1154 #, python-format msgid "LDAP Group Object Filter Needs to Have One \"%s\" Format Identifier" msgstr "Фильтр объектов группы LDAP должен иметь один идентификатор формата \"%s\"" -#: cps/admin.py:1133 +#: cps/admin.py:1156 msgid "LDAP Group Object Filter Has Unmatched Parenthesis" msgstr "Фильтр объектов группы LDAP имеет незавершённые круглые скобки" -#: cps/admin.py:1137 +#: cps/admin.py:1160 #, python-format msgid "LDAP User Object Filter needs to Have One \"%s\" Format Identifier" msgstr "Фильтр объектов пользователя LDAP должен иметь один идентификатор формата \"%s\"" -#: cps/admin.py:1139 +#: cps/admin.py:1162 msgid "LDAP User Object Filter Has Unmatched Parenthesis" msgstr "Фильтр объектов пользователя LDAP имеет незавершенную круглую скобку" -#: cps/admin.py:1146 +#: cps/admin.py:1169 #, python-format msgid "LDAP Member User Filter needs to Have One \"%s\" Format Identifier" msgstr "" -#: cps/admin.py:1148 +#: cps/admin.py:1171 msgid "LDAP Member User Filter Has Unmatched Parenthesis" msgstr "" -#: cps/admin.py:1155 +#: cps/admin.py:1178 msgid "LDAP CACertificate, Certificate or Key Location is not Valid, Please Enter Correct Path" msgstr "" -#: cps/admin.py:1197 cps/admin.py:1308 cps/admin.py:1405 cps/admin.py:1521 -#: cps/admin.py:1590 cps/shelf.py:100 cps/shelf.py:160 cps/shelf.py:203 -#: cps/shelf.py:279 cps/shelf.py:341 cps/shelf.py:376 cps/shelf.py:451 -msgid "Settings DB is not Writeable" -msgstr "" - -#: cps/admin.py:1208 -msgid "DB Location is not Valid, Please Enter Correct Path" -msgstr "Расположение Базы Данных неверно, пожалуйста, введите правильный путь." - -#: cps/admin.py:1223 -msgid "DB is not Writeable" -msgstr "" - -#: cps/admin.py:1235 -msgid "Keyfile Location is not Valid, Please Enter Correct Path" -msgstr "Расположение ключевого файла неверно, пожалуйста, введите правильный путь" - -#: cps/admin.py:1239 -msgid "Certfile Location is not Valid, Please Enter Correct Path" -msgstr "Расположение Certfile не является действительным, пожалуйста, введите правильный путь" - -#: cps/admin.py:1346 -#, fuzzy -msgid "Database Settings updated" -msgstr "Настройки E-mail сервера обновлены" - -#: cps/admin.py:1354 -#, fuzzy -msgid "Database Configuration" -msgstr "Дополнительный Настройки" - -#: cps/admin.py:1370 cps/web.py:1479 -msgid "Please fill out all fields!" -msgstr "Пожалуйста, заполните все поля!" - -#: cps/admin.py:1378 -msgid "E-mail is not from valid domain" -msgstr "E-mail не из существующей доменной зоны" - -#: cps/admin.py:1384 cps/admin.py:1543 -msgid "Add new user" -msgstr "Добавить пользователя" - -#: cps/admin.py:1395 -#, python-format -msgid "User '%(user)s' created" -msgstr "Пользователь '%(user)s' добавлен" - -#: cps/admin.py:1401 -#, fuzzy -msgid "Found an existing account for this e-mail address or name." -msgstr "Для этого адреса электронной почты или логина уже есть учётная запись." - -#: cps/admin.py:1430 -#, python-format -msgid "User '%(nick)s' deleted" -msgstr "Пользователь '%(nick)s' удалён" - -#: cps/admin.py:1432 cps/admin.py:1433 -msgid "Can't delete Guest User" -msgstr "" - -#: cps/admin.py:1436 -msgid "No admin user remaining, can't delete user" -msgstr "Это последний администратор, невозможно удалить пользователя" - -#: cps/admin.py:1509 cps/admin.py:1634 -#, python-format -msgid "Edit User %(nick)s" -msgstr "Изменить пользователя %(nick)s" - -#: cps/admin.py:1513 -#, python-format -msgid "User '%(nick)s' updated" -msgstr "Пользователь '%(nick)s' обновлён" - -#: cps/admin.py:1517 cps/admin.py:1649 cps/web.py:1504 cps/web.py:1564 -msgid "An unknown error occurred. Please try again later." -msgstr "Неизвестная ошибка. Попробуйте позже." - -#: cps/admin.py:1552 cps/templates/admin.html:98 -msgid "Edit E-mail Server Settings" -msgstr "Изменить настройки SMTP" - -#: cps/admin.py:1571 -msgid "Gmail Account Verification Successful" -msgstr "" - -#: cps/admin.py:1597 -#, python-format -msgid "Test e-mail queued for sending to %(email)s, please check Tasks for result" -msgstr "" - -#: cps/admin.py:1600 -#, python-format -msgid "There was an error sending the Test e-mail: %(res)s" -msgstr "Произошла ошибка при отправке тестового письма на: %(res)s" - -#: cps/admin.py:1602 -msgid "Please configure your e-mail address first..." -msgstr "Пожалуйста, сначала настройте свой адрес электронной почты ..." - -#: cps/admin.py:1604 -msgid "E-mail server settings updated" -msgstr "Настройки E-mail сервера обновлены" - -#: cps/admin.py:1646 -#, python-format -msgid "Password for user %(user)s reset" -msgstr "Пароль для пользователя %(user)s сброшен" - -#: cps/admin.py:1652 cps/web.py:1444 -msgid "Please configure the SMTP mail settings first..." -msgstr "Пожалуйста, сперва настройте параметры SMTP....." - -#: cps/admin.py:1663 -msgid "Logfile viewer" -msgstr "Просмотр лога" - -#: cps/admin.py:1729 -msgid "Requesting update package" -msgstr "Проверка обновлений" - -#: cps/admin.py:1730 -msgid "Downloading update package" -msgstr "Загрузка обновлений" - -#: cps/admin.py:1731 -msgid "Unzipping update package" -msgstr "Распаковка обновлений" - -#: cps/admin.py:1732 -msgid "Replacing files" -msgstr "Замена файлов" - -#: cps/admin.py:1733 -msgid "Database connections are closed" -msgstr "Соединения с базой данных закрыты" - -#: cps/admin.py:1734 -msgid "Stopping server" -msgstr "Остановка сервера" - -#: cps/admin.py:1735 -msgid "Update finished, please press okay and reload page" -msgstr "Обновления установлены, нажмите ок и перезагрузите страницу" - -#: cps/admin.py:1736 cps/admin.py:1737 cps/admin.py:1738 cps/admin.py:1739 -#: cps/admin.py:1740 cps/admin.py:1741 -msgid "Update failed:" -msgstr "Ошибка обновления:" - -#: cps/admin.py:1736 cps/updater.py:385 cps/updater.py:595 cps/updater.py:597 -msgid "HTTP Error" -msgstr "Ошибка HTTP" - -#: cps/admin.py:1737 cps/updater.py:387 cps/updater.py:599 -msgid "Connection error" -msgstr "Ошибка соединения" - -#: cps/admin.py:1738 cps/updater.py:389 cps/updater.py:601 -msgid "Timeout while establishing connection" -msgstr "Тайм-аут при установлении соединения" - -#: cps/admin.py:1739 cps/updater.py:391 cps/updater.py:603 -msgid "General error" -msgstr "Общая ошибка" - -#: cps/admin.py:1740 -#, fuzzy -msgid "Update file could not be saved in temp dir" -msgstr "Не удалось сохранить файл обновления во временной папке." - -#: cps/admin.py:1741 -msgid "Files could not be replaced during update" -msgstr "" - -#: cps/admin.py:1765 -#, fuzzy -msgid "Failed to extract at least One LDAP User" -msgstr "Не удалось создать хотя бы одного пользователя LDAP" - -#: cps/admin.py:1810 -msgid "Failed to Create at Least One LDAP User" -msgstr "Не удалось создать хотя бы одного пользователя LDAP" - -#: cps/admin.py:1823 -#, python-format -msgid "Error: %(ldaperror)s" -msgstr "Ошибка: %(ldaperror)s" - -#: cps/admin.py:1827 -msgid "Error: No user returned in response of LDAP server" -msgstr "Ошибка: ни одного пользователя не найдено в ответ на запрос сервер LDAP" - -#: cps/admin.py:1860 -msgid "At Least One LDAP User Not Found in Database" -msgstr "По крайней мере, один пользователь LDAP не найден в базе данных" - -#: cps/admin.py:1862 -msgid "{} User Successfully Imported" -msgstr "" - -#: cps/converter.py:30 -msgid "not configured" -msgstr "не настроено" - -#: cps/converter.py:32 -msgid "Execution permissions missing" -msgstr "" - -#: cps/db.py:651 cps/web.py:667 cps/web.py:1155 -#, python-format -msgid "Custom Column No.%(column)d is not existing in calibre database" -msgstr "" - -#: cps/editbooks.py:300 cps/editbooks.py:302 -msgid "Book Format Successfully Deleted" -msgstr "" - -#: cps/editbooks.py:309 cps/editbooks.py:311 -msgid "Book Successfully Deleted" -msgstr "" - -#: cps/editbooks.py:361 -msgid "You are missing permissions to delete books" -msgstr "" - -#: cps/editbooks.py:376 cps/editbooks.py:763 cps/web.py:523 cps/web.py:1703 -#: cps/web.py:1744 cps/web.py:1811 -msgid "Oops! Selected book title is unavailable. File does not exist or is not accessible" -msgstr "Невозможно открыть книгу. Файл не существует или недоступен" - -#: cps/editbooks.py:410 -msgid "edit metadata" -msgstr "изменить метаданные" - -#: cps/editbooks.py:458 -#, python-format -msgid "%(seriesindex)s is not a valid number, skipping" -msgstr "" - -#: cps/editbooks.py:494 cps/editbooks.py:958 -#, fuzzy, python-format -msgid "'%(langname)s' is not a valid language" -msgstr "%(langname)s не допустимый язык" - -#: cps/editbooks.py:634 cps/editbooks.py:985 -#, python-format -msgid "File extension '%(ext)s' is not allowed to be uploaded to this server" -msgstr "Запрещена загрузка файлов с расширением '%(ext)s'" - -#: cps/editbooks.py:638 cps/editbooks.py:989 -msgid "File to be uploaded must have an extension" -msgstr "Загружаемый файл должен иметь расширение" - -#: cps/editbooks.py:650 -#, python-format -msgid "Failed to create path %(path)s (Permission denied)." -msgstr "Ошибка при создании пути %(path)s (Доступ запрещён)." - -#: cps/editbooks.py:655 -#, python-format -msgid "Failed to store file %(file)s." -msgstr "Не удалось сохранить файл %(file)s." - -#: cps/editbooks.py:673 cps/editbooks.py:1076 cps/web.py:1664 +#: cps/admin.py:1223 cps/admin.py:1339 cps/admin.py:1437 cps/admin.py:1554 +#: cps/admin.py:1623 cps/editbooks.py:678 cps/editbooks.py:882 +#: cps/editbooks.py:1130 cps/shelf.py:100 cps/shelf.py:160 cps/shelf.py:203 +#: cps/shelf.py:278 cps/shelf.py:343 cps/shelf.py:380 cps/shelf.py:456 +#: cps/web.py:1742 #, python-format msgid "Database error: %(error)s." msgstr "" -#: cps/editbooks.py:678 +#: cps/admin.py:1235 +msgid "DB Location is not Valid, Please Enter Correct Path" +msgstr "Расположение Базы Данных неверно, пожалуйста, введите правильный путь." + +#: cps/admin.py:1253 +msgid "DB is not Writeable" +msgstr "" + +#: cps/admin.py:1266 +msgid "Keyfile Location is not Valid, Please Enter Correct Path" +msgstr "Расположение ключевого файла неверно, пожалуйста, введите правильный путь" + +#: cps/admin.py:1270 +msgid "Certfile Location is not Valid, Please Enter Correct Path" +msgstr "Расположение Certfile не является действительным, пожалуйста, введите правильный путь" + +#: cps/admin.py:1378 +#, fuzzy +msgid "Database Settings updated" +msgstr "Настройки E-mail сервера обновлены" + +#: cps/admin.py:1386 +#, fuzzy +msgid "Database Configuration" +msgstr "Дополнительный Настройки" + +#: cps/admin.py:1402 cps/web.py:1557 +msgid "Please fill out all fields!" +msgstr "Пожалуйста, заполните все поля!" + +#: cps/admin.py:1410 +msgid "E-mail is not from valid domain" +msgstr "E-mail не из существующей доменной зоны" + +#: cps/admin.py:1416 cps/admin.py:1576 +msgid "Add new user" +msgstr "Добавить пользователя" + +#: cps/admin.py:1427 +#, python-format +msgid "User '%(user)s' created" +msgstr "Пользователь '%(user)s' добавлен" + +#: cps/admin.py:1433 +#, fuzzy +msgid "Found an existing account for this e-mail address or name." +msgstr "Для этого адреса электронной почты или логина уже есть учётная запись." + +#: cps/admin.py:1463 +#, python-format +msgid "User '%(nick)s' deleted" +msgstr "Пользователь '%(nick)s' удалён" + +#: cps/admin.py:1465 cps/admin.py:1466 +msgid "Can't delete Guest User" +msgstr "" + +#: cps/admin.py:1469 +msgid "No admin user remaining, can't delete user" +msgstr "Это последний администратор, невозможно удалить пользователя" + +#: cps/admin.py:1542 cps/admin.py:1667 +#, python-format +msgid "Edit User %(nick)s" +msgstr "Изменить пользователя %(nick)s" + +#: cps/admin.py:1546 +#, python-format +msgid "User '%(nick)s' updated" +msgstr "Пользователь '%(nick)s' обновлён" + +#: cps/admin.py:1550 cps/admin.py:1682 cps/web.py:1582 cps/web.py:1642 +msgid "An unknown error occurred. Please try again later." +msgstr "Неизвестная ошибка. Попробуйте позже." + +#: cps/admin.py:1585 cps/templates/admin.html:100 +msgid "Edit E-mail Server Settings" +msgstr "Изменить настройки SMTP" + +#: cps/admin.py:1604 +msgid "Gmail Account Verification Successful" +msgstr "" + +#: cps/admin.py:1630 +#, python-format +msgid "Test e-mail queued for sending to %(email)s, please check Tasks for result" +msgstr "" + +#: cps/admin.py:1633 +#, python-format +msgid "There was an error sending the Test e-mail: %(res)s" +msgstr "Произошла ошибка при отправке тестового письма на: %(res)s" + +#: cps/admin.py:1635 +msgid "Please configure your e-mail address first..." +msgstr "Пожалуйста, сначала настройте свой адрес электронной почты ..." + +#: cps/admin.py:1637 +msgid "E-mail server settings updated" +msgstr "Настройки E-mail сервера обновлены" + +#: cps/admin.py:1679 +#, python-format +msgid "Password for user %(user)s reset" +msgstr "Пароль для пользователя %(user)s сброшен" + +#: cps/admin.py:1685 cps/web.py:1522 +msgid "Please configure the SMTP mail settings first..." +msgstr "Пожалуйста, сперва настройте параметры SMTP....." + +#: cps/admin.py:1696 +msgid "Logfile viewer" +msgstr "Просмотр лога" + +#: cps/admin.py:1762 +msgid "Requesting update package" +msgstr "Проверка обновлений" + +#: cps/admin.py:1763 +msgid "Downloading update package" +msgstr "Загрузка обновлений" + +#: cps/admin.py:1764 +msgid "Unzipping update package" +msgstr "Распаковка обновлений" + +#: cps/admin.py:1765 +msgid "Replacing files" +msgstr "Замена файлов" + +#: cps/admin.py:1766 +msgid "Database connections are closed" +msgstr "Соединения с базой данных закрыты" + +#: cps/admin.py:1767 +msgid "Stopping server" +msgstr "Остановка сервера" + +#: cps/admin.py:1768 +msgid "Update finished, please press okay and reload page" +msgstr "Обновления установлены, нажмите ок и перезагрузите страницу" + +#: cps/admin.py:1769 cps/admin.py:1770 cps/admin.py:1771 cps/admin.py:1772 +#: cps/admin.py:1773 cps/admin.py:1774 +msgid "Update failed:" +msgstr "Ошибка обновления:" + +#: cps/admin.py:1769 cps/updater.py:384 cps/updater.py:619 cps/updater.py:621 +msgid "HTTP Error" +msgstr "Ошибка HTTP" + +#: cps/admin.py:1770 cps/updater.py:386 cps/updater.py:623 +msgid "Connection error" +msgstr "Ошибка соединения" + +#: cps/admin.py:1771 cps/updater.py:388 cps/updater.py:625 +msgid "Timeout while establishing connection" +msgstr "Тайм-аут при установлении соединения" + +#: cps/admin.py:1772 cps/updater.py:390 cps/updater.py:627 +msgid "General error" +msgstr "Общая ошибка" + +#: cps/admin.py:1773 +#, fuzzy +msgid "Update file could not be saved in temp dir" +msgstr "Не удалось сохранить файл обновления во временной папке." + +#: cps/admin.py:1774 +msgid "Files could not be replaced during update" +msgstr "" + +#: cps/admin.py:1798 +#, fuzzy +msgid "Failed to extract at least One LDAP User" +msgstr "Не удалось создать хотя бы одного пользователя LDAP" + +#: cps/admin.py:1843 +msgid "Failed to Create at Least One LDAP User" +msgstr "Не удалось создать хотя бы одного пользователя LDAP" + +#: cps/admin.py:1856 +#, python-format +msgid "Error: %(ldaperror)s" +msgstr "Ошибка: %(ldaperror)s" + +#: cps/admin.py:1860 +msgid "Error: No user returned in response of LDAP server" +msgstr "Ошибка: ни одного пользователя не найдено в ответ на запрос сервер LDAP" + +#: cps/admin.py:1893 +msgid "At Least One LDAP User Not Found in Database" +msgstr "По крайней мере, один пользователь LDAP не найден в базе данных" + +#: cps/admin.py:1895 +msgid "{} User Successfully Imported" +msgstr "" + +#: cps/converter.py:30 +msgid "not installed" +msgstr "не установлено" + +#: cps/converter.py:31 +msgid "Execution permissions missing" +msgstr "" + +#: cps/db.py:674 cps/web.py:710 cps/web.py:1222 +#, python-format +msgid "Custom Column No.%(column)d is not existing in calibre database" +msgstr "" + +#: cps/db.py:917 cps/templates/config_edit.html:204 +#: cps/templates/config_view_edit.html:62 cps/templates/email_edit.html:41 +#: cps/web.py:551 cps/web.py:585 cps/web.py:646 cps/web.py:671 cps/web.py:1003 +#: cps/web.py:1032 cps/web.py:1066 cps/web.py:1093 cps/web.py:1132 +msgid "None" +msgstr "Нет" + +#: cps/editbooks.py:295 cps/editbooks.py:297 +msgid "Book Format Successfully Deleted" +msgstr "" + +#: cps/editbooks.py:304 cps/editbooks.py:306 +msgid "Book Successfully Deleted" +msgstr "" + +#: cps/editbooks.py:358 +msgid "You are missing permissions to delete books" +msgstr "" + +#: cps/editbooks.py:373 cps/editbooks.py:765 cps/web.py:518 cps/web.py:1783 +#: cps/web.py:1825 cps/web.py:1870 +msgid "Oops! Selected book title is unavailable. File does not exist or is not accessible" +msgstr "Невозможно открыть книгу. Файл не существует или недоступен" + +#: cps/editbooks.py:408 +msgid "edit metadata" +msgstr "изменить метаданные" + +#: cps/editbooks.py:457 +#, python-format +msgid "%(seriesindex)s is not a valid number, skipping" +msgstr "" + +#: cps/editbooks.py:493 cps/editbooks.py:1001 +#, fuzzy, python-format +msgid "'%(langname)s' is not a valid language" +msgstr "%(langname)s не допустимый язык" + +#: cps/editbooks.py:634 +msgid "User has no rights to upload additional file formats" +msgstr "" + +#: cps/editbooks.py:639 cps/editbooks.py:1029 +#, python-format +msgid "File extension '%(ext)s' is not allowed to be uploaded to this server" +msgstr "Запрещена загрузка файлов с расширением '%(ext)s'" + +#: cps/editbooks.py:643 cps/editbooks.py:1033 +msgid "File to be uploaded must have an extension" +msgstr "Загружаемый файл должен иметь расширение" + +#: cps/editbooks.py:655 +#, python-format +msgid "Failed to create path %(path)s (Permission denied)." +msgstr "Ошибка при создании пути %(path)s (Доступ запрещён)." + +#: cps/editbooks.py:660 +#, python-format +msgid "Failed to store file %(file)s." +msgstr "Не удалось сохранить файл %(file)s." + +#: cps/editbooks.py:683 #, python-format msgid "File format %(ext)s added to %(book)s" msgstr "Формат файла %(ext)s добавлен в %(book)s" -#: cps/editbooks.py:814 +#: cps/editbooks.py:697 cps/editbooks.py:809 +msgid "User has no rights to upload cover" +msgstr "" + +#: cps/editbooks.py:828 msgid "Identifiers are not Case Sensitive, Overwriting Old Identifier" msgstr "" -#: cps/editbooks.py:848 +#: cps/editbooks.py:869 msgid "Metadata successfully updated" msgstr "Метаданные обновлены" -#: cps/editbooks.py:861 -msgid "Error editing book, please check logfile for details" -msgstr "Ошибка редактирования книги. Пожалуйста, проверьте лог-файл для дополнительной информации" +#: cps/editbooks.py:887 +msgid "Error editing book: {}" +msgstr "" -#: cps/editbooks.py:899 +#: cps/editbooks.py:951 msgid "Uploaded book probably exists in the library, consider to change before upload new: " msgstr "Загруженная книга, вероятно, существует в библиотеке, перед тем как загрузить новую, рассмотрите возможность изменения: " -#: cps/editbooks.py:997 +#: cps/editbooks.py:1041 #, python-format msgid "File %(filename)s could not saved to temp dir" msgstr "Файл %(filename)s не удалось сохранить во временную папку" -#: cps/editbooks.py:1016 +#: cps/editbooks.py:1061 #, python-format msgid "Failed to Move Cover File %(file)s: %(error)s" msgstr "" -#: cps/editbooks.py:1063 +#: cps/editbooks.py:1117 #, python-format msgid "File %(file)s uploaded" msgstr "Файл %(file)s загружен" -#: cps/editbooks.py:1088 +#: cps/editbooks.py:1143 msgid "Source or destination format for conversion missing" msgstr "Исходный или целевой формат для конвертирования отсутствует" -#: cps/editbooks.py:1096 +#: cps/editbooks.py:1151 #, python-format msgid "Book successfully queued for converting to %(book_format)s" msgstr "Книга успешно поставлена в очередь для конвертирования в %(book_format)s" -#: cps/editbooks.py:1100 +#: cps/editbooks.py:1155 #, python-format msgid "There was an error converting this book: %(res)s" msgstr "Произошла ошибка при конвертирования этой книги: %(res)s" @@ -612,175 +615,192 @@ msgstr "Настройка Google Drive не завершена, попробу msgid "Callback domain is not verified, please follow steps to verify domain in google developer console" msgstr "Не удалось проверить домен обратного вызова, пожалуйста, выполните шаги для проверки домена в консоли разработчика Google." -#: cps/helper.py:77 +#: cps/helper.py:81 #, python-format msgid "%(format)s format not found for book id: %(book)d" msgstr "%(format)s форма не найден для книги с id: %(book)d" -#: cps/helper.py:83 cps/tasks/convert.py:73 +#: cps/helper.py:87 cps/tasks/convert.py:75 #, python-format msgid "%(format)s not found on Google Drive: %(fn)s" msgstr "%(format)s не найден на Google Drive: %(fn)s" -#: cps/helper.py:88 +#: cps/helper.py:92 #, python-format msgid "%(format)s not found: %(fn)s" msgstr "%(format)s не найден: %(fn)s" -#: cps/helper.py:93 cps/helper.py:217 cps/templates/detail.html:41 +#: cps/helper.py:97 cps/helper.py:221 cps/templates/detail.html:41 #: cps/templates/detail.html:45 msgid "Send to Kindle" msgstr "Отправить на Kindle" -#: cps/helper.py:94 cps/helper.py:111 cps/helper.py:219 +#: cps/helper.py:98 cps/helper.py:115 cps/helper.py:223 msgid "This e-mail has been sent via Calibre-Web." msgstr "Это электронное письмо было отправлено через Caliber-Web." -#: cps/helper.py:109 +#: cps/helper.py:113 msgid "Calibre-Web test e-mail" msgstr "Тестовый e-mail для Calibre-Web" -#: cps/helper.py:110 +#: cps/helper.py:114 msgid "Test e-mail" msgstr "Тестовый e-mail" -#: cps/helper.py:127 +#: cps/helper.py:131 msgid "Get Started with Calibre-Web" msgstr "Начать работу с Calibre-Web" -#: cps/helper.py:132 +#: cps/helper.py:136 #, python-format msgid "Registration e-mail for user: %(name)s" msgstr "Регистрационный e-mail для пользователя: %(name)s" -#: cps/helper.py:143 cps/helper.py:149 +#: cps/helper.py:147 cps/helper.py:153 #, python-format msgid "Convert %(orig)s to %(format)s and send to Kindle" msgstr "Преобразовать %(orig)s в %(format)s и отправить в Kindle" -#: cps/helper.py:168 cps/helper.py:172 cps/helper.py:176 +#: cps/helper.py:172 cps/helper.py:176 cps/helper.py:180 #, python-format msgid "Send %(format)s to Kindle" msgstr "Отправить %(format)s в Kindle" -#: cps/helper.py:216 cps/tasks/convert.py:90 +#: cps/helper.py:220 cps/tasks/convert.py:92 #, fuzzy, python-format msgid "%(book)s send to Kindle" msgstr "Отправить на Kindle" -#: cps/helper.py:221 +#: cps/helper.py:225 msgid "The requested file could not be read. Maybe wrong permissions?" msgstr "Запрашиваемый файл не может быть прочитан. Возможно у вас нет разрешения?" -#: cps/helper.py:313 +#: cps/helper.py:353 +msgid "Read status could not set: {}" +msgstr "" + +#: cps/helper.py:376 #, python-format msgid "Deleting bookfolder for book %(id)s failed, path has subfolders: %(path)s" msgstr "" -#: cps/helper.py:319 +#: cps/helper.py:382 #, python-format msgid "Deleting book %(id)s failed: %(message)s" msgstr "" -#: cps/helper.py:330 +#: cps/helper.py:393 #, python-format msgid "Deleting book %(id)s from database only, book path in database not valid: %(path)s" msgstr "" -#: cps/helper.py:385 -#, python-format -msgid "Rename title from: '%(src)s' to '%(dest)s' failed with error: %(error)s" +#: cps/helper.py:458 +#, fuzzy, python-format +msgid "Rename author from: '%(src)s' to '%(dest)s' failed with error: %(error)s" msgstr "Переименовывание заголовка с: '%(src)s' на '%(dest)s' не удалось из-за ошибки: %(error)s" -#: cps/helper.py:400 -#, python-format -msgid "Rename file in path '%(src)s' to '%(dest)s' failed with error: %(error)s" -msgstr "Не удалось переименовать файл по пути '%(src)s' to '%(dest)s' из-за ошибки: %(error)s" - -#: cps/helper.py:425 cps/helper.py:435 cps/helper.py:443 +#: cps/helper.py:529 cps/helper.py:538 #, python-format msgid "File %(file)s not found on Google Drive" msgstr "Файл %(file)s не найден на Google Drive" -#: cps/helper.py:464 +#: cps/helper.py:572 +#, python-format +msgid "Rename title from: '%(src)s' to '%(dest)s' failed with error: %(error)s" +msgstr "Переименовывание заголовка с: '%(src)s' на '%(dest)s' не удалось из-за ошибки: %(error)s" + +#: cps/helper.py:592 +msgid "Error in rename file in path: {}" +msgstr "" + +#: cps/helper.py:610 #, python-format msgid "Book path %(path)s not found on Google Drive" msgstr "Путь книги %(path)s не найден на Google Drive" -#: cps/helper.py:504 cps/web.py:1659 +#: cps/helper.py:651 cps/web.py:1737 #, fuzzy msgid "Found an existing account for this e-mail address" msgstr "Этот адрес электронной почты уже зарегистрирован." -#: cps/helper.py:512 +#: cps/helper.py:659 msgid "This username is already taken" msgstr "Это имя пользователя уже занято" -#: cps/helper.py:522 +#: cps/helper.py:669 msgid "Invalid e-mail address format" msgstr "" -#: cps/helper.py:595 +#: cps/helper.py:754 +msgid "Python modul 'advocate' is not installed but is needed for cover downloads" +msgstr "" + +#: cps/helper.py:767 msgid "Error Downloading Cover" msgstr "" -#: cps/helper.py:598 +#: cps/helper.py:770 msgid "Cover Format Error" msgstr "" -#: cps/helper.py:608 +#: cps/helper.py:773 +msgid "You are not allowed to access localhost or the local network for cover uploads" +msgstr "" + +#: cps/helper.py:783 msgid "Failed to create path for cover" msgstr "Не удалось создать путь для обложки." -#: cps/helper.py:624 +#: cps/helper.py:799 msgid "Cover-file is not a valid image file, or could not be stored" msgstr "" -#: cps/helper.py:635 +#: cps/helper.py:810 msgid "Only jpg/jpeg/png/webp/bmp files are supported as coverfile" msgstr "" -#: cps/helper.py:648 +#: cps/helper.py:822 msgid "Invalid cover file content" msgstr "" -#: cps/helper.py:652 +#: cps/helper.py:826 msgid "Only jpg/jpeg files are supported as coverfile" msgstr "Только файлы в формате jpg / jpeg поддерживаются как файл обложки" -#: cps/helper.py:704 +#: cps/helper.py:878 msgid "Unrar binary file not found" msgstr "" -#: cps/helper.py:715 +#: cps/helper.py:889 msgid "Error excecuting UnRar" msgstr "" -#: cps/helper.py:763 +#: cps/helper.py:937 msgid "Waiting" msgstr "Ожидание" -#: cps/helper.py:765 +#: cps/helper.py:939 msgid "Failed" msgstr "Неудачно" -#: cps/helper.py:767 +#: cps/helper.py:941 msgid "Started" msgstr "Начало" -#: cps/helper.py:769 +#: cps/helper.py:943 msgid "Finished" msgstr "Завершено" -#: cps/helper.py:771 +#: cps/helper.py:945 msgid "Unknown Status" msgstr "Неизвестный статус" -#: cps/kobo_auth.py:127 -msgid "PLease access calibre-web from non localhost to get valid api_endpoint for kobo device" +#: cps/kobo_auth.py:128 +#, fuzzy +msgid "Please access Calibre-Web from non localhost to get valid api_endpoint for kobo device" msgstr "Пожалуйста, подключитесь к Calibre-Web не с локального хоста, чтобы получить действительный api_endpoint для устройства Kobo" -#: cps/kobo_auth.py:130 cps/kobo_auth.py:158 +#: cps/kobo_auth.py:154 msgid "Kobo Setup" msgstr "Настройка Kobo" @@ -789,7 +809,7 @@ msgstr "Настройка Kobo" msgid "Register with %(provider)s" msgstr "Зарегистрируйтесь с %(provider)s" -#: cps/oauth_bb.py:138 cps/remotelogin.py:133 cps/web.py:1535 +#: cps/oauth_bb.py:138 cps/remotelogin.py:130 cps/web.py:1613 #, python-format msgid "you are now logged in as: '%(nickname)s'" msgstr "вы вошли как пользователь '%(nickname)s'" @@ -850,163 +870,163 @@ msgstr "Ошибка Google Oauth, пожалуйста попробуйте п msgid "Google Oauth error: {}" msgstr "" -#: cps/opds.py:384 +#: cps/opds.py:298 msgid "{} Stars" msgstr "" -#: cps/remotelogin.py:65 cps/templates/layout.html:84 -#: cps/templates/login.html:4 cps/templates/login.html:21 cps/web.py:1584 +#: cps/remotelogin.py:62 cps/templates/layout.html:84 +#: cps/templates/login.html:4 cps/templates/login.html:21 cps/web.py:1662 msgid "Login" msgstr "Логин" -#: cps/remotelogin.py:77 cps/remotelogin.py:111 +#: cps/remotelogin.py:74 cps/remotelogin.py:108 msgid "Token not found" msgstr "Ключ не найден" -#: cps/remotelogin.py:86 cps/remotelogin.py:119 +#: cps/remotelogin.py:83 cps/remotelogin.py:116 msgid "Token has expired" msgstr "Ключ просрочен" -#: cps/remotelogin.py:95 +#: cps/remotelogin.py:92 msgid "Success! Please return to your device" msgstr "Успешно! Пожалуйста, проверьте свое устройство" -#: cps/render_template.py:39 cps/web.py:416 +#: cps/render_template.py:41 cps/web.py:407 msgid "Books" msgstr "Книги" -#: cps/render_template.py:41 +#: cps/render_template.py:43 msgid "Show recent books" msgstr "Показывать недавние книги" -#: cps/render_template.py:42 cps/templates/index.xml:25 +#: cps/render_template.py:44 cps/templates/index.xml:25 msgid "Hot Books" msgstr "Популярные Книги" -#: cps/render_template.py:44 +#: cps/render_template.py:46 msgid "Show Hot Books" msgstr "Показывать популярные книги" -#: cps/render_template.py:46 cps/render_template.py:51 +#: cps/render_template.py:48 cps/render_template.py:53 msgid "Downloaded Books" msgstr "" -#: cps/render_template.py:48 cps/render_template.py:53 +#: cps/render_template.py:50 cps/render_template.py:55 #: cps/templates/user_table.html:167 msgid "Show Downloaded Books" msgstr "" -#: cps/render_template.py:56 cps/templates/index.xml:32 cps/web.py:430 +#: cps/render_template.py:58 cps/templates/index.xml:32 cps/web.py:422 msgid "Top Rated Books" msgstr "Книги с наилучшим рейтингом" -#: cps/render_template.py:58 cps/templates/user_table.html:161 +#: cps/render_template.py:60 cps/templates/user_table.html:161 msgid "Show Top Rated Books" msgstr "Показывать книги с наивысшим рейтингом" -#: cps/render_template.py:59 cps/templates/index.xml:54 -#: cps/templates/index.xml:58 cps/web.py:676 +#: cps/render_template.py:61 cps/templates/index.xml:54 +#: cps/templates/index.xml:58 cps/web.py:729 msgid "Read Books" msgstr "Прочитанные Книги" -#: cps/render_template.py:61 +#: cps/render_template.py:63 msgid "Show read and unread" msgstr "Показывать прочитанные и непрочитанные" -#: cps/render_template.py:63 cps/templates/index.xml:61 -#: cps/templates/index.xml:65 cps/web.py:679 +#: cps/render_template.py:65 cps/templates/index.xml:61 +#: cps/templates/index.xml:65 cps/web.py:732 msgid "Unread Books" msgstr "Непрочитанные Книги" -#: cps/render_template.py:65 +#: cps/render_template.py:67 msgid "Show unread" msgstr "Показать непрочитанное" -#: cps/render_template.py:66 +#: cps/render_template.py:68 msgid "Discover" msgstr "Обзор" -#: cps/render_template.py:68 cps/templates/index.xml:50 +#: cps/render_template.py:70 cps/templates/index.xml:50 #: cps/templates/user_table.html:162 msgid "Show Random Books" msgstr "Показывать Случайные Книги" -#: cps/render_template.py:69 cps/templates/book_table.html:67 -#: cps/templates/index.xml:83 cps/web.py:1041 +#: cps/render_template.py:71 cps/templates/book_table.html:67 +#: cps/templates/index.xml:83 cps/web.py:1135 msgid "Categories" msgstr "Категории" -#: cps/render_template.py:71 cps/templates/user_table.html:158 +#: cps/render_template.py:73 cps/templates/user_table.html:158 msgid "Show category selection" msgstr "Показывать выбор категории" -#: cps/render_template.py:72 cps/templates/book_edit.html:90 +#: cps/render_template.py:74 cps/templates/book_edit.html:90 #: cps/templates/book_table.html:68 cps/templates/index.xml:90 -#: cps/templates/search_form.html:69 cps/web.py:948 cps/web.py:959 +#: cps/templates/search_form.html:69 cps/web.py:1034 cps/web.py:1041 msgid "Series" msgstr "Серии" -#: cps/render_template.py:74 cps/templates/user_table.html:157 +#: cps/render_template.py:76 cps/templates/user_table.html:157 msgid "Show series selection" msgstr "Показывать выбор серии" -#: cps/render_template.py:75 cps/templates/book_table.html:66 +#: cps/render_template.py:77 cps/templates/book_table.html:66 #: cps/templates/index.xml:69 msgid "Authors" msgstr "Авторы" -#: cps/render_template.py:77 cps/templates/user_table.html:160 +#: cps/render_template.py:79 cps/templates/user_table.html:160 msgid "Show author selection" msgstr "Показывать выбор автора" -#: cps/render_template.py:79 cps/templates/book_table.html:72 -#: cps/templates/index.xml:76 cps/web.py:925 +#: cps/render_template.py:81 cps/templates/book_table.html:72 +#: cps/templates/index.xml:76 cps/web.py:1006 msgid "Publishers" msgstr "Издатели" -#: cps/render_template.py:81 cps/templates/user_table.html:163 +#: cps/render_template.py:83 cps/templates/user_table.html:163 msgid "Show publisher selection" msgstr "Показать выбор издателя" -#: cps/render_template.py:82 cps/templates/book_table.html:70 +#: cps/render_template.py:84 cps/templates/book_table.html:70 #: cps/templates/index.xml:97 cps/templates/search_form.html:107 -#: cps/web.py:1018 +#: cps/web.py:1108 msgid "Languages" msgstr "Языки" -#: cps/render_template.py:85 cps/templates/user_table.html:155 +#: cps/render_template.py:87 cps/templates/user_table.html:155 msgid "Show language selection" msgstr "Показывать выбор языка" -#: cps/render_template.py:86 cps/templates/index.xml:104 +#: cps/render_template.py:88 cps/templates/index.xml:104 msgid "Ratings" msgstr "Рейтинги" -#: cps/render_template.py:88 cps/templates/user_table.html:164 +#: cps/render_template.py:90 cps/templates/user_table.html:164 msgid "Show ratings selection" msgstr "Показать выбор рейтинга" -#: cps/render_template.py:89 cps/templates/index.xml:112 +#: cps/render_template.py:91 cps/templates/index.xml:112 msgid "File formats" msgstr "Форматы файлов" -#: cps/render_template.py:91 cps/templates/user_table.html:165 +#: cps/render_template.py:93 cps/templates/user_table.html:165 msgid "Show file formats selection" msgstr "Показать выбор форматов файлов" -#: cps/render_template.py:93 cps/web.py:703 +#: cps/render_template.py:95 cps/web.py:755 msgid "Archived Books" msgstr "" -#: cps/render_template.py:95 cps/templates/user_table.html:166 +#: cps/render_template.py:97 cps/templates/user_table.html:166 msgid "Show archived books" msgstr "" -#: cps/render_template.py:97 cps/web.py:780 +#: cps/render_template.py:100 cps/web.py:837 msgid "Books List" msgstr "" -#: cps/render_template.py:99 cps/templates/user_table.html:168 +#: cps/render_template.py:102 cps/templates/user_table.html:168 msgid "Show Books List" msgstr "" @@ -1061,262 +1081,266 @@ msgstr "" msgid "Create a Shelf" msgstr "Создать полку" -#: cps/shelf.py:237 +#: cps/shelf.py:236 #, fuzzy msgid "Sorry you are not allowed to edit this shelf" msgstr "Извините, вы не можете удалить книгу с полки: %(sname)s" -#: cps/shelf.py:239 +#: cps/shelf.py:238 msgid "Edit a shelf" msgstr "Изменить полку" -#: cps/shelf.py:249 +#: cps/shelf.py:248 msgid "Sorry you are not allowed to create a public shelf" msgstr "" -#: cps/shelf.py:266 +#: cps/shelf.py:265 #, python-format msgid "Shelf %(title)s created" msgstr "Создана полка %(title)s" -#: cps/shelf.py:269 +#: cps/shelf.py:268 #, python-format msgid "Shelf %(title)s changed" msgstr "Колка %(title)s изменена" -#: cps/shelf.py:283 +#: cps/shelf.py:282 msgid "There was an error" msgstr "Произошла ошибка" -#: cps/shelf.py:305 +#: cps/shelf.py:304 #, python-format msgid "A public shelf with the name '%(title)s' already exists." msgstr "Публичная полка с названием '%(title)s' уже существует." -#: cps/shelf.py:316 +#: cps/shelf.py:315 #, python-format msgid "A private shelf with the name '%(title)s' already exists." msgstr "Приватная полка с названием '%(title)s' уже существует." #: cps/shelf.py:337 +msgid "Error deleting Shelf" +msgstr "" + +#: cps/shelf.py:339 #, fuzzy msgid "Shelf successfully deleted" msgstr "Метаданные обновлены" -#: cps/shelf.py:386 +#: cps/shelf.py:389 #, python-format msgid "Change order of Shelf: '%(name)s'" msgstr "Изменить расположение полки '%(name)s'" -#: cps/shelf.py:456 +#: cps/shelf.py:461 #, python-format msgid "Shelf: '%(name)s'" msgstr "Полка: '%(name)s'" -#: cps/shelf.py:460 +#: cps/shelf.py:465 msgid "Error opening shelf. Shelf does not exist or is not accessible" msgstr "Ошибка открытия Полки. Полка не существует или недоступна" -#: cps/updater.py:403 cps/updater.py:414 cps/updater.py:514 cps/updater.py:529 +#: cps/updater.py:426 cps/updater.py:437 cps/updater.py:538 cps/updater.py:553 msgid "Unexpected data while reading update information" msgstr "Некорректные данные при чтении информации об обновлении" -#: cps/updater.py:410 cps/updater.py:521 +#: cps/updater.py:433 cps/updater.py:545 msgid "No update available. You already have the latest version installed" msgstr "Нет доступных обновлений. Вы используете последнюю версию" -#: cps/updater.py:428 +#: cps/updater.py:451 msgid "A new update is available. Click on the button below to update to the latest version." msgstr "Новое обновление доступно. Нажмите на кнопку ниже, чтобы обновить до последней версии." -#: cps/updater.py:446 +#: cps/updater.py:469 msgid "Could not fetch update information" msgstr "Не удалось получить информацию об обновлении" -#: cps/updater.py:456 +#: cps/updater.py:479 msgid "Click on the button below to update to the latest stable version." msgstr "Нажмите на кнопку ниже для обновления до последней стабильной версии." -#: cps/updater.py:465 cps/updater.py:479 cps/updater.py:490 +#: cps/updater.py:488 cps/updater.py:502 cps/updater.py:513 #, python-format msgid "A new update is available. Click on the button below to update to version: %(version)s" msgstr "Новое обновление доступно. Нажмите на кнопку ниже, чтобы обновиться до версии: %(version)s" -#: cps/updater.py:507 +#: cps/updater.py:531 msgid "No release information available" msgstr "Информация о выпуске недоступна" -#: cps/templates/index.html:5 cps/web.py:440 +#: cps/templates/index.html:5 cps/web.py:434 msgid "Discover (Random Books)" msgstr "Обзор (Случайные Книги)" -#: cps/web.py:471 +#: cps/web.py:470 msgid "Hot Books (Most Downloaded)" msgstr "Популярные книги (часто загружаемые)" -#: cps/web.py:507 +#: cps/web.py:501 #, python-format msgid "Downloaded books by %(user)s" msgstr "" -#: cps/web.py:539 +#: cps/web.py:534 #, python-format msgid "Author: %(name)s" msgstr "Автор: %(name)s" -#: cps/web.py:554 +#: cps/web.py:570 #, python-format msgid "Publisher: %(name)s" msgstr "Издатель: %(name)s" -#: cps/web.py:569 +#: cps/web.py:598 #, python-format msgid "Series: %(serie)s" msgstr "Серии: %(serie)s" -#: cps/web.py:582 +#: cps/web.py:610 #, python-format msgid "Rating: %(rating)s stars" msgstr "Оценка: %(rating)s звезды(а)" -#: cps/web.py:597 +#: cps/web.py:626 #, python-format msgid "File format: %(format)s" msgstr "Формат файла: %(format)s" -#: cps/web.py:615 +#: cps/web.py:663 #, python-format msgid "Category: %(name)s" msgstr "Категория: %(name)s" -#: cps/web.py:631 +#: cps/web.py:690 #, python-format msgid "Language: %(name)s" msgstr "Язык: %(name)s" -#: cps/templates/layout.html:56 cps/web.py:737 cps/web.py:1371 +#: cps/templates/layout.html:56 cps/web.py:789 cps/web.py:1444 msgid "Advanced Search" msgstr "Расширенный поиск" #: cps/templates/book_edit.html:235 cps/templates/feed.xml:33 #: cps/templates/index.xml:11 cps/templates/layout.html:45 #: cps/templates/layout.html:48 cps/templates/search_form.html:226 -#: cps/web.py:750 cps/web.py:1077 +#: cps/web.py:807 cps/web.py:1164 msgid "Search" msgstr "Поиск" -#: cps/templates/admin.html:16 cps/web.py:903 +#: cps/templates/admin.html:16 cps/web.py:979 msgid "Downloads" msgstr "Скачать" -#: cps/web.py:980 +#: cps/web.py:1068 msgid "Ratings list" msgstr "Список рейтингов" -#: cps/web.py:1001 +#: cps/web.py:1095 msgid "File formats list" msgstr "Список форматов файлов" -#: cps/templates/layout.html:73 cps/templates/tasks.html:7 cps/web.py:1055 +#: cps/templates/layout.html:73 cps/templates/tasks.html:7 cps/web.py:1149 msgid "Tasks" msgstr "Задания" -#: cps/web.py:1215 +#: cps/web.py:1286 msgid "Published after " msgstr "Опубликовано после " -#: cps/web.py:1222 +#: cps/web.py:1293 msgid "Published before " msgstr "Опубликовано до " -#: cps/web.py:1244 +#: cps/web.py:1315 #, python-format msgid "Rating <= %(rating)s" msgstr "Рейтинг <= %(rating)s" -#: cps/web.py:1246 +#: cps/web.py:1317 #, python-format msgid "Rating >= %(rating)s" msgstr "Рейтинг >= %(rating)s" -#: cps/web.py:1248 +#: cps/web.py:1319 #, python-format msgid "Read Status = %(status)s" msgstr "" -#: cps/web.py:1353 +#: cps/web.py:1425 msgid "Error on search for custom columns, please restart Calibre-Web" msgstr "" -#: cps/web.py:1449 +#: cps/web.py:1527 #, python-format msgid "Book successfully queued for sending to %(kindlemail)s" msgstr "Книга успешно поставлена в очередь для отправки на %(kindlemail)s" -#: cps/web.py:1453 +#: cps/web.py:1531 #, python-format msgid "Oops! There was an error sending this book: %(res)s" msgstr "При отправке этой книги произошла ошибка: %(res)s" -#: cps/web.py:1455 +#: cps/web.py:1533 msgid "Please update your profile with a valid Send to Kindle E-mail Address." msgstr "Пожалуйста, сначала настройте e-mail на вашем kindle..." -#: cps/web.py:1472 +#: cps/web.py:1550 msgid "E-Mail server is not configured, please contact your administrator!" msgstr "Сервер электронной почты не настроен, обратитесь к администратору !" -#: cps/templates/layout.html:85 cps/templates/register.html:17 cps/web.py:1473 -#: cps/web.py:1480 cps/web.py:1486 cps/web.py:1505 cps/web.py:1509 -#: cps/web.py:1515 +#: cps/templates/layout.html:85 cps/templates/register.html:17 cps/web.py:1551 +#: cps/web.py:1558 cps/web.py:1564 cps/web.py:1583 cps/web.py:1587 +#: cps/web.py:1593 msgid "Register" msgstr "Зарегистрироваться" -#: cps/web.py:1507 +#: cps/web.py:1585 msgid "Your e-mail is not allowed to register" msgstr "Ваш e-mail не подходит для регистрации" -#: cps/web.py:1510 +#: cps/web.py:1588 msgid "Confirmation e-mail was send to your e-mail account." msgstr "Письмо с подтверждением отправлено вам на e-mail." -#: cps/web.py:1524 +#: cps/web.py:1602 msgid "Cannot activate LDAP authentication" msgstr "Не удается активировать LDAP аутентификацию" -#: cps/web.py:1543 +#: cps/web.py:1621 #, python-format msgid "Fallback Login as: '%(nickname)s', LDAP Server not reachable, or user not known" msgstr "Резервный вход в систему как: '%(nickname)s', LDAP-сервер недоступен или пользователь не известен" -#: cps/web.py:1549 +#: cps/web.py:1627 #, python-format msgid "Could not login: %(message)s" msgstr "Не удалось войти: %(message)s" -#: cps/web.py:1553 cps/web.py:1578 +#: cps/web.py:1631 cps/web.py:1656 msgid "Wrong Username or Password" msgstr "Ошибка в имени пользователя или пароле" -#: cps/web.py:1560 +#: cps/web.py:1638 msgid "New Password was send to your email address" msgstr "Новый пароль был отправлен на ваш адрес электронной почты" -#: cps/web.py:1566 +#: cps/web.py:1644 msgid "Please enter valid username to reset password" msgstr "Пожалуйста, введите действительное имя пользователя для сброса пароля" -#: cps/web.py:1573 +#: cps/web.py:1651 #, python-format msgid "You are now logged in as: '%(nickname)s'" msgstr "Вы вошли как: '%(nickname)s'" -#: cps/web.py:1639 cps/web.py:1688 +#: cps/web.py:1717 cps/web.py:1766 #, python-format msgid "%(name)s's profile" msgstr "Профиль %(name)s's" -#: cps/web.py:1655 +#: cps/web.py:1733 msgid "Profile updated" msgstr "Профиль обновлён" @@ -1324,36 +1348,36 @@ msgstr "Профиль обновлён" msgid "Found no valid gmail.json file with OAuth information" msgstr "" -#: cps/tasks/convert.py:137 +#: cps/tasks/convert.py:154 #, python-format msgid "Calibre ebook-convert %(tool)s not found" msgstr "" -#: cps/tasks/convert.py:163 +#: cps/tasks/convert.py:187 #, python-format msgid "%(format)s format not found on disk" msgstr "" -#: cps/tasks/convert.py:167 +#: cps/tasks/convert.py:191 msgid "Ebook converter failed with unknown error" msgstr "" -#: cps/tasks/convert.py:177 +#: cps/tasks/convert.py:201 #, python-format msgid "Kepubify-converter failed: %(error)s" msgstr "" -#: cps/tasks/convert.py:199 +#: cps/tasks/convert.py:223 #, python-format msgid "Converted file not found or more than one file in folder %(folder)s" msgstr "" -#: cps/tasks/convert.py:222 +#: cps/tasks/convert.py:246 #, python-format msgid "Ebook-converter failed: %(error)s" msgstr "Ошибка Ebook-конвертора: %(error)s" -#: cps/tasks/convert.py:245 +#: cps/tasks/convert.py:269 #, python-format msgid "Calibre failed with error: %(error)s" msgstr "" @@ -1408,7 +1432,7 @@ msgid "Edit" msgstr "Редактировать" #: cps/templates/admin.html:25 cps/templates/book_edit.html:16 -#: cps/templates/book_table.html:97 cps/templates/modal_dialogs.html:63 +#: cps/templates/book_table.html:100 cps/templates/modal_dialogs.html:63 #: cps/templates/modal_dialogs.html:116 cps/templates/user_edit.html:67 #: cps/templates/user_table.html:149 msgid "Delete" @@ -1418,180 +1442,180 @@ msgstr "Удалить" msgid "Public Shelf" msgstr "" -#: cps/templates/admin.html:51 +#: cps/templates/admin.html:53 msgid "Add New User" msgstr "Добавить нового пользователя" -#: cps/templates/admin.html:53 +#: cps/templates/admin.html:55 msgid "Import LDAP Users" msgstr "Импорт пользователей LDAP" -#: cps/templates/admin.html:60 +#: cps/templates/admin.html:62 msgid "E-mail Server Settings" msgstr "Настройки SMTP-сервера" -#: cps/templates/admin.html:65 cps/templates/email_edit.html:31 +#: cps/templates/admin.html:67 cps/templates/email_edit.html:31 msgid "SMTP Hostname" msgstr "SMTP-сервер" -#: cps/templates/admin.html:69 cps/templates/email_edit.html:35 +#: cps/templates/admin.html:71 cps/templates/email_edit.html:35 msgid "SMTP Port" msgstr "SMTP-порт" -#: cps/templates/admin.html:73 cps/templates/email_edit.html:39 +#: cps/templates/admin.html:75 cps/templates/email_edit.html:39 msgid "Encryption" msgstr "SSL" -#: cps/templates/admin.html:77 cps/templates/email_edit.html:47 +#: cps/templates/admin.html:79 cps/templates/email_edit.html:47 msgid "SMTP Login" msgstr "SMTP-логин" -#: cps/templates/admin.html:81 cps/templates/admin.html:92 +#: cps/templates/admin.html:83 cps/templates/admin.html:94 #: cps/templates/email_edit.html:55 msgid "From E-mail" msgstr "Отправитель" -#: cps/templates/admin.html:88 +#: cps/templates/admin.html:90 msgid "E-Mail Service" msgstr "" -#: cps/templates/admin.html:89 +#: cps/templates/admin.html:91 msgid "Gmail via Oauth2" msgstr "" -#: cps/templates/admin.html:104 +#: cps/templates/admin.html:106 msgid "Configuration" msgstr "Настройки сервера" -#: cps/templates/admin.html:107 +#: cps/templates/admin.html:109 msgid "Calibre Database Directory" msgstr "Расположение базы данных Calibre" -#: cps/templates/admin.html:111 cps/templates/config_edit.html:68 +#: cps/templates/admin.html:113 cps/templates/config_edit.html:68 msgid "Log Level" msgstr "Уровень логирования" -#: cps/templates/admin.html:115 +#: cps/templates/admin.html:117 msgid "Port" msgstr "Порт" -#: cps/templates/admin.html:120 +#: cps/templates/admin.html:122 msgid "External Port" msgstr "" -#: cps/templates/admin.html:127 cps/templates/config_view_edit.html:28 +#: cps/templates/admin.html:129 cps/templates/config_view_edit.html:28 msgid "Books per Page" msgstr "Количество книг на странице" -#: cps/templates/admin.html:131 +#: cps/templates/admin.html:133 msgid "Uploads" msgstr "Загрузка на сервер" -#: cps/templates/admin.html:135 +#: cps/templates/admin.html:137 msgid "Anonymous Browsing" msgstr "Анонимный просмотр" -#: cps/templates/admin.html:139 +#: cps/templates/admin.html:141 msgid "Public Registration" msgstr "Публичная регистрация" -#: cps/templates/admin.html:143 +#: cps/templates/admin.html:145 msgid "Magic Link Remote Login" msgstr "Удалённый логин" -#: cps/templates/admin.html:147 +#: cps/templates/admin.html:149 msgid "Reverse Proxy Login" msgstr "Логин обратного прокси" -#: cps/templates/admin.html:152 cps/templates/config_edit.html:173 +#: cps/templates/admin.html:154 cps/templates/config_edit.html:173 msgid "Reverse Proxy Header Name" msgstr "Имя заголовка обратного прокси" -#: cps/templates/admin.html:157 +#: cps/templates/admin.html:159 #, fuzzy msgid "Edit Calibre Database Configuration" msgstr "Изменить основные настройки" -#: cps/templates/admin.html:158 +#: cps/templates/admin.html:160 msgid "Edit Basic Configuration" msgstr "Изменить основные настройки" -#: cps/templates/admin.html:159 +#: cps/templates/admin.html:161 msgid "Edit UI Configuration" msgstr "Изменить настройки интерфейса" -#: cps/templates/admin.html:164 +#: cps/templates/admin.html:166 msgid "Administration" msgstr "Управление" -#: cps/templates/admin.html:165 +#: cps/templates/admin.html:167 msgid "Download Debug Package" msgstr "" -#: cps/templates/admin.html:166 +#: cps/templates/admin.html:168 msgid "View Logs" msgstr "Просмотреть лог файл" -#: cps/templates/admin.html:169 +#: cps/templates/admin.html:171 msgid "Reconnect Calibre Database" msgstr "Пере подключиться к базе жанных Calibre" -#: cps/templates/admin.html:170 +#: cps/templates/admin.html:172 msgid "Restart" msgstr "Перезагрузить Calibre-Web" -#: cps/templates/admin.html:171 +#: cps/templates/admin.html:173 msgid "Shutdown" msgstr "Остановить Calibre-Web" -#: cps/templates/admin.html:176 +#: cps/templates/admin.html:178 msgid "Update" msgstr "Обновление" -#: cps/templates/admin.html:180 +#: cps/templates/admin.html:182 msgid "Version" msgstr "Версия" -#: cps/templates/admin.html:181 +#: cps/templates/admin.html:183 msgid "Details" msgstr "Подробности" -#: cps/templates/admin.html:187 +#: cps/templates/admin.html:189 msgid "Current version" msgstr "Текущая версия" -#: cps/templates/admin.html:194 +#: cps/templates/admin.html:196 msgid "Check for Update" msgstr "Проверка обновлений" -#: cps/templates/admin.html:195 +#: cps/templates/admin.html:197 msgid "Perform Update" msgstr "Установить обновления" -#: cps/templates/admin.html:208 +#: cps/templates/admin.html:210 msgid "Are you sure you want to restart?" msgstr "Вы действительно хотите перезагрузить Calibre-Web?" -#: cps/templates/admin.html:213 cps/templates/admin.html:227 -#: cps/templates/admin.html:247 cps/templates/config_db.html:70 +#: cps/templates/admin.html:215 cps/templates/admin.html:229 +#: cps/templates/admin.html:249 cps/templates/config_db.html:70 msgid "OK" msgstr "Ok" -#: cps/templates/admin.html:214 cps/templates/admin.html:228 -#: cps/templates/book_edit.html:213 cps/templates/book_table.html:124 +#: cps/templates/admin.html:216 cps/templates/admin.html:230 +#: cps/templates/book_edit.html:213 cps/templates/book_table.html:127 #: cps/templates/config_db.html:54 cps/templates/config_edit.html:359 -#: cps/templates/config_view_edit.html:173 cps/templates/modal_dialogs.html:64 +#: cps/templates/config_view_edit.html:175 cps/templates/modal_dialogs.html:64 #: cps/templates/modal_dialogs.html:99 cps/templates/modal_dialogs.html:117 #: cps/templates/modal_dialogs.html:135 cps/templates/shelf_edit.html:27 #: cps/templates/user_edit.html:144 msgid "Cancel" msgstr "Отмена" -#: cps/templates/admin.html:226 +#: cps/templates/admin.html:228 msgid "Are you sure you want to shutdown?" msgstr "Вы действительно хотите остановить Calibre-Web?" -#: cps/templates/admin.html:238 +#: cps/templates/admin.html:240 msgid "Updating, please do not reload this page" msgstr "Установка обновлений, пожалуйста, не обновляйте страницу" @@ -1603,44 +1627,43 @@ msgstr "с помощью" msgid "In Library" msgstr "В библиотеке" -#: cps/templates/author.html:26 cps/templates/index.html:72 -#: cps/templates/search.html:29 cps/templates/shelf.html:19 +#: cps/templates/author.html:26 cps/templates/index.html:73 +#: cps/templates/search.html:30 cps/templates/shelf.html:19 msgid "Sort according to book date, newest first" msgstr "" -#: cps/templates/author.html:27 cps/templates/index.html:73 -#: cps/templates/search.html:30 cps/templates/shelf.html:20 +#: cps/templates/author.html:27 cps/templates/index.html:74 +#: cps/templates/search.html:31 cps/templates/shelf.html:20 msgid "Sort according to book date, oldest first" msgstr "" -#: cps/templates/author.html:28 cps/templates/index.html:74 -#: cps/templates/search.html:31 cps/templates/shelf.html:21 +#: cps/templates/author.html:28 cps/templates/index.html:75 +#: cps/templates/search.html:32 cps/templates/shelf.html:21 msgid "Sort title in alphabetical order" msgstr "" -#: cps/templates/author.html:29 cps/templates/index.html:75 -#: cps/templates/search.html:32 cps/templates/shelf.html:22 +#: cps/templates/author.html:29 cps/templates/index.html:76 +#: cps/templates/search.html:33 cps/templates/shelf.html:22 msgid "Sort title in reverse alphabetical order" msgstr "" -#: cps/templates/author.html:30 cps/templates/index.html:78 -#: cps/templates/search.html:35 cps/templates/shelf.html:25 +#: cps/templates/author.html:30 cps/templates/index.html:79 +#: cps/templates/search.html:36 cps/templates/shelf.html:25 msgid "Sort according to publishing date, newest first" msgstr "" -#: cps/templates/author.html:31 cps/templates/index.html:79 -#: cps/templates/search.html:36 cps/templates/shelf.html:26 +#: cps/templates/author.html:31 cps/templates/index.html:80 +#: cps/templates/search.html:37 cps/templates/shelf.html:26 msgid "Sort according to publishing date, oldest first" msgstr "" -#: cps/templates/author.html:57 cps/templates/author.html:117 -#: cps/templates/discover.html:30 cps/templates/index.html:29 -#: cps/templates/index.html:111 cps/templates/search.html:65 -#: cps/templates/shelf.html:54 +#: cps/templates/author.html:56 cps/templates/author.html:115 +#: cps/templates/index.html:29 cps/templates/index.html:112 +#: cps/templates/search.html:66 cps/templates/shelf.html:54 msgid "reduce" msgstr "уменьшить" -#: cps/templates/author.html:101 +#: cps/templates/author.html:99 msgid "More by" msgstr "Ещё от" @@ -1765,7 +1788,7 @@ msgid "Fetch Metadata" msgstr "Получить метаданные" #: cps/templates/book_edit.html:212 cps/templates/config_db.html:53 -#: cps/templates/config_edit.html:358 cps/templates/config_view_edit.html:172 +#: cps/templates/config_edit.html:358 cps/templates/config_view_edit.html:174 #: cps/templates/email_edit.html:65 cps/templates/shelf_edit.html:25 #: cps/templates/shelf_order.html:41 cps/templates/user_edit.html:142 msgid "Save" @@ -1894,27 +1917,35 @@ msgstr "Введите доменное имя" msgid "Comments" msgstr "" -#: cps/templates/book_table.html:77 cps/templates/book_table.html:79 -#: cps/templates/book_table.html:81 cps/templates/book_table.html:83 -#: cps/templates/book_table.html:87 cps/templates/book_table.html:89 -#: cps/templates/book_table.html:91 cps/templates/book_table.html:93 +#: cps/templates/book_table.html:75 +msgid "Archiv Status" +msgstr "" + +#: cps/templates/book_table.html:77 cps/templates/search_form.html:42 +msgid "Read Status" +msgstr "" + +#: cps/templates/book_table.html:80 cps/templates/book_table.html:82 +#: cps/templates/book_table.html:84 cps/templates/book_table.html:86 +#: cps/templates/book_table.html:90 cps/templates/book_table.html:92 +#: cps/templates/book_table.html:96 #, fuzzy msgid "Enter " msgstr "Зарегистрироваться" -#: cps/templates/book_table.html:110 cps/templates/modal_dialogs.html:46 +#: cps/templates/book_table.html:113 cps/templates/modal_dialogs.html:46 msgid "Are you really sure?" msgstr "Вы действительно уверены?" -#: cps/templates/book_table.html:114 +#: cps/templates/book_table.html:117 msgid "Books with Title will be merged from:" msgstr "" -#: cps/templates/book_table.html:118 +#: cps/templates/book_table.html:121 msgid "Into Book with Title:" msgstr "" -#: cps/templates/book_table.html:123 +#: cps/templates/book_table.html:126 msgid "Merge" msgstr "" @@ -2091,11 +2122,6 @@ msgstr "Порт сервера LDAP" msgid "LDAP Encryption" msgstr "Шифрование LDAP" -#: cps/templates/config_edit.html:204 cps/templates/config_view_edit.html:62 -#: cps/templates/email_edit.html:41 -msgid "None" -msgstr "Нет" - #: cps/templates/config_edit.html:205 msgid "TLS" msgstr "TLS" @@ -2314,11 +2340,11 @@ msgstr "Видимость для новых пользователей(по у msgid "Show Random Books in Detail View" msgstr "Показывать случайные книги при просмотре деталей" -#: cps/templates/config_view_edit.html:165 cps/templates/user_edit.html:87 +#: cps/templates/config_view_edit.html:166 cps/templates/user_edit.html:87 msgid "Add Allowed/Denied Tags" msgstr "Добавить разрешенные / запрещенные теги" -#: cps/templates/config_view_edit.html:166 +#: cps/templates/config_view_edit.html:167 msgid "Add Allowed/Denied custom column values" msgstr "Добавить разрешенные / запрещенные значения индивидуальных столбцов" @@ -2367,13 +2393,13 @@ msgstr "" msgid "Description:" msgstr "Описание:" -#: cps/templates/detail.html:256 cps/templates/search.html:14 +#: cps/templates/detail.html:256 cps/templates/search.html:15 msgid "Add to shelf" msgstr "Добавить на книжную полку" #: cps/templates/detail.html:267 cps/templates/detail.html:284 #: cps/templates/feed.xml:79 cps/templates/layout.html:137 -#: cps/templates/search.html:20 +#: cps/templates/search.html:21 msgid "(Public)" msgstr "(Публичная)" @@ -2451,10 +2477,15 @@ msgstr "Запрещенные домены (черный список)" msgid "Next" msgstr "Далее" -#: cps/templates/generate_kobo_auth_url.html:5 +#: cps/templates/generate_kobo_auth_url.html:6 msgid "Open the .kobo/Kobo eReader.conf file in a text editor and add (or edit):" msgstr "Откройте файл .kobo / Kobo eReader.conf в текстовом редакторе и добавьте (или отредактируйте):" +#: cps/templates/generate_kobo_auth_url.html:11 +#, fuzzy +msgid "Kobo Token:" +msgstr "Kobo Sync Token" + #: cps/templates/http_error.html:31 #, fuzzy msgid "Calibre-Web Instance is unconfigured, please contact your administrator" @@ -2472,29 +2503,29 @@ msgstr "Вернуться на главную" msgid "Logout User" msgstr "" -#: cps/templates/index.html:69 +#: cps/templates/index.html:70 msgid "Sort ascending according to download count" msgstr "" -#: cps/templates/index.html:70 +#: cps/templates/index.html:71 msgid "Sort descending according to download count" msgstr "" -#: cps/templates/index.html:76 cps/templates/search.html:33 +#: cps/templates/index.html:77 cps/templates/search.html:34 #: cps/templates/shelf.html:23 msgid "Sort authors in alphabetical order" msgstr "" -#: cps/templates/index.html:77 cps/templates/search.html:34 +#: cps/templates/index.html:78 cps/templates/search.html:35 #: cps/templates/shelf.html:24 msgid "Sort authors in reverse alphabetical order" msgstr "" -#: cps/templates/index.html:81 +#: cps/templates/index.html:82 msgid "Sort ascending according to series index" msgstr "" -#: cps/templates/index.html:82 +#: cps/templates/index.html:83 msgid "Sort descending according to series index" msgstr "" @@ -2930,10 +2961,6 @@ msgstr "Опубликовано от" msgid "Published Date To" msgstr "Опубликовано до" -#: cps/templates/search_form.html:42 -msgid "Read Status" -msgstr "" - #: cps/templates/search_form.html:59 msgid "Exclude Tags" msgstr "Исключить теги" diff --git a/cps/translations/sv/LC_MESSAGES/messages.mo b/cps/translations/sv/LC_MESSAGES/messages.mo index c396c602..1e216ed2 100644 Binary files a/cps/translations/sv/LC_MESSAGES/messages.mo and b/cps/translations/sv/LC_MESSAGES/messages.mo differ diff --git a/cps/translations/sv/LC_MESSAGES/messages.po b/cps/translations/sv/LC_MESSAGES/messages.po index ea19c81d..1a276632 100644 --- a/cps/translations/sv/LC_MESSAGES/messages.po +++ b/cps/translations/sv/LC_MESSAGES/messages.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Calibre-Web\n" "Report-Msgid-Bugs-To: https://github.com/janeczku/Calibre-Web\n" -"POT-Creation-Date: 2022-01-15 09:19+0100\n" +"POT-Creation-Date: 2022-04-18 20:01+0200\n" "PO-Revision-Date: 2021-05-13 11:00+0000\n" "Last-Translator: Jonatan Nyberg \n" "Language: sv\n" @@ -16,587 +16,590 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.9.0\n" +"Generated-By: Babel 2.9.1\n" -#: cps/about.py:34 cps/about.py:49 cps/about.py:65 cps/converter.py:31 -msgid "not installed" -msgstr "inte installerad" - -#: cps/about.py:47 cps/about.py:63 -msgid "installed" -msgstr "installerad" - -#: cps/about.py:145 +#: cps/about.py:86 msgid "Statistics" msgstr "Statistik" -#: cps/admin.py:144 +#: cps/admin.py:141 msgid "Server restarted, please reload page" msgstr "Server startas om, vänligen uppdatera sidan" -#: cps/admin.py:146 +#: cps/admin.py:143 msgid "Performing shutdown of server, please close window" msgstr "Stänger servern, vänligen stäng fönstret" -#: cps/admin.py:154 +#: cps/admin.py:151 msgid "Reconnect successful" msgstr "Återanslutning lyckades" -#: cps/admin.py:157 +#: cps/admin.py:154 msgid "Unknown command" msgstr "Okänt kommando" -#: cps/admin.py:167 cps/editbooks.py:707 cps/editbooks.py:721 -#: cps/editbooks.py:866 cps/editbooks.py:868 cps/editbooks.py:895 -#: cps/editbooks.py:911 cps/updater.py:584 cps/uploader.py:93 -#: cps/uploader.py:103 +#: cps/admin.py:176 cps/editbooks.py:713 cps/editbooks.py:892 +#: cps/editbooks.py:894 cps/editbooks.py:930 cps/editbooks.py:947 +#: cps/updater.py:608 cps/uploader.py:93 cps/uploader.py:103 msgid "Unknown" msgstr "Okänd" -#: cps/admin.py:188 +#: cps/admin.py:197 msgid "Admin page" msgstr "Administrationssida" -#: cps/admin.py:207 +#: cps/admin.py:217 msgid "Basic Configuration" msgstr "Grundläggande konfiguration" -#: cps/admin.py:244 +#: cps/admin.py:255 msgid "UI Configuration" msgstr "Användargränssnitt konfiguration" -#: cps/admin.py:277 cps/templates/admin.html:50 +#: cps/admin.py:289 cps/templates/admin.html:51 msgid "Edit Users" msgstr "Redigera användare" -#: cps/admin.py:318 cps/opds.py:109 cps/opds.py:198 cps/opds.py:275 -#: cps/opds.py:327 cps/templates/grid.html:13 cps/templates/languages.html:9 +#: cps/admin.py:333 cps/opds.py:529 cps/templates/grid.html:13 #: cps/templates/list.html:13 msgid "All" msgstr "Alla" -#: cps/admin.py:343 cps/admin.py:1615 +#: cps/admin.py:360 cps/admin.py:1648 msgid "User not found" msgstr "Användaren hittades inte" -#: cps/admin.py:357 +#: cps/admin.py:374 msgid "{} users deleted successfully" msgstr "{} användare har tagits bort" -#: cps/admin.py:379 cps/templates/config_view_edit.html:133 +#: cps/admin.py:397 cps/templates/config_view_edit.html:133 #: cps/templates/user_edit.html:45 cps/templates/user_table.html:81 msgid "Show All" msgstr "Visa alla" -#: cps/admin.py:400 cps/admin.py:406 +#: cps/admin.py:418 cps/admin.py:424 msgid "Malformed request" msgstr "Felaktig begäran" -#: cps/admin.py:418 cps/admin.py:1493 +#: cps/admin.py:436 cps/admin.py:1526 msgid "Guest Name can't be changed" msgstr "Gästnamn kan inte ändras" -#: cps/admin.py:430 +#: cps/admin.py:448 msgid "Guest can't have this role" msgstr "Gäst kan inte ha den här rollen" -#: cps/admin.py:442 cps/admin.py:1451 +#: cps/admin.py:460 cps/admin.py:1484 msgid "No admin user remaining, can't remove admin role" msgstr "Ingen administratörsanvändare kvar, kan inte ta bort administratörsrollen" -#: cps/admin.py:446 cps/admin.py:460 +#: cps/admin.py:464 cps/admin.py:478 msgid "Value has to be true or false" msgstr "Värdet måste vara sant eller falskt" -#: cps/admin.py:448 +#: cps/admin.py:466 msgid "Invalid role" msgstr "Ogiltig roll" -#: cps/admin.py:452 +#: cps/admin.py:470 msgid "Guest can't have this view" msgstr "Gästen kan inte ha den här vyn" -#: cps/admin.py:462 +#: cps/admin.py:480 msgid "Invalid view" msgstr "Ogiltig vy" -#: cps/admin.py:465 +#: cps/admin.py:483 msgid "Guest's Locale is determined automatically and can't be set" msgstr "Gästens språk bestäms automatiskt och kan inte ställas in" -#: cps/admin.py:469 +#: cps/admin.py:487 msgid "No Valid Locale Given" msgstr "Inget giltigt språk anges" -#: cps/admin.py:480 +#: cps/admin.py:498 msgid "No Valid Book Language Given" msgstr "Inget giltigt bokspråk anges" -#: cps/admin.py:482 +#: cps/admin.py:500 cps/editbooks.py:1267 msgid "Parameter not found" msgstr "Parameter hittades inte" -#: cps/admin.py:533 +#: cps/admin.py:553 #, fuzzy msgid "Invalid Read Column" msgstr "Ogiltig roll" -#: cps/admin.py:539 +#: cps/admin.py:559 msgid "Invalid Restricted Column" msgstr "" -#: cps/admin.py:560 cps/admin.py:1323 +#: cps/admin.py:579 cps/admin.py:1355 msgid "Calibre-Web configuration updated" msgstr "Calibre-Web konfiguration uppdaterad" -#: cps/admin.py:572 +#: cps/admin.py:591 msgid "Do you really want to delete the Kobo Token?" msgstr "Vill du verkligen ta bort Kobo-token?" -#: cps/admin.py:574 +#: cps/admin.py:593 msgid "Do you really want to delete this domain?" msgstr "Vill du verkligen ta bort den här domänen?" -#: cps/admin.py:576 +#: cps/admin.py:595 msgid "Do you really want to delete this user?" msgstr "Vill du verkligen ta bort den här användaren?" -#: cps/admin.py:578 +#: cps/admin.py:597 msgid "Are you sure you want to delete this shelf?" msgstr "Är du säker på att du vill ta bort hyllan?" -#: cps/admin.py:580 +#: cps/admin.py:599 msgid "Are you sure you want to change locales of selected user(s)?" msgstr "Är du säker på att du vill ändra språk för valda användare?" -#: cps/admin.py:582 +#: cps/admin.py:601 msgid "Are you sure you want to change visible book languages for selected user(s)?" msgstr "Är du säker på att du vill ändra synliga bokspråk för valda användare?" -#: cps/admin.py:584 +#: cps/admin.py:603 msgid "Are you sure you want to change the selected role for the selected user(s)?" msgstr "Är du säker på att du vill ändra den valda rollen för de valda användarna?" -#: cps/admin.py:586 +#: cps/admin.py:605 msgid "Are you sure you want to change the selected restrictions for the selected user(s)?" msgstr "Är du säker på att du vill ändra de valda begränsningarna för de valda användarna?" -#: cps/admin.py:588 +#: cps/admin.py:607 msgid "Are you sure you want to change the selected visibility restrictions for the selected user(s)?" msgstr "Är du säker på att du vill ändra de valda synlighetsbegränsningarna för de valda användarna?" -#: cps/admin.py:590 +#: cps/admin.py:610 #, fuzzy msgid "Are you sure you want to change shelf sync behavior for the selected user(s)?" msgstr "Är du säker på att du vill ändra den valda rollen för de valda användarna?" -#: cps/admin.py:592 +#: cps/admin.py:612 #, fuzzy msgid "Are you sure you want to change Calibre library location?" msgstr "Är du säker på att du vill stoppa Calibre-Web?" -#: cps/admin.py:594 +#: cps/admin.py:614 msgid "Are you sure you want delete Calibre-Web's sync database to force a full sync with your Kobo Reader?" msgstr "" -#: cps/admin.py:743 +#: cps/admin.py:764 msgid "Tag not found" msgstr "Taggen hittades inte" -#: cps/admin.py:755 +#: cps/admin.py:776 msgid "Invalid Action" msgstr "Ogiltig åtgärd" -#: cps/admin.py:871 cps/admin.py:877 cps/admin.py:887 cps/admin.py:897 +#: cps/admin.py:893 cps/admin.py:899 cps/admin.py:909 cps/admin.py:919 #: cps/templates/modal_dialogs.html:29 cps/templates/user_table.html:41 #: cps/templates/user_table.html:58 msgid "Deny" msgstr "Förneka" -#: cps/admin.py:873 cps/admin.py:879 cps/admin.py:889 cps/admin.py:899 +#: cps/admin.py:895 cps/admin.py:901 cps/admin.py:911 cps/admin.py:921 #: cps/templates/modal_dialogs.html:28 cps/templates/user_table.html:44 #: cps/templates/user_table.html:61 msgid "Allow" msgstr "Tillåt" -#: cps/admin.py:913 +#: cps/admin.py:936 msgid "{} sync entries deleted" msgstr "" -#: cps/admin.py:1036 +#: cps/admin.py:1059 msgid "client_secrets.json Is Not Configured For Web Application" msgstr "client_secrets.json är inte konfigurerad för webbapplikation" -#: cps/admin.py:1081 +#: cps/admin.py:1104 msgid "Logfile Location is not Valid, Please Enter Correct Path" msgstr "Loggfilens plats är inte giltig, vänligen ange rätt sökväg" -#: cps/admin.py:1087 +#: cps/admin.py:1110 msgid "Access Logfile Location is not Valid, Please Enter Correct Path" msgstr "Åtkomstloggplatsens plats är inte giltig, vänligen ange rätt sökväg" -#: cps/admin.py:1117 +#: cps/admin.py:1140 msgid "Please Enter a LDAP Provider, Port, DN and User Object Identifier" msgstr "Vänligen ange en LDAP-leverantör, port, DN och användarobjektidentifierare" -#: cps/admin.py:1123 +#: cps/admin.py:1146 #, fuzzy msgid "Please Enter a LDAP Service Account and Password" msgstr "Ange giltigt användarnamn för att återställa lösenordet" -#: cps/admin.py:1126 +#: cps/admin.py:1149 msgid "Please Enter a LDAP Service Account" msgstr "" -#: cps/admin.py:1131 +#: cps/admin.py:1154 #, python-format msgid "LDAP Group Object Filter Needs to Have One \"%s\" Format Identifier" msgstr "LDAP-gruppobjektfilter måste ha en \"%s\"-formatidentifierare" -#: cps/admin.py:1133 +#: cps/admin.py:1156 msgid "LDAP Group Object Filter Has Unmatched Parenthesis" msgstr "LDAP-gruppobjektfilter har omatchande parentes" -#: cps/admin.py:1137 +#: cps/admin.py:1160 #, python-format msgid "LDAP User Object Filter needs to Have One \"%s\" Format Identifier" msgstr "LDAP-användarobjektfilter måste ha en \"%s\"-formatidentifierare" -#: cps/admin.py:1139 +#: cps/admin.py:1162 msgid "LDAP User Object Filter Has Unmatched Parenthesis" msgstr "LDAP-användarobjektfilter har omatchad parentes" -#: cps/admin.py:1146 +#: cps/admin.py:1169 #, python-format msgid "LDAP Member User Filter needs to Have One \"%s\" Format Identifier" msgstr "Användarfilter för LDAP-medlemmar måste ha en \"%s\"-formatidentifierare" -#: cps/admin.py:1148 +#: cps/admin.py:1171 msgid "LDAP Member User Filter Has Unmatched Parenthesis" msgstr "Användarfilter för LDAP-medlemmar har omatchad parentes" -#: cps/admin.py:1155 +#: cps/admin.py:1178 msgid "LDAP CACertificate, Certificate or Key Location is not Valid, Please Enter Correct Path" msgstr "LDAP-certifikat, certifikat eller nyckelplats är inte giltigt, vänligen ange rätt sökväg" -#: cps/admin.py:1197 cps/admin.py:1308 cps/admin.py:1405 cps/admin.py:1521 -#: cps/admin.py:1590 cps/shelf.py:100 cps/shelf.py:160 cps/shelf.py:203 -#: cps/shelf.py:279 cps/shelf.py:341 cps/shelf.py:376 cps/shelf.py:451 -msgid "Settings DB is not Writeable" -msgstr "Inställningar för DB är inte skrivbara" - -#: cps/admin.py:1208 -msgid "DB Location is not Valid, Please Enter Correct Path" -msgstr "DB-plats är inte giltig, vänligen ange rätt sökväg" - -#: cps/admin.py:1223 -msgid "DB is not Writeable" -msgstr "DB är inte skrivbar" - -#: cps/admin.py:1235 -msgid "Keyfile Location is not Valid, Please Enter Correct Path" -msgstr "Keyfile-platsen är inte giltig, vänligen ange rätt sökväg" - -#: cps/admin.py:1239 -msgid "Certfile Location is not Valid, Please Enter Correct Path" -msgstr "Certfile-platsen är inte giltig, vänligen ange rätt sökväg" - -#: cps/admin.py:1346 -#, fuzzy -msgid "Database Settings updated" -msgstr "E-postserverinställningar uppdaterade" - -#: cps/admin.py:1354 -#, fuzzy -msgid "Database Configuration" -msgstr "Funktion konfiguration" - -#: cps/admin.py:1370 cps/web.py:1479 -msgid "Please fill out all fields!" -msgstr "Fyll i alla fält!" - -#: cps/admin.py:1378 -msgid "E-mail is not from valid domain" -msgstr "E-posten är inte från giltig domän" - -#: cps/admin.py:1384 cps/admin.py:1543 -msgid "Add new user" -msgstr "Lägg till ny användare" - -#: cps/admin.py:1395 -#, python-format -msgid "User '%(user)s' created" -msgstr "Användaren '%(user)s' skapad" - -#: cps/admin.py:1401 -msgid "Found an existing account for this e-mail address or name." -msgstr "Hittade ett befintligt konto för den här e-postadressen eller namnet." - -#: cps/admin.py:1430 -#, python-format -msgid "User '%(nick)s' deleted" -msgstr "Användaren '%(nick)s' borttagen" - -#: cps/admin.py:1432 cps/admin.py:1433 -msgid "Can't delete Guest User" -msgstr "Det går inte att ta bort gästanvändaren" - -#: cps/admin.py:1436 -msgid "No admin user remaining, can't delete user" -msgstr "Ingen adminstratörsanvändare kvar, kan inte ta bort användaren" - -#: cps/admin.py:1509 cps/admin.py:1634 -#, python-format -msgid "Edit User %(nick)s" -msgstr "Redigera användaren %(nick)s" - -#: cps/admin.py:1513 -#, python-format -msgid "User '%(nick)s' updated" -msgstr "Användaren '%(nick)s' uppdaterad" - -#: cps/admin.py:1517 cps/admin.py:1649 cps/web.py:1504 cps/web.py:1564 -msgid "An unknown error occurred. Please try again later." -msgstr "Ett okänt fel uppstod. Försök igen senare." - -#: cps/admin.py:1552 cps/templates/admin.html:98 -msgid "Edit E-mail Server Settings" -msgstr "Ändra SMTP-inställningar" - -#: cps/admin.py:1571 -#, fuzzy -msgid "Gmail Account Verification Successful" -msgstr "Verifiering av G-mail-kontot lyckades" - -#: cps/admin.py:1597 -#, python-format -msgid "Test e-mail queued for sending to %(email)s, please check Tasks for result" -msgstr "Testa e-post i kö för att skicka till %(email)s, vänligen kontrollera Uppgifter för resultat" - -#: cps/admin.py:1600 -#, python-format -msgid "There was an error sending the Test e-mail: %(res)s" -msgstr "Det gick inte att skicka Testmeddelandet: %(res)s" - -#: cps/admin.py:1602 -msgid "Please configure your e-mail address first..." -msgstr "Vänligen konfigurera din e-postadress först..." - -#: cps/admin.py:1604 -msgid "E-mail server settings updated" -msgstr "E-postserverinställningar uppdaterade" - -#: cps/admin.py:1646 -#, python-format -msgid "Password for user %(user)s reset" -msgstr "Lösenord för användaren %(user)s återställd" - -#: cps/admin.py:1652 cps/web.py:1444 -msgid "Please configure the SMTP mail settings first..." -msgstr "Konfigurera SMTP-postinställningarna först..." - -#: cps/admin.py:1663 -msgid "Logfile viewer" -msgstr "Visaren för loggfil" - -#: cps/admin.py:1729 -msgid "Requesting update package" -msgstr "Begär uppdateringspaketet" - -#: cps/admin.py:1730 -msgid "Downloading update package" -msgstr "Hämtar uppdateringspaketet" - -#: cps/admin.py:1731 -msgid "Unzipping update package" -msgstr "Packar upp uppdateringspaketet" - -#: cps/admin.py:1732 -msgid "Replacing files" -msgstr "Ersätta filer" - -#: cps/admin.py:1733 -msgid "Database connections are closed" -msgstr "Databasanslutningarna är stängda" - -#: cps/admin.py:1734 -msgid "Stopping server" -msgstr "Stoppar server" - -#: cps/admin.py:1735 -msgid "Update finished, please press okay and reload page" -msgstr "Uppdatering klar, tryck på okej och uppdatera sidan" - -#: cps/admin.py:1736 cps/admin.py:1737 cps/admin.py:1738 cps/admin.py:1739 -#: cps/admin.py:1740 cps/admin.py:1741 -msgid "Update failed:" -msgstr "Uppdateringen misslyckades:" - -#: cps/admin.py:1736 cps/updater.py:385 cps/updater.py:595 cps/updater.py:597 -msgid "HTTP Error" -msgstr "HTTP-fel" - -#: cps/admin.py:1737 cps/updater.py:387 cps/updater.py:599 -msgid "Connection error" -msgstr "Anslutningsfel" - -#: cps/admin.py:1738 cps/updater.py:389 cps/updater.py:601 -msgid "Timeout while establishing connection" -msgstr "Tiden ute när du etablerade anslutning" - -#: cps/admin.py:1739 cps/updater.py:391 cps/updater.py:603 -msgid "General error" -msgstr "Allmänt fel" - -#: cps/admin.py:1740 -#, fuzzy -msgid "Update file could not be saved in temp dir" -msgstr "Uppdateringsfilen kunde inte sparas i Temp Dir" - -#: cps/admin.py:1741 -msgid "Files could not be replaced during update" -msgstr "" - -#: cps/admin.py:1765 -#, fuzzy -msgid "Failed to extract at least One LDAP User" -msgstr "Det gick inte att skapa minst en LDAP-användare" - -#: cps/admin.py:1810 -msgid "Failed to Create at Least One LDAP User" -msgstr "Det gick inte att skapa minst en LDAP-användare" - -#: cps/admin.py:1823 -#, python-format -msgid "Error: %(ldaperror)s" -msgstr "Fel: %(ldaperror)s" - -#: cps/admin.py:1827 -msgid "Error: No user returned in response of LDAP server" -msgstr "Fel: Ingen användare återges som svar på LDAP-servern" - -#: cps/admin.py:1860 -msgid "At Least One LDAP User Not Found in Database" -msgstr "Minst en LDAP-användare hittades inte i databasen" - -#: cps/admin.py:1862 -msgid "{} User Successfully Imported" -msgstr "{} användare har importerats" - -#: cps/converter.py:30 -msgid "not configured" -msgstr "inte konfigurerad" - -#: cps/converter.py:32 -msgid "Execution permissions missing" -msgstr "Körningstillstånd saknas" - -#: cps/db.py:651 cps/web.py:667 cps/web.py:1155 -#, python-format -msgid "Custom Column No.%(column)d is not existing in calibre database" -msgstr "Anpassad kolumn n.%(column)d finns inte i calibre-databasen" - -#: cps/editbooks.py:300 cps/editbooks.py:302 -msgid "Book Format Successfully Deleted" -msgstr "Bokformat har tagits bort" - -#: cps/editbooks.py:309 cps/editbooks.py:311 -msgid "Book Successfully Deleted" -msgstr "Boken har tagits bort" - -#: cps/editbooks.py:361 -msgid "You are missing permissions to delete books" -msgstr "" - -#: cps/editbooks.py:376 cps/editbooks.py:763 cps/web.py:523 cps/web.py:1703 -#: cps/web.py:1744 cps/web.py:1811 -msgid "Oops! Selected book title is unavailable. File does not exist or is not accessible" -msgstr "Hoppsan! Vald boktitel är inte tillgänglig. Filen finns inte eller är inte tillgänglig" - -#: cps/editbooks.py:410 -msgid "edit metadata" -msgstr "redigera metadata" - -#: cps/editbooks.py:458 -#, python-format -msgid "%(seriesindex)s is not a valid number, skipping" -msgstr "" - -#: cps/editbooks.py:494 cps/editbooks.py:958 -#, fuzzy, python-format -msgid "'%(langname)s' is not a valid language" -msgstr "%(langname)s är inte ett giltigt språk" - -#: cps/editbooks.py:634 cps/editbooks.py:985 -#, python-format -msgid "File extension '%(ext)s' is not allowed to be uploaded to this server" -msgstr "Filändelsen '%(ext)s' får inte laddas upp till den här servern" - -#: cps/editbooks.py:638 cps/editbooks.py:989 -msgid "File to be uploaded must have an extension" -msgstr "Filen som ska laddas upp måste ha en ändelse" - -#: cps/editbooks.py:650 -#, python-format -msgid "Failed to create path %(path)s (Permission denied)." -msgstr "Det gick inte att skapa sökväg %(path)s (behörighet nekad)." - -#: cps/editbooks.py:655 -#, python-format -msgid "Failed to store file %(file)s." -msgstr "Det gick inte att lagra filen %(file)s." - -#: cps/editbooks.py:673 cps/editbooks.py:1076 cps/web.py:1664 +#: cps/admin.py:1223 cps/admin.py:1339 cps/admin.py:1437 cps/admin.py:1554 +#: cps/admin.py:1623 cps/editbooks.py:678 cps/editbooks.py:882 +#: cps/editbooks.py:1130 cps/shelf.py:100 cps/shelf.py:160 cps/shelf.py:203 +#: cps/shelf.py:278 cps/shelf.py:343 cps/shelf.py:380 cps/shelf.py:456 +#: cps/web.py:1742 #, python-format msgid "Database error: %(error)s." msgstr "Databasfel: %(error)s." -#: cps/editbooks.py:678 +#: cps/admin.py:1235 +msgid "DB Location is not Valid, Please Enter Correct Path" +msgstr "DB-plats är inte giltig, vänligen ange rätt sökväg" + +#: cps/admin.py:1253 +msgid "DB is not Writeable" +msgstr "DB är inte skrivbar" + +#: cps/admin.py:1266 +msgid "Keyfile Location is not Valid, Please Enter Correct Path" +msgstr "Keyfile-platsen är inte giltig, vänligen ange rätt sökväg" + +#: cps/admin.py:1270 +msgid "Certfile Location is not Valid, Please Enter Correct Path" +msgstr "Certfile-platsen är inte giltig, vänligen ange rätt sökväg" + +#: cps/admin.py:1378 +#, fuzzy +msgid "Database Settings updated" +msgstr "E-postserverinställningar uppdaterade" + +#: cps/admin.py:1386 +#, fuzzy +msgid "Database Configuration" +msgstr "Funktion konfiguration" + +#: cps/admin.py:1402 cps/web.py:1557 +msgid "Please fill out all fields!" +msgstr "Fyll i alla fält!" + +#: cps/admin.py:1410 +msgid "E-mail is not from valid domain" +msgstr "E-posten är inte från giltig domän" + +#: cps/admin.py:1416 cps/admin.py:1576 +msgid "Add new user" +msgstr "Lägg till ny användare" + +#: cps/admin.py:1427 +#, python-format +msgid "User '%(user)s' created" +msgstr "Användaren '%(user)s' skapad" + +#: cps/admin.py:1433 +msgid "Found an existing account for this e-mail address or name." +msgstr "Hittade ett befintligt konto för den här e-postadressen eller namnet." + +#: cps/admin.py:1463 +#, python-format +msgid "User '%(nick)s' deleted" +msgstr "Användaren '%(nick)s' borttagen" + +#: cps/admin.py:1465 cps/admin.py:1466 +msgid "Can't delete Guest User" +msgstr "Det går inte att ta bort gästanvändaren" + +#: cps/admin.py:1469 +msgid "No admin user remaining, can't delete user" +msgstr "Ingen adminstratörsanvändare kvar, kan inte ta bort användaren" + +#: cps/admin.py:1542 cps/admin.py:1667 +#, python-format +msgid "Edit User %(nick)s" +msgstr "Redigera användaren %(nick)s" + +#: cps/admin.py:1546 +#, python-format +msgid "User '%(nick)s' updated" +msgstr "Användaren '%(nick)s' uppdaterad" + +#: cps/admin.py:1550 cps/admin.py:1682 cps/web.py:1582 cps/web.py:1642 +msgid "An unknown error occurred. Please try again later." +msgstr "Ett okänt fel uppstod. Försök igen senare." + +#: cps/admin.py:1585 cps/templates/admin.html:100 +msgid "Edit E-mail Server Settings" +msgstr "Ändra SMTP-inställningar" + +#: cps/admin.py:1604 +#, fuzzy +msgid "Gmail Account Verification Successful" +msgstr "Verifiering av G-mail-kontot lyckades" + +#: cps/admin.py:1630 +#, python-format +msgid "Test e-mail queued for sending to %(email)s, please check Tasks for result" +msgstr "Testa e-post i kö för att skicka till %(email)s, vänligen kontrollera Uppgifter för resultat" + +#: cps/admin.py:1633 +#, python-format +msgid "There was an error sending the Test e-mail: %(res)s" +msgstr "Det gick inte att skicka Testmeddelandet: %(res)s" + +#: cps/admin.py:1635 +msgid "Please configure your e-mail address first..." +msgstr "Vänligen konfigurera din e-postadress först..." + +#: cps/admin.py:1637 +msgid "E-mail server settings updated" +msgstr "E-postserverinställningar uppdaterade" + +#: cps/admin.py:1679 +#, python-format +msgid "Password for user %(user)s reset" +msgstr "Lösenord för användaren %(user)s återställd" + +#: cps/admin.py:1685 cps/web.py:1522 +msgid "Please configure the SMTP mail settings first..." +msgstr "Konfigurera SMTP-postinställningarna först..." + +#: cps/admin.py:1696 +msgid "Logfile viewer" +msgstr "Visaren för loggfil" + +#: cps/admin.py:1762 +msgid "Requesting update package" +msgstr "Begär uppdateringspaketet" + +#: cps/admin.py:1763 +msgid "Downloading update package" +msgstr "Hämtar uppdateringspaketet" + +#: cps/admin.py:1764 +msgid "Unzipping update package" +msgstr "Packar upp uppdateringspaketet" + +#: cps/admin.py:1765 +msgid "Replacing files" +msgstr "Ersätta filer" + +#: cps/admin.py:1766 +msgid "Database connections are closed" +msgstr "Databasanslutningarna är stängda" + +#: cps/admin.py:1767 +msgid "Stopping server" +msgstr "Stoppar server" + +#: cps/admin.py:1768 +msgid "Update finished, please press okay and reload page" +msgstr "Uppdatering klar, tryck på okej och uppdatera sidan" + +#: cps/admin.py:1769 cps/admin.py:1770 cps/admin.py:1771 cps/admin.py:1772 +#: cps/admin.py:1773 cps/admin.py:1774 +msgid "Update failed:" +msgstr "Uppdateringen misslyckades:" + +#: cps/admin.py:1769 cps/updater.py:384 cps/updater.py:619 cps/updater.py:621 +msgid "HTTP Error" +msgstr "HTTP-fel" + +#: cps/admin.py:1770 cps/updater.py:386 cps/updater.py:623 +msgid "Connection error" +msgstr "Anslutningsfel" + +#: cps/admin.py:1771 cps/updater.py:388 cps/updater.py:625 +msgid "Timeout while establishing connection" +msgstr "Tiden ute när du etablerade anslutning" + +#: cps/admin.py:1772 cps/updater.py:390 cps/updater.py:627 +msgid "General error" +msgstr "Allmänt fel" + +#: cps/admin.py:1773 +#, fuzzy +msgid "Update file could not be saved in temp dir" +msgstr "Uppdateringsfilen kunde inte sparas i Temp Dir" + +#: cps/admin.py:1774 +msgid "Files could not be replaced during update" +msgstr "" + +#: cps/admin.py:1798 +#, fuzzy +msgid "Failed to extract at least One LDAP User" +msgstr "Det gick inte att skapa minst en LDAP-användare" + +#: cps/admin.py:1843 +msgid "Failed to Create at Least One LDAP User" +msgstr "Det gick inte att skapa minst en LDAP-användare" + +#: cps/admin.py:1856 +#, python-format +msgid "Error: %(ldaperror)s" +msgstr "Fel: %(ldaperror)s" + +#: cps/admin.py:1860 +msgid "Error: No user returned in response of LDAP server" +msgstr "Fel: Ingen användare återges som svar på LDAP-servern" + +#: cps/admin.py:1893 +msgid "At Least One LDAP User Not Found in Database" +msgstr "Minst en LDAP-användare hittades inte i databasen" + +#: cps/admin.py:1895 +msgid "{} User Successfully Imported" +msgstr "{} användare har importerats" + +#: cps/converter.py:30 +msgid "not installed" +msgstr "inte installerad" + +#: cps/converter.py:31 +msgid "Execution permissions missing" +msgstr "Körningstillstånd saknas" + +#: cps/db.py:674 cps/web.py:710 cps/web.py:1222 +#, python-format +msgid "Custom Column No.%(column)d is not existing in calibre database" +msgstr "Anpassad kolumn n.%(column)d finns inte i calibre-databasen" + +#: cps/db.py:917 cps/templates/config_edit.html:204 +#: cps/templates/config_view_edit.html:62 cps/templates/email_edit.html:41 +#: cps/web.py:551 cps/web.py:585 cps/web.py:646 cps/web.py:671 cps/web.py:1003 +#: cps/web.py:1032 cps/web.py:1066 cps/web.py:1093 cps/web.py:1132 +msgid "None" +msgstr "Ingen" + +#: cps/editbooks.py:295 cps/editbooks.py:297 +msgid "Book Format Successfully Deleted" +msgstr "Bokformat har tagits bort" + +#: cps/editbooks.py:304 cps/editbooks.py:306 +msgid "Book Successfully Deleted" +msgstr "Boken har tagits bort" + +#: cps/editbooks.py:358 +msgid "You are missing permissions to delete books" +msgstr "" + +#: cps/editbooks.py:373 cps/editbooks.py:765 cps/web.py:518 cps/web.py:1783 +#: cps/web.py:1825 cps/web.py:1870 +msgid "Oops! Selected book title is unavailable. File does not exist or is not accessible" +msgstr "Hoppsan! Vald boktitel är inte tillgänglig. Filen finns inte eller är inte tillgänglig" + +#: cps/editbooks.py:408 +msgid "edit metadata" +msgstr "redigera metadata" + +#: cps/editbooks.py:457 +#, python-format +msgid "%(seriesindex)s is not a valid number, skipping" +msgstr "" + +#: cps/editbooks.py:493 cps/editbooks.py:1001 +#, fuzzy, python-format +msgid "'%(langname)s' is not a valid language" +msgstr "%(langname)s är inte ett giltigt språk" + +#: cps/editbooks.py:634 +msgid "User has no rights to upload additional file formats" +msgstr "" + +#: cps/editbooks.py:639 cps/editbooks.py:1029 +#, python-format +msgid "File extension '%(ext)s' is not allowed to be uploaded to this server" +msgstr "Filändelsen '%(ext)s' får inte laddas upp till den här servern" + +#: cps/editbooks.py:643 cps/editbooks.py:1033 +msgid "File to be uploaded must have an extension" +msgstr "Filen som ska laddas upp måste ha en ändelse" + +#: cps/editbooks.py:655 +#, python-format +msgid "Failed to create path %(path)s (Permission denied)." +msgstr "Det gick inte att skapa sökväg %(path)s (behörighet nekad)." + +#: cps/editbooks.py:660 +#, python-format +msgid "Failed to store file %(file)s." +msgstr "Det gick inte att lagra filen %(file)s." + +#: cps/editbooks.py:683 #, python-format msgid "File format %(ext)s added to %(book)s" msgstr "Filformatet %(ext)s lades till %(book)s" -#: cps/editbooks.py:814 +#: cps/editbooks.py:697 cps/editbooks.py:809 +msgid "User has no rights to upload cover" +msgstr "" + +#: cps/editbooks.py:828 msgid "Identifiers are not Case Sensitive, Overwriting Old Identifier" msgstr "Identifierare är inte skiftlägeskänsliga, skriver över gammal identifierare" -#: cps/editbooks.py:848 +#: cps/editbooks.py:869 msgid "Metadata successfully updated" msgstr "Metadata uppdaterades" -#: cps/editbooks.py:861 -msgid "Error editing book, please check logfile for details" -msgstr "Det gick inte att redigera boken, kontrollera loggfilen för mer information" +#: cps/editbooks.py:887 +msgid "Error editing book: {}" +msgstr "" -#: cps/editbooks.py:899 +#: cps/editbooks.py:951 msgid "Uploaded book probably exists in the library, consider to change before upload new: " msgstr "Uppladdad bok finns förmodligen i biblioteket, överväg att ändra innan du laddar upp nya: " -#: cps/editbooks.py:997 +#: cps/editbooks.py:1041 #, python-format msgid "File %(filename)s could not saved to temp dir" msgstr "Filen %(filename)s kunde inte sparas i temp dir" -#: cps/editbooks.py:1016 +#: cps/editbooks.py:1061 #, python-format msgid "Failed to Move Cover File %(file)s: %(error)s" msgstr "Det gick inte att flytta omslagsfil %(file)s: %(error)s" -#: cps/editbooks.py:1063 +#: cps/editbooks.py:1117 #, python-format msgid "File %(file)s uploaded" msgstr "Filen %(file)s uppladdad" -#: cps/editbooks.py:1088 +#: cps/editbooks.py:1143 msgid "Source or destination format for conversion missing" msgstr "Källa eller målformat för konvertering saknas" -#: cps/editbooks.py:1096 +#: cps/editbooks.py:1151 #, python-format msgid "Book successfully queued for converting to %(book_format)s" msgstr "Boken är i kö för konvertering till %(book_format)s" -#: cps/editbooks.py:1100 +#: cps/editbooks.py:1155 #, python-format msgid "There was an error converting this book: %(res)s" msgstr "Det gick inte att konvertera den här boken: %(res)s" @@ -609,174 +612,191 @@ msgstr "Installationen av Google Drive är inte klar, försök att inaktivera oc msgid "Callback domain is not verified, please follow steps to verify domain in google developer console" msgstr "Återuppringningsdomänen är inte verifierad, följ stegen för att verifiera domänen i Google utvecklarkonsol" -#: cps/helper.py:77 +#: cps/helper.py:81 #, python-format msgid "%(format)s format not found for book id: %(book)d" msgstr "%(format)s formatet hittades inte för bok-id: %(book)d" -#: cps/helper.py:83 cps/tasks/convert.py:73 +#: cps/helper.py:87 cps/tasks/convert.py:75 #, python-format msgid "%(format)s not found on Google Drive: %(fn)s" msgstr "%(format)s hittades inte på Google Drive: %(fn)s" -#: cps/helper.py:88 +#: cps/helper.py:92 #, python-format msgid "%(format)s not found: %(fn)s" msgstr "%(format)s hittades inte: %(fn)s" -#: cps/helper.py:93 cps/helper.py:217 cps/templates/detail.html:41 +#: cps/helper.py:97 cps/helper.py:221 cps/templates/detail.html:41 #: cps/templates/detail.html:45 msgid "Send to Kindle" msgstr "Skicka till Kindle" -#: cps/helper.py:94 cps/helper.py:111 cps/helper.py:219 +#: cps/helper.py:98 cps/helper.py:115 cps/helper.py:223 msgid "This e-mail has been sent via Calibre-Web." msgstr "Detta e-postmeddelande har skickats via Calibre-Web." -#: cps/helper.py:109 +#: cps/helper.py:113 msgid "Calibre-Web test e-mail" msgstr "Calibre-Web test e-post" -#: cps/helper.py:110 +#: cps/helper.py:114 msgid "Test e-mail" msgstr "Test e-post" -#: cps/helper.py:127 +#: cps/helper.py:131 msgid "Get Started with Calibre-Web" msgstr "Kom igång med Calibre-Web" -#: cps/helper.py:132 +#: cps/helper.py:136 #, python-format msgid "Registration e-mail for user: %(name)s" msgstr "Registrera e-post för användare: %(name)s" -#: cps/helper.py:143 cps/helper.py:149 +#: cps/helper.py:147 cps/helper.py:153 #, python-format msgid "Convert %(orig)s to %(format)s and send to Kindle" msgstr "Konvertera %(orig)s till %(format)s och skicka till Kindle" -#: cps/helper.py:168 cps/helper.py:172 cps/helper.py:176 +#: cps/helper.py:172 cps/helper.py:176 cps/helper.py:180 #, python-format msgid "Send %(format)s to Kindle" msgstr "Skicka %(format)s till Kindle" -#: cps/helper.py:216 cps/tasks/convert.py:90 +#: cps/helper.py:220 cps/tasks/convert.py:92 #, fuzzy, python-format msgid "%(book)s send to Kindle" msgstr "Skicka till Kindle" -#: cps/helper.py:221 +#: cps/helper.py:225 msgid "The requested file could not be read. Maybe wrong permissions?" msgstr "Den begärda filen kunde inte läsas. Kanske fel behörigheter?" -#: cps/helper.py:313 +#: cps/helper.py:353 +msgid "Read status could not set: {}" +msgstr "" + +#: cps/helper.py:376 #, python-format msgid "Deleting bookfolder for book %(id)s failed, path has subfolders: %(path)s" msgstr "Borttagning av bokmapp för boken %(id)s misslyckades, sökvägen har undermappar: %(path)s" -#: cps/helper.py:319 +#: cps/helper.py:382 #, python-format msgid "Deleting book %(id)s failed: %(message)s" msgstr "Borttagning av boken %(id)s misslyckades: %(message)s" -#: cps/helper.py:330 +#: cps/helper.py:393 #, fuzzy, python-format msgid "Deleting book %(id)s from database only, book path in database not valid: %(path)s" msgstr "Borttagning av boken %(id)s, boksökväg inte giltig: %(path)s" -#: cps/helper.py:385 -#, python-format -msgid "Rename title from: '%(src)s' to '%(dest)s' failed with error: %(error)s" +#: cps/helper.py:458 +#, fuzzy, python-format +msgid "Rename author from: '%(src)s' to '%(dest)s' failed with error: %(error)s" msgstr "Byt namn på titel från: \"%(src)s\" till \"%(dest)s\" misslyckades med fel: %(error)s" -#: cps/helper.py:400 -#, python-format -msgid "Rename file in path '%(src)s' to '%(dest)s' failed with error: %(error)s" -msgstr "Byt namn på fil i sökvägen '%(src)s' till '%(dest)s' misslyckades med fel: %(error)s" - -#: cps/helper.py:425 cps/helper.py:435 cps/helper.py:443 +#: cps/helper.py:529 cps/helper.py:538 #, python-format msgid "File %(file)s not found on Google Drive" msgstr "Filen %(file)s hittades inte på Google Drive" -#: cps/helper.py:464 +#: cps/helper.py:572 +#, python-format +msgid "Rename title from: '%(src)s' to '%(dest)s' failed with error: %(error)s" +msgstr "Byt namn på titel från: \"%(src)s\" till \"%(dest)s\" misslyckades med fel: %(error)s" + +#: cps/helper.py:592 +msgid "Error in rename file in path: {}" +msgstr "" + +#: cps/helper.py:610 #, python-format msgid "Book path %(path)s not found on Google Drive" msgstr "Boksökvägen %(path)s hittades inte på Google Drive" -#: cps/helper.py:504 cps/web.py:1659 +#: cps/helper.py:651 cps/web.py:1737 msgid "Found an existing account for this e-mail address" msgstr "Hittade ett befintligt konto för den här e-postadressen" -#: cps/helper.py:512 +#: cps/helper.py:659 msgid "This username is already taken" msgstr "Detta användarnamn är redan taget" -#: cps/helper.py:522 +#: cps/helper.py:669 msgid "Invalid e-mail address format" msgstr "Ogiltigt e-postadressformat" -#: cps/helper.py:595 +#: cps/helper.py:754 +msgid "Python modul 'advocate' is not installed but is needed for cover downloads" +msgstr "" + +#: cps/helper.py:767 msgid "Error Downloading Cover" msgstr "Fel vid hämtning av omslaget" -#: cps/helper.py:598 +#: cps/helper.py:770 msgid "Cover Format Error" msgstr "Fel på omslagsformat" -#: cps/helper.py:608 +#: cps/helper.py:773 +msgid "You are not allowed to access localhost or the local network for cover uploads" +msgstr "" + +#: cps/helper.py:783 msgid "Failed to create path for cover" msgstr "Det gick inte att skapa sökväg för omslag" -#: cps/helper.py:624 +#: cps/helper.py:799 msgid "Cover-file is not a valid image file, or could not be stored" msgstr "Omslagsfilen är inte en giltig bildfil eller kunde inte lagras" -#: cps/helper.py:635 +#: cps/helper.py:810 msgid "Only jpg/jpeg/png/webp/bmp files are supported as coverfile" msgstr "Endast jpg/jpeg/png/webp/bmp-filer stöds som omslagsfil" -#: cps/helper.py:648 +#: cps/helper.py:822 msgid "Invalid cover file content" msgstr "" -#: cps/helper.py:652 +#: cps/helper.py:826 msgid "Only jpg/jpeg files are supported as coverfile" msgstr "Endast jpg/jpeg-filer stöds som omslagsfil" -#: cps/helper.py:704 +#: cps/helper.py:878 msgid "Unrar binary file not found" msgstr "Unrar binär fil hittades inte" -#: cps/helper.py:715 +#: cps/helper.py:889 msgid "Error excecuting UnRar" msgstr "Fel vid körning av UnRar" -#: cps/helper.py:763 +#: cps/helper.py:937 msgid "Waiting" msgstr "Väntar" -#: cps/helper.py:765 +#: cps/helper.py:939 msgid "Failed" msgstr "Misslyckades" -#: cps/helper.py:767 +#: cps/helper.py:941 msgid "Started" msgstr "Startad" -#: cps/helper.py:769 +#: cps/helper.py:943 msgid "Finished" msgstr "Klar" -#: cps/helper.py:771 +#: cps/helper.py:945 msgid "Unknown Status" msgstr "Okänd status" -#: cps/kobo_auth.py:127 -msgid "PLease access calibre-web from non localhost to get valid api_endpoint for kobo device" +#: cps/kobo_auth.py:128 +#, fuzzy +msgid "Please access Calibre-Web from non localhost to get valid api_endpoint for kobo device" msgstr "Vänligen få tillgång till calibre-web från icke localhost för att få giltig api_endpoint för Kobo-enhet" -#: cps/kobo_auth.py:130 cps/kobo_auth.py:158 +#: cps/kobo_auth.py:154 msgid "Kobo Setup" msgstr "Kobo-installation" @@ -785,7 +805,7 @@ msgstr "Kobo-installation" msgid "Register with %(provider)s" msgstr "Registrera dig med %(provider)s" -#: cps/oauth_bb.py:138 cps/remotelogin.py:133 cps/web.py:1535 +#: cps/oauth_bb.py:138 cps/remotelogin.py:130 cps/web.py:1613 #, python-format msgid "you are now logged in as: '%(nickname)s'" msgstr "du är nu inloggad som: \"%(nickname)s\"" @@ -846,163 +866,163 @@ msgstr "Google Oauth-fel, försök igen senare." msgid "Google Oauth error: {}" msgstr "Google Oauth-fel: {}" -#: cps/opds.py:384 +#: cps/opds.py:298 msgid "{} Stars" msgstr "{} stjärnor" -#: cps/remotelogin.py:65 cps/templates/layout.html:84 -#: cps/templates/login.html:4 cps/templates/login.html:21 cps/web.py:1584 +#: cps/remotelogin.py:62 cps/templates/layout.html:84 +#: cps/templates/login.html:4 cps/templates/login.html:21 cps/web.py:1662 msgid "Login" msgstr "Logga in" -#: cps/remotelogin.py:77 cps/remotelogin.py:111 +#: cps/remotelogin.py:74 cps/remotelogin.py:108 msgid "Token not found" msgstr "Token hittades inte" -#: cps/remotelogin.py:86 cps/remotelogin.py:119 +#: cps/remotelogin.py:83 cps/remotelogin.py:116 msgid "Token has expired" msgstr "Token har löpt ut" -#: cps/remotelogin.py:95 +#: cps/remotelogin.py:92 msgid "Success! Please return to your device" msgstr "Lyckades! Vänligen återvänd till din enhet" -#: cps/render_template.py:39 cps/web.py:416 +#: cps/render_template.py:41 cps/web.py:407 msgid "Books" msgstr "Böcker" -#: cps/render_template.py:41 +#: cps/render_template.py:43 msgid "Show recent books" msgstr "Visa senaste böcker" -#: cps/render_template.py:42 cps/templates/index.xml:25 +#: cps/render_template.py:44 cps/templates/index.xml:25 msgid "Hot Books" msgstr "Heta böcker" -#: cps/render_template.py:44 +#: cps/render_template.py:46 msgid "Show Hot Books" msgstr "Visa heta böcker" -#: cps/render_template.py:46 cps/render_template.py:51 +#: cps/render_template.py:48 cps/render_template.py:53 msgid "Downloaded Books" msgstr "Hämtade böcker" -#: cps/render_template.py:48 cps/render_template.py:53 +#: cps/render_template.py:50 cps/render_template.py:55 #: cps/templates/user_table.html:167 msgid "Show Downloaded Books" msgstr "Visa hämtade böcker" -#: cps/render_template.py:56 cps/templates/index.xml:32 cps/web.py:430 +#: cps/render_template.py:58 cps/templates/index.xml:32 cps/web.py:422 msgid "Top Rated Books" msgstr "Bäst rankade böcker" -#: cps/render_template.py:58 cps/templates/user_table.html:161 +#: cps/render_template.py:60 cps/templates/user_table.html:161 msgid "Show Top Rated Books" msgstr "Visa böcker med bästa betyg" -#: cps/render_template.py:59 cps/templates/index.xml:54 -#: cps/templates/index.xml:58 cps/web.py:676 +#: cps/render_template.py:61 cps/templates/index.xml:54 +#: cps/templates/index.xml:58 cps/web.py:729 msgid "Read Books" msgstr "Lästa böcker" -#: cps/render_template.py:61 +#: cps/render_template.py:63 msgid "Show read and unread" msgstr "Visa lästa och olästa" -#: cps/render_template.py:63 cps/templates/index.xml:61 -#: cps/templates/index.xml:65 cps/web.py:679 +#: cps/render_template.py:65 cps/templates/index.xml:61 +#: cps/templates/index.xml:65 cps/web.py:732 msgid "Unread Books" msgstr "Olästa böcker" -#: cps/render_template.py:65 +#: cps/render_template.py:67 msgid "Show unread" msgstr "Visa olästa" -#: cps/render_template.py:66 +#: cps/render_template.py:68 msgid "Discover" msgstr "Upptäck" -#: cps/render_template.py:68 cps/templates/index.xml:50 +#: cps/render_template.py:70 cps/templates/index.xml:50 #: cps/templates/user_table.html:162 msgid "Show Random Books" msgstr "Visa slumpmässiga böcker" -#: cps/render_template.py:69 cps/templates/book_table.html:67 -#: cps/templates/index.xml:83 cps/web.py:1041 +#: cps/render_template.py:71 cps/templates/book_table.html:67 +#: cps/templates/index.xml:83 cps/web.py:1135 msgid "Categories" msgstr "Kategorier" -#: cps/render_template.py:71 cps/templates/user_table.html:158 +#: cps/render_template.py:73 cps/templates/user_table.html:158 msgid "Show category selection" msgstr "Visa kategorival" -#: cps/render_template.py:72 cps/templates/book_edit.html:90 +#: cps/render_template.py:74 cps/templates/book_edit.html:90 #: cps/templates/book_table.html:68 cps/templates/index.xml:90 -#: cps/templates/search_form.html:69 cps/web.py:948 cps/web.py:959 +#: cps/templates/search_form.html:69 cps/web.py:1034 cps/web.py:1041 msgid "Series" msgstr "Serier" -#: cps/render_template.py:74 cps/templates/user_table.html:157 +#: cps/render_template.py:76 cps/templates/user_table.html:157 msgid "Show series selection" msgstr "Visa serieval" -#: cps/render_template.py:75 cps/templates/book_table.html:66 +#: cps/render_template.py:77 cps/templates/book_table.html:66 #: cps/templates/index.xml:69 msgid "Authors" msgstr "Författare" -#: cps/render_template.py:77 cps/templates/user_table.html:160 +#: cps/render_template.py:79 cps/templates/user_table.html:160 msgid "Show author selection" msgstr "Visa författarval" -#: cps/render_template.py:79 cps/templates/book_table.html:72 -#: cps/templates/index.xml:76 cps/web.py:925 +#: cps/render_template.py:81 cps/templates/book_table.html:72 +#: cps/templates/index.xml:76 cps/web.py:1006 msgid "Publishers" msgstr "Förlag" -#: cps/render_template.py:81 cps/templates/user_table.html:163 +#: cps/render_template.py:83 cps/templates/user_table.html:163 msgid "Show publisher selection" msgstr "Visa urval av förlag" -#: cps/render_template.py:82 cps/templates/book_table.html:70 +#: cps/render_template.py:84 cps/templates/book_table.html:70 #: cps/templates/index.xml:97 cps/templates/search_form.html:107 -#: cps/web.py:1018 +#: cps/web.py:1108 msgid "Languages" msgstr "Språk" -#: cps/render_template.py:85 cps/templates/user_table.html:155 +#: cps/render_template.py:87 cps/templates/user_table.html:155 msgid "Show language selection" msgstr "Visa språkval" -#: cps/render_template.py:86 cps/templates/index.xml:104 +#: cps/render_template.py:88 cps/templates/index.xml:104 msgid "Ratings" msgstr "Betyg" -#: cps/render_template.py:88 cps/templates/user_table.html:164 +#: cps/render_template.py:90 cps/templates/user_table.html:164 msgid "Show ratings selection" msgstr "Visa val av betyg" -#: cps/render_template.py:89 cps/templates/index.xml:112 +#: cps/render_template.py:91 cps/templates/index.xml:112 msgid "File formats" msgstr "Filformat" -#: cps/render_template.py:91 cps/templates/user_table.html:165 +#: cps/render_template.py:93 cps/templates/user_table.html:165 msgid "Show file formats selection" msgstr "Visa val av filformat" -#: cps/render_template.py:93 cps/web.py:703 +#: cps/render_template.py:95 cps/web.py:755 msgid "Archived Books" msgstr "Arkiverade böcker" -#: cps/render_template.py:95 cps/templates/user_table.html:166 +#: cps/render_template.py:97 cps/templates/user_table.html:166 msgid "Show archived books" msgstr "Visa arkiverade böcker" -#: cps/render_template.py:97 cps/web.py:780 +#: cps/render_template.py:100 cps/web.py:837 msgid "Books List" msgstr "Boklista" -#: cps/render_template.py:99 cps/templates/user_table.html:168 +#: cps/render_template.py:102 cps/templates/user_table.html:168 msgid "Show Books List" msgstr "Visa boklista" @@ -1057,262 +1077,266 @@ msgstr "" msgid "Create a Shelf" msgstr "Skapa en hylla" -#: cps/shelf.py:237 +#: cps/shelf.py:236 #, fuzzy msgid "Sorry you are not allowed to edit this shelf" msgstr "Tyvärr har du inte rätt att ta bort en bok från den här hyllan: %(sname)s" -#: cps/shelf.py:239 +#: cps/shelf.py:238 msgid "Edit a shelf" msgstr "Redigera en hylla" -#: cps/shelf.py:249 +#: cps/shelf.py:248 msgid "Sorry you are not allowed to create a public shelf" msgstr "" -#: cps/shelf.py:266 +#: cps/shelf.py:265 #, python-format msgid "Shelf %(title)s created" msgstr "Hyllan %(title)s skapad" -#: cps/shelf.py:269 +#: cps/shelf.py:268 #, python-format msgid "Shelf %(title)s changed" msgstr "Hyllan %(title)s ändrad" -#: cps/shelf.py:283 +#: cps/shelf.py:282 msgid "There was an error" msgstr "Det fanns ett fel" -#: cps/shelf.py:305 +#: cps/shelf.py:304 #, python-format msgid "A public shelf with the name '%(title)s' already exists." msgstr "En offentlig hylla med namnet \"%(title)s\" finns redan." -#: cps/shelf.py:316 +#: cps/shelf.py:315 #, python-format msgid "A private shelf with the name '%(title)s' already exists." msgstr "En privat hylla med namnet \"%(title)s\" finns redan." #: cps/shelf.py:337 +msgid "Error deleting Shelf" +msgstr "" + +#: cps/shelf.py:339 #, fuzzy msgid "Shelf successfully deleted" msgstr "Boken har tagits bort" -#: cps/shelf.py:386 +#: cps/shelf.py:389 #, python-format msgid "Change order of Shelf: '%(name)s'" msgstr "Ändra ordning på hyllan: '%(name)s'" -#: cps/shelf.py:456 +#: cps/shelf.py:461 #, python-format msgid "Shelf: '%(name)s'" msgstr "Hylla: '%(name)s'" -#: cps/shelf.py:460 +#: cps/shelf.py:465 msgid "Error opening shelf. Shelf does not exist or is not accessible" msgstr "Fel vid öppning av hyllan. Hylla finns inte eller är inte tillgänglig" -#: cps/updater.py:403 cps/updater.py:414 cps/updater.py:514 cps/updater.py:529 +#: cps/updater.py:426 cps/updater.py:437 cps/updater.py:538 cps/updater.py:553 msgid "Unexpected data while reading update information" msgstr "Oväntade data vid läsning av uppdateringsinformation" -#: cps/updater.py:410 cps/updater.py:521 +#: cps/updater.py:433 cps/updater.py:545 msgid "No update available. You already have the latest version installed" msgstr "Ingen uppdatering tillgänglig. Du har redan den senaste versionen installerad" -#: cps/updater.py:428 +#: cps/updater.py:451 msgid "A new update is available. Click on the button below to update to the latest version." msgstr "En ny uppdatering är tillgänglig. Klicka på knappen nedan för att uppdatera till den senaste versionen." -#: cps/updater.py:446 +#: cps/updater.py:469 msgid "Could not fetch update information" msgstr "Kunde inte hämta uppdateringsinformation" -#: cps/updater.py:456 +#: cps/updater.py:479 msgid "Click on the button below to update to the latest stable version." msgstr "Klicka på knappen nedan för att uppdatera till den senaste stabila versionen." -#: cps/updater.py:465 cps/updater.py:479 cps/updater.py:490 +#: cps/updater.py:488 cps/updater.py:502 cps/updater.py:513 #, python-format msgid "A new update is available. Click on the button below to update to version: %(version)s" msgstr "En ny uppdatering är tillgänglig. Klicka på knappen nedan för att uppdatera till version: %(version)s" -#: cps/updater.py:507 +#: cps/updater.py:531 msgid "No release information available" msgstr "Ingen versionsinformation tillgänglig" -#: cps/templates/index.html:5 cps/web.py:440 +#: cps/templates/index.html:5 cps/web.py:434 msgid "Discover (Random Books)" msgstr "Upptäck (slumpmässiga böcker)" -#: cps/web.py:471 +#: cps/web.py:470 msgid "Hot Books (Most Downloaded)" msgstr "Heta böcker (mest hämtade)" -#: cps/web.py:507 +#: cps/web.py:501 #, python-format msgid "Downloaded books by %(user)s" msgstr "Hämtade böcker av %(user)s" -#: cps/web.py:539 +#: cps/web.py:534 #, python-format msgid "Author: %(name)s" msgstr "Författare: %(name)s" -#: cps/web.py:554 +#: cps/web.py:570 #, python-format msgid "Publisher: %(name)s" msgstr "Förlag: %(name)s" -#: cps/web.py:569 +#: cps/web.py:598 #, python-format msgid "Series: %(serie)s" msgstr "Serier: %(serie)s" -#: cps/web.py:582 +#: cps/web.py:610 #, python-format msgid "Rating: %(rating)s stars" msgstr "Betyg: %(rating)s stars" -#: cps/web.py:597 +#: cps/web.py:626 #, python-format msgid "File format: %(format)s" msgstr "Filformat: %(format)s" -#: cps/web.py:615 +#: cps/web.py:663 #, python-format msgid "Category: %(name)s" msgstr "Kategori: %(name)s" -#: cps/web.py:631 +#: cps/web.py:690 #, python-format msgid "Language: %(name)s" msgstr "Språk: %(name)s" -#: cps/templates/layout.html:56 cps/web.py:737 cps/web.py:1371 +#: cps/templates/layout.html:56 cps/web.py:789 cps/web.py:1444 msgid "Advanced Search" msgstr "Avancerad sökning" #: cps/templates/book_edit.html:235 cps/templates/feed.xml:33 #: cps/templates/index.xml:11 cps/templates/layout.html:45 #: cps/templates/layout.html:48 cps/templates/search_form.html:226 -#: cps/web.py:750 cps/web.py:1077 +#: cps/web.py:807 cps/web.py:1164 msgid "Search" msgstr "Sök" -#: cps/templates/admin.html:16 cps/web.py:903 +#: cps/templates/admin.html:16 cps/web.py:979 msgid "Downloads" msgstr "Hämtningar" -#: cps/web.py:980 +#: cps/web.py:1068 msgid "Ratings list" msgstr "Betygslista" -#: cps/web.py:1001 +#: cps/web.py:1095 msgid "File formats list" msgstr "Lista över filformat" -#: cps/templates/layout.html:73 cps/templates/tasks.html:7 cps/web.py:1055 +#: cps/templates/layout.html:73 cps/templates/tasks.html:7 cps/web.py:1149 msgid "Tasks" msgstr "Uppgifter" -#: cps/web.py:1215 +#: cps/web.py:1286 msgid "Published after " msgstr "Publicerad efter " -#: cps/web.py:1222 +#: cps/web.py:1293 msgid "Published before " msgstr "Publicerad före " -#: cps/web.py:1244 +#: cps/web.py:1315 #, python-format msgid "Rating <= %(rating)s" msgstr "Betyg <= %(rating)s" -#: cps/web.py:1246 +#: cps/web.py:1317 #, python-format msgid "Rating >= %(rating)s" msgstr "Betyg >= %(rating)s" -#: cps/web.py:1248 +#: cps/web.py:1319 #, python-format msgid "Read Status = %(status)s" msgstr "Lässtatus = %(status)s" -#: cps/web.py:1353 +#: cps/web.py:1425 msgid "Error on search for custom columns, please restart Calibre-Web" msgstr "" -#: cps/web.py:1449 +#: cps/web.py:1527 #, python-format msgid "Book successfully queued for sending to %(kindlemail)s" msgstr "Boken är i kö för att skicka till %(kindlemail)s" -#: cps/web.py:1453 +#: cps/web.py:1531 #, python-format msgid "Oops! There was an error sending this book: %(res)s" msgstr "Det gick inte att skicka den här boken: %(res)s" -#: cps/web.py:1455 +#: cps/web.py:1533 msgid "Please update your profile with a valid Send to Kindle E-mail Address." msgstr "Konfigurera din kindle-e-postadress först..." -#: cps/web.py:1472 +#: cps/web.py:1550 msgid "E-Mail server is not configured, please contact your administrator!" msgstr "E-postservern är inte konfigurerad, kontakta din administratör!" -#: cps/templates/layout.html:85 cps/templates/register.html:17 cps/web.py:1473 -#: cps/web.py:1480 cps/web.py:1486 cps/web.py:1505 cps/web.py:1509 -#: cps/web.py:1515 +#: cps/templates/layout.html:85 cps/templates/register.html:17 cps/web.py:1551 +#: cps/web.py:1558 cps/web.py:1564 cps/web.py:1583 cps/web.py:1587 +#: cps/web.py:1593 msgid "Register" msgstr "Registrera" -#: cps/web.py:1507 +#: cps/web.py:1585 msgid "Your e-mail is not allowed to register" msgstr "Din e-post är inte tillåten att registrera" -#: cps/web.py:1510 +#: cps/web.py:1588 msgid "Confirmation e-mail was send to your e-mail account." msgstr "Bekräftelsemail skickades till ditt e-postkonto." -#: cps/web.py:1524 +#: cps/web.py:1602 msgid "Cannot activate LDAP authentication" msgstr "Det går inte att aktivera LDAP-autentisering" -#: cps/web.py:1543 +#: cps/web.py:1621 #, python-format msgid "Fallback Login as: '%(nickname)s', LDAP Server not reachable, or user not known" msgstr "" -#: cps/web.py:1549 +#: cps/web.py:1627 #, python-format msgid "Could not login: %(message)s" msgstr "Det gick inte att logga in: %(message)s" -#: cps/web.py:1553 cps/web.py:1578 +#: cps/web.py:1631 cps/web.py:1656 msgid "Wrong Username or Password" msgstr "Fel användarnamn eller lösenord" -#: cps/web.py:1560 +#: cps/web.py:1638 msgid "New Password was send to your email address" msgstr "Nytt lösenord skickades till din e-postadress" -#: cps/web.py:1566 +#: cps/web.py:1644 msgid "Please enter valid username to reset password" msgstr "Ange giltigt användarnamn för att återställa lösenordet" -#: cps/web.py:1573 +#: cps/web.py:1651 #, python-format msgid "You are now logged in as: '%(nickname)s'" msgstr "Du är nu inloggad som: \"%(nickname)s\"" -#: cps/web.py:1639 cps/web.py:1688 +#: cps/web.py:1717 cps/web.py:1766 #, python-format msgid "%(name)s's profile" msgstr "%(name)ss profil" -#: cps/web.py:1655 +#: cps/web.py:1733 msgid "Profile updated" msgstr "Profilen uppdaterad" @@ -1320,36 +1344,36 @@ msgstr "Profilen uppdaterad" msgid "Found no valid gmail.json file with OAuth information" msgstr "Hittade ingen giltig gmail.json-fil med OAuth-information" -#: cps/tasks/convert.py:137 +#: cps/tasks/convert.py:154 #, python-format msgid "Calibre ebook-convert %(tool)s not found" msgstr "calibre e-bokkonverterings %(tool)s hittades inte" -#: cps/tasks/convert.py:163 +#: cps/tasks/convert.py:187 #, python-format msgid "%(format)s format not found on disk" msgstr "%(format)s-format hittades inte på disken" -#: cps/tasks/convert.py:167 +#: cps/tasks/convert.py:191 msgid "Ebook converter failed with unknown error" msgstr "E-bokkonverteraren misslyckades med okänt fel" -#: cps/tasks/convert.py:177 +#: cps/tasks/convert.py:201 #, python-format msgid "Kepubify-converter failed: %(error)s" msgstr "Kepubify-konverteraren misslyckades: %(error)s" -#: cps/tasks/convert.py:199 +#: cps/tasks/convert.py:223 #, python-format msgid "Converted file not found or more than one file in folder %(folder)s" msgstr "Konverterad fil hittades inte eller mer än en fil i mappen %(folder)s" -#: cps/tasks/convert.py:222 +#: cps/tasks/convert.py:246 #, python-format msgid "Ebook-converter failed: %(error)s" msgstr "E-bokkonverteraren misslyckades: %(error)s" -#: cps/tasks/convert.py:245 +#: cps/tasks/convert.py:269 #, python-format msgid "Calibre failed with error: %(error)s" msgstr "calibre misslyckades med fel: %(error)s" @@ -1404,7 +1428,7 @@ msgid "Edit" msgstr "Redigera" #: cps/templates/admin.html:25 cps/templates/book_edit.html:16 -#: cps/templates/book_table.html:97 cps/templates/modal_dialogs.html:63 +#: cps/templates/book_table.html:100 cps/templates/modal_dialogs.html:63 #: cps/templates/modal_dialogs.html:116 cps/templates/user_edit.html:67 #: cps/templates/user_table.html:149 msgid "Delete" @@ -1414,180 +1438,180 @@ msgstr "Ta bort" msgid "Public Shelf" msgstr "Publik hylla" -#: cps/templates/admin.html:51 +#: cps/templates/admin.html:53 msgid "Add New User" msgstr "Lägg till ny användare" -#: cps/templates/admin.html:53 +#: cps/templates/admin.html:55 msgid "Import LDAP Users" msgstr "Importera LDAP-användare" -#: cps/templates/admin.html:60 +#: cps/templates/admin.html:62 msgid "E-mail Server Settings" msgstr "Inställningar för SMTP-e-postserver" -#: cps/templates/admin.html:65 cps/templates/email_edit.html:31 +#: cps/templates/admin.html:67 cps/templates/email_edit.html:31 msgid "SMTP Hostname" msgstr "SMTP-värdnamn" -#: cps/templates/admin.html:69 cps/templates/email_edit.html:35 +#: cps/templates/admin.html:71 cps/templates/email_edit.html:35 msgid "SMTP Port" msgstr "SMTP-port" -#: cps/templates/admin.html:73 cps/templates/email_edit.html:39 +#: cps/templates/admin.html:75 cps/templates/email_edit.html:39 msgid "Encryption" msgstr "SSL" -#: cps/templates/admin.html:77 cps/templates/email_edit.html:47 +#: cps/templates/admin.html:79 cps/templates/email_edit.html:47 msgid "SMTP Login" msgstr "SMTP-inloggning" -#: cps/templates/admin.html:81 cps/templates/admin.html:92 +#: cps/templates/admin.html:83 cps/templates/admin.html:94 #: cps/templates/email_edit.html:55 msgid "From E-mail" msgstr "Från meddelande" -#: cps/templates/admin.html:88 +#: cps/templates/admin.html:90 msgid "E-Mail Service" msgstr "E-posttjänst" -#: cps/templates/admin.html:89 +#: cps/templates/admin.html:91 msgid "Gmail via Oauth2" msgstr "Gmail via Oauth2" -#: cps/templates/admin.html:104 +#: cps/templates/admin.html:106 msgid "Configuration" msgstr "Konfiguration" -#: cps/templates/admin.html:107 +#: cps/templates/admin.html:109 msgid "Calibre Database Directory" msgstr "Calibre DB dir" -#: cps/templates/admin.html:111 cps/templates/config_edit.html:68 +#: cps/templates/admin.html:113 cps/templates/config_edit.html:68 msgid "Log Level" msgstr "Loggnivå" -#: cps/templates/admin.html:115 +#: cps/templates/admin.html:117 msgid "Port" msgstr "Port" -#: cps/templates/admin.html:120 +#: cps/templates/admin.html:122 msgid "External Port" msgstr "Extern port" -#: cps/templates/admin.html:127 cps/templates/config_view_edit.html:28 +#: cps/templates/admin.html:129 cps/templates/config_view_edit.html:28 msgid "Books per Page" msgstr "Böcker per sida" -#: cps/templates/admin.html:131 +#: cps/templates/admin.html:133 msgid "Uploads" msgstr "Laddar upp" -#: cps/templates/admin.html:135 +#: cps/templates/admin.html:137 msgid "Anonymous Browsing" msgstr "Anonym surfning" -#: cps/templates/admin.html:139 +#: cps/templates/admin.html:141 msgid "Public Registration" msgstr "Publik registrering" -#: cps/templates/admin.html:143 +#: cps/templates/admin.html:145 msgid "Magic Link Remote Login" msgstr "Fjärrinloggning" -#: cps/templates/admin.html:147 +#: cps/templates/admin.html:149 msgid "Reverse Proxy Login" msgstr "Omvänd proxy inloggning" -#: cps/templates/admin.html:152 cps/templates/config_edit.html:173 +#: cps/templates/admin.html:154 cps/templates/config_edit.html:173 msgid "Reverse Proxy Header Name" msgstr "Omvänt proxy rubriknamn" -#: cps/templates/admin.html:157 +#: cps/templates/admin.html:159 #, fuzzy msgid "Edit Calibre Database Configuration" msgstr "Redigera grundläggande konfiguration" -#: cps/templates/admin.html:158 +#: cps/templates/admin.html:160 msgid "Edit Basic Configuration" msgstr "Redigera grundläggande konfiguration" -#: cps/templates/admin.html:159 +#: cps/templates/admin.html:161 msgid "Edit UI Configuration" msgstr "Redigera UI-konfiguration" -#: cps/templates/admin.html:164 +#: cps/templates/admin.html:166 msgid "Administration" msgstr "Administration" -#: cps/templates/admin.html:165 +#: cps/templates/admin.html:167 msgid "Download Debug Package" msgstr "Hämta felsökningspaketet" -#: cps/templates/admin.html:166 +#: cps/templates/admin.html:168 msgid "View Logs" msgstr "Visa loggfiler" -#: cps/templates/admin.html:169 +#: cps/templates/admin.html:171 msgid "Reconnect Calibre Database" msgstr "Anslut till Calibre DB igen" -#: cps/templates/admin.html:170 +#: cps/templates/admin.html:172 msgid "Restart" msgstr "Starta om Calibre-Web" -#: cps/templates/admin.html:171 +#: cps/templates/admin.html:173 msgid "Shutdown" msgstr "Stoppa Calibre-Web" -#: cps/templates/admin.html:176 +#: cps/templates/admin.html:178 msgid "Update" msgstr "Uppdatera" -#: cps/templates/admin.html:180 +#: cps/templates/admin.html:182 msgid "Version" msgstr "Version" -#: cps/templates/admin.html:181 +#: cps/templates/admin.html:183 msgid "Details" msgstr "Detaljer" -#: cps/templates/admin.html:187 +#: cps/templates/admin.html:189 msgid "Current version" msgstr "Aktuell version" -#: cps/templates/admin.html:194 +#: cps/templates/admin.html:196 msgid "Check for Update" msgstr "Sök efter uppdatering" -#: cps/templates/admin.html:195 +#: cps/templates/admin.html:197 msgid "Perform Update" msgstr "Utför uppdatering" -#: cps/templates/admin.html:208 +#: cps/templates/admin.html:210 msgid "Are you sure you want to restart?" msgstr "Är du säker på att du vill starta om Calibre-Web?" -#: cps/templates/admin.html:213 cps/templates/admin.html:227 -#: cps/templates/admin.html:247 cps/templates/config_db.html:70 +#: cps/templates/admin.html:215 cps/templates/admin.html:229 +#: cps/templates/admin.html:249 cps/templates/config_db.html:70 msgid "OK" msgstr "Ok" -#: cps/templates/admin.html:214 cps/templates/admin.html:228 -#: cps/templates/book_edit.html:213 cps/templates/book_table.html:124 +#: cps/templates/admin.html:216 cps/templates/admin.html:230 +#: cps/templates/book_edit.html:213 cps/templates/book_table.html:127 #: cps/templates/config_db.html:54 cps/templates/config_edit.html:359 -#: cps/templates/config_view_edit.html:173 cps/templates/modal_dialogs.html:64 +#: cps/templates/config_view_edit.html:175 cps/templates/modal_dialogs.html:64 #: cps/templates/modal_dialogs.html:99 cps/templates/modal_dialogs.html:117 #: cps/templates/modal_dialogs.html:135 cps/templates/shelf_edit.html:27 #: cps/templates/user_edit.html:144 msgid "Cancel" msgstr "Avbryt" -#: cps/templates/admin.html:226 +#: cps/templates/admin.html:228 msgid "Are you sure you want to shutdown?" msgstr "Är du säker på att du vill stoppa Calibre-Web?" -#: cps/templates/admin.html:238 +#: cps/templates/admin.html:240 msgid "Updating, please do not reload this page" msgstr "Uppdaterar, vänligen uppdatera inte sidan" @@ -1599,44 +1623,43 @@ msgstr "via" msgid "In Library" msgstr "I biblioteket" -#: cps/templates/author.html:26 cps/templates/index.html:72 -#: cps/templates/search.html:29 cps/templates/shelf.html:19 +#: cps/templates/author.html:26 cps/templates/index.html:73 +#: cps/templates/search.html:30 cps/templates/shelf.html:19 msgid "Sort according to book date, newest first" msgstr "Sortera efter bokdatum, nyast först" -#: cps/templates/author.html:27 cps/templates/index.html:73 -#: cps/templates/search.html:30 cps/templates/shelf.html:20 +#: cps/templates/author.html:27 cps/templates/index.html:74 +#: cps/templates/search.html:31 cps/templates/shelf.html:20 msgid "Sort according to book date, oldest first" msgstr "Sortera efter bokdatum, äldsta först" -#: cps/templates/author.html:28 cps/templates/index.html:74 -#: cps/templates/search.html:31 cps/templates/shelf.html:21 +#: cps/templates/author.html:28 cps/templates/index.html:75 +#: cps/templates/search.html:32 cps/templates/shelf.html:21 msgid "Sort title in alphabetical order" msgstr "Sortera titel i alfabetisk ordning" -#: cps/templates/author.html:29 cps/templates/index.html:75 -#: cps/templates/search.html:32 cps/templates/shelf.html:22 +#: cps/templates/author.html:29 cps/templates/index.html:76 +#: cps/templates/search.html:33 cps/templates/shelf.html:22 msgid "Sort title in reverse alphabetical order" msgstr "Sortera titel i omvänd alfabetisk ordning" -#: cps/templates/author.html:30 cps/templates/index.html:78 -#: cps/templates/search.html:35 cps/templates/shelf.html:25 +#: cps/templates/author.html:30 cps/templates/index.html:79 +#: cps/templates/search.html:36 cps/templates/shelf.html:25 msgid "Sort according to publishing date, newest first" msgstr "Sortera efter publiceringsdatum, nyast först" -#: cps/templates/author.html:31 cps/templates/index.html:79 -#: cps/templates/search.html:36 cps/templates/shelf.html:26 +#: cps/templates/author.html:31 cps/templates/index.html:80 +#: cps/templates/search.html:37 cps/templates/shelf.html:26 msgid "Sort according to publishing date, oldest first" msgstr "Sortera efter publiceringsdatum, äldsta först" -#: cps/templates/author.html:57 cps/templates/author.html:117 -#: cps/templates/discover.html:30 cps/templates/index.html:29 -#: cps/templates/index.html:111 cps/templates/search.html:65 -#: cps/templates/shelf.html:54 +#: cps/templates/author.html:56 cps/templates/author.html:115 +#: cps/templates/index.html:29 cps/templates/index.html:112 +#: cps/templates/search.html:66 cps/templates/shelf.html:54 msgid "reduce" msgstr "minska" -#: cps/templates/author.html:101 +#: cps/templates/author.html:99 msgid "More by" msgstr "Mer av" @@ -1761,7 +1784,7 @@ msgid "Fetch Metadata" msgstr "Hämta metadata" #: cps/templates/book_edit.html:212 cps/templates/config_db.html:53 -#: cps/templates/config_edit.html:358 cps/templates/config_view_edit.html:172 +#: cps/templates/config_edit.html:358 cps/templates/config_view_edit.html:174 #: cps/templates/email_edit.html:65 cps/templates/shelf_edit.html:25 #: cps/templates/shelf_order.html:41 cps/templates/user_edit.html:142 msgid "Save" @@ -1890,27 +1913,35 @@ msgstr "Ange domännamn" msgid "Comments" msgstr "" -#: cps/templates/book_table.html:77 cps/templates/book_table.html:79 -#: cps/templates/book_table.html:81 cps/templates/book_table.html:83 -#: cps/templates/book_table.html:87 cps/templates/book_table.html:89 -#: cps/templates/book_table.html:91 cps/templates/book_table.html:93 +#: cps/templates/book_table.html:75 +msgid "Archiv Status" +msgstr "" + +#: cps/templates/book_table.html:77 cps/templates/search_form.html:42 +msgid "Read Status" +msgstr "Lässtatus" + +#: cps/templates/book_table.html:80 cps/templates/book_table.html:82 +#: cps/templates/book_table.html:84 cps/templates/book_table.html:86 +#: cps/templates/book_table.html:90 cps/templates/book_table.html:92 +#: cps/templates/book_table.html:96 #, fuzzy msgid "Enter " msgstr "Identifierare" -#: cps/templates/book_table.html:110 cps/templates/modal_dialogs.html:46 +#: cps/templates/book_table.html:113 cps/templates/modal_dialogs.html:46 msgid "Are you really sure?" msgstr "Är du verkligen säker?" -#: cps/templates/book_table.html:114 +#: cps/templates/book_table.html:117 msgid "Books with Title will be merged from:" msgstr "Böcker med titel slås samman från:" -#: cps/templates/book_table.html:118 +#: cps/templates/book_table.html:121 msgid "Into Book with Title:" msgstr "I bok med titel:" -#: cps/templates/book_table.html:123 +#: cps/templates/book_table.html:126 msgid "Merge" msgstr "Slå samman" @@ -2087,11 +2118,6 @@ msgstr "LDAP-serverport" msgid "LDAP Encryption" msgstr "LDAP-kryptering" -#: cps/templates/config_edit.html:204 cps/templates/config_view_edit.html:62 -#: cps/templates/email_edit.html:41 -msgid "None" -msgstr "Ingen" - #: cps/templates/config_edit.html:205 msgid "TLS" msgstr "TLS" @@ -2310,11 +2336,11 @@ msgstr "Standardvisibiliteter för nya användare" msgid "Show Random Books in Detail View" msgstr "Visa slumpmässiga böcker i detaljvyn" -#: cps/templates/config_view_edit.html:165 cps/templates/user_edit.html:87 +#: cps/templates/config_view_edit.html:166 cps/templates/user_edit.html:87 msgid "Add Allowed/Denied Tags" msgstr "Lägg till tillåtna/avvisade taggar" -#: cps/templates/config_view_edit.html:166 +#: cps/templates/config_view_edit.html:167 msgid "Add Allowed/Denied custom column values" msgstr "Lägg till tillåtna/avvisade anpassade kolumnvärden" @@ -2363,13 +2389,13 @@ msgstr "Arkiverad" msgid "Description:" msgstr "Beskrivning:" -#: cps/templates/detail.html:256 cps/templates/search.html:14 +#: cps/templates/detail.html:256 cps/templates/search.html:15 msgid "Add to shelf" msgstr "Lägg till hyllan" #: cps/templates/detail.html:267 cps/templates/detail.html:284 #: cps/templates/feed.xml:79 cps/templates/layout.html:137 -#: cps/templates/search.html:20 +#: cps/templates/search.html:21 msgid "(Public)" msgstr "(Publik)" @@ -2448,10 +2474,15 @@ msgstr "Avvisade domäner för registrering" msgid "Next" msgstr "Nästa" -#: cps/templates/generate_kobo_auth_url.html:5 +#: cps/templates/generate_kobo_auth_url.html:6 msgid "Open the .kobo/Kobo eReader.conf file in a text editor and add (or edit):" msgstr "Öppna filen .kobo/Kobo eReader.conf i en textredigerare och lägg till (eller redigera):" +#: cps/templates/generate_kobo_auth_url.html:11 +#, fuzzy +msgid "Kobo Token:" +msgstr "Kobo Sync Token" + #: cps/templates/http_error.html:31 #, fuzzy msgid "Calibre-Web Instance is unconfigured, please contact your administrator" @@ -2469,29 +2500,29 @@ msgstr "Tillbaka till hemmet" msgid "Logout User" msgstr "" -#: cps/templates/index.html:69 +#: cps/templates/index.html:70 msgid "Sort ascending according to download count" msgstr "" -#: cps/templates/index.html:70 +#: cps/templates/index.html:71 msgid "Sort descending according to download count" msgstr "" -#: cps/templates/index.html:76 cps/templates/search.html:33 +#: cps/templates/index.html:77 cps/templates/search.html:34 #: cps/templates/shelf.html:23 msgid "Sort authors in alphabetical order" msgstr "Sortera författare i alfabetisk ordning" -#: cps/templates/index.html:77 cps/templates/search.html:34 +#: cps/templates/index.html:78 cps/templates/search.html:35 #: cps/templates/shelf.html:24 msgid "Sort authors in reverse alphabetical order" msgstr "Sortera författare i omvänd alfabetisk ordning" -#: cps/templates/index.html:81 +#: cps/templates/index.html:82 msgid "Sort ascending according to series index" msgstr "Sortera stigande enligt serieindex" -#: cps/templates/index.html:82 +#: cps/templates/index.html:83 msgid "Sort descending according to series index" msgstr "Sortera fallande enligt serieindex" @@ -2926,10 +2957,6 @@ msgstr "Publiceringsdatum från" msgid "Published Date To" msgstr "Publiceringsdatum till" -#: cps/templates/search_form.html:42 -msgid "Read Status" -msgstr "Lässtatus" - #: cps/templates/search_form.html:59 msgid "Exclude Tags" msgstr "Uteslut taggar" diff --git a/cps/translations/tr/LC_MESSAGES/messages.mo b/cps/translations/tr/LC_MESSAGES/messages.mo index 26014d5f..50d23b6b 100644 Binary files a/cps/translations/tr/LC_MESSAGES/messages.mo and b/cps/translations/tr/LC_MESSAGES/messages.mo differ diff --git a/cps/translations/tr/LC_MESSAGES/messages.po b/cps/translations/tr/LC_MESSAGES/messages.po index 10387783..7234d5bb 100644 --- a/cps/translations/tr/LC_MESSAGES/messages.po +++ b/cps/translations/tr/LC_MESSAGES/messages.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Calibre-Web\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2022-01-15 09:19+0100\n" +"POT-Creation-Date: 2022-04-18 20:01+0200\n" "PO-Revision-Date: 2020-04-23 22:47+0300\n" "Last-Translator: iz \n" "Language: tr\n" @@ -16,583 +16,586 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.9.0\n" +"Generated-By: Babel 2.9.1\n" -#: cps/about.py:34 cps/about.py:49 cps/about.py:65 cps/converter.py:31 -msgid "not installed" -msgstr "yüklü değil" - -#: cps/about.py:47 cps/about.py:63 -msgid "installed" -msgstr "yüklü" - -#: cps/about.py:145 +#: cps/about.py:86 msgid "Statistics" msgstr "İstatistikler" -#: cps/admin.py:144 +#: cps/admin.py:141 msgid "Server restarted, please reload page" msgstr "Sunucu yeniden başlatıldı, lütfen sayfayı yeniden yükleyin" -#: cps/admin.py:146 +#: cps/admin.py:143 msgid "Performing shutdown of server, please close window" msgstr "Sunucu kapatıyor, lütfen pencereyi kapatın" -#: cps/admin.py:154 +#: cps/admin.py:151 msgid "Reconnect successful" msgstr "" -#: cps/admin.py:157 +#: cps/admin.py:154 msgid "Unknown command" msgstr "" -#: cps/admin.py:167 cps/editbooks.py:707 cps/editbooks.py:721 -#: cps/editbooks.py:866 cps/editbooks.py:868 cps/editbooks.py:895 -#: cps/editbooks.py:911 cps/updater.py:584 cps/uploader.py:93 -#: cps/uploader.py:103 +#: cps/admin.py:176 cps/editbooks.py:713 cps/editbooks.py:892 +#: cps/editbooks.py:894 cps/editbooks.py:930 cps/editbooks.py:947 +#: cps/updater.py:608 cps/uploader.py:93 cps/uploader.py:103 msgid "Unknown" msgstr "Bilinmeyen" -#: cps/admin.py:188 +#: cps/admin.py:197 msgid "Admin page" msgstr "Yönetim sayfası" -#: cps/admin.py:207 +#: cps/admin.py:217 msgid "Basic Configuration" msgstr "Temel Ayarlar" -#: cps/admin.py:244 +#: cps/admin.py:255 msgid "UI Configuration" msgstr "Arayüz Ayarları" -#: cps/admin.py:277 cps/templates/admin.html:50 +#: cps/admin.py:289 cps/templates/admin.html:51 msgid "Edit Users" msgstr "" -#: cps/admin.py:318 cps/opds.py:109 cps/opds.py:198 cps/opds.py:275 -#: cps/opds.py:327 cps/templates/grid.html:13 cps/templates/languages.html:9 +#: cps/admin.py:333 cps/opds.py:529 cps/templates/grid.html:13 #: cps/templates/list.html:13 msgid "All" msgstr "Tümü" -#: cps/admin.py:343 cps/admin.py:1615 +#: cps/admin.py:360 cps/admin.py:1648 msgid "User not found" msgstr "" -#: cps/admin.py:357 +#: cps/admin.py:374 msgid "{} users deleted successfully" msgstr "" -#: cps/admin.py:379 cps/templates/config_view_edit.html:133 +#: cps/admin.py:397 cps/templates/config_view_edit.html:133 #: cps/templates/user_edit.html:45 cps/templates/user_table.html:81 msgid "Show All" msgstr "" -#: cps/admin.py:400 cps/admin.py:406 +#: cps/admin.py:418 cps/admin.py:424 msgid "Malformed request" msgstr "" -#: cps/admin.py:418 cps/admin.py:1493 +#: cps/admin.py:436 cps/admin.py:1526 msgid "Guest Name can't be changed" msgstr "" -#: cps/admin.py:430 +#: cps/admin.py:448 msgid "Guest can't have this role" msgstr "" -#: cps/admin.py:442 cps/admin.py:1451 +#: cps/admin.py:460 cps/admin.py:1484 msgid "No admin user remaining, can't remove admin role" msgstr "" -#: cps/admin.py:446 cps/admin.py:460 +#: cps/admin.py:464 cps/admin.py:478 msgid "Value has to be true or false" msgstr "" -#: cps/admin.py:448 +#: cps/admin.py:466 msgid "Invalid role" msgstr "" -#: cps/admin.py:452 +#: cps/admin.py:470 msgid "Guest can't have this view" msgstr "" -#: cps/admin.py:462 +#: cps/admin.py:480 msgid "Invalid view" msgstr "" -#: cps/admin.py:465 +#: cps/admin.py:483 msgid "Guest's Locale is determined automatically and can't be set" msgstr "" -#: cps/admin.py:469 +#: cps/admin.py:487 msgid "No Valid Locale Given" msgstr "" -#: cps/admin.py:480 +#: cps/admin.py:498 msgid "No Valid Book Language Given" msgstr "" -#: cps/admin.py:482 +#: cps/admin.py:500 cps/editbooks.py:1267 msgid "Parameter not found" msgstr "" -#: cps/admin.py:533 +#: cps/admin.py:553 msgid "Invalid Read Column" msgstr "" -#: cps/admin.py:539 +#: cps/admin.py:559 msgid "Invalid Restricted Column" msgstr "" -#: cps/admin.py:560 cps/admin.py:1323 +#: cps/admin.py:579 cps/admin.py:1355 msgid "Calibre-Web configuration updated" msgstr "Calibre-Web yapılandırması güncellendi" -#: cps/admin.py:572 +#: cps/admin.py:591 msgid "Do you really want to delete the Kobo Token?" msgstr "" -#: cps/admin.py:574 +#: cps/admin.py:593 msgid "Do you really want to delete this domain?" msgstr "" -#: cps/admin.py:576 +#: cps/admin.py:595 msgid "Do you really want to delete this user?" msgstr "" -#: cps/admin.py:578 +#: cps/admin.py:597 msgid "Are you sure you want to delete this shelf?" msgstr "" -#: cps/admin.py:580 +#: cps/admin.py:599 msgid "Are you sure you want to change locales of selected user(s)?" msgstr "" -#: cps/admin.py:582 +#: cps/admin.py:601 msgid "Are you sure you want to change visible book languages for selected user(s)?" msgstr "" -#: cps/admin.py:584 +#: cps/admin.py:603 msgid "Are you sure you want to change the selected role for the selected user(s)?" msgstr "" -#: cps/admin.py:586 +#: cps/admin.py:605 msgid "Are you sure you want to change the selected restrictions for the selected user(s)?" msgstr "" -#: cps/admin.py:588 +#: cps/admin.py:607 msgid "Are you sure you want to change the selected visibility restrictions for the selected user(s)?" msgstr "" -#: cps/admin.py:590 +#: cps/admin.py:610 msgid "Are you sure you want to change shelf sync behavior for the selected user(s)?" msgstr "" -#: cps/admin.py:592 +#: cps/admin.py:612 msgid "Are you sure you want to change Calibre library location?" msgstr "" -#: cps/admin.py:594 +#: cps/admin.py:614 msgid "Are you sure you want delete Calibre-Web's sync database to force a full sync with your Kobo Reader?" msgstr "" -#: cps/admin.py:743 +#: cps/admin.py:764 msgid "Tag not found" msgstr "" -#: cps/admin.py:755 +#: cps/admin.py:776 msgid "Invalid Action" msgstr "" -#: cps/admin.py:871 cps/admin.py:877 cps/admin.py:887 cps/admin.py:897 +#: cps/admin.py:893 cps/admin.py:899 cps/admin.py:909 cps/admin.py:919 #: cps/templates/modal_dialogs.html:29 cps/templates/user_table.html:41 #: cps/templates/user_table.html:58 msgid "Deny" msgstr "" -#: cps/admin.py:873 cps/admin.py:879 cps/admin.py:889 cps/admin.py:899 +#: cps/admin.py:895 cps/admin.py:901 cps/admin.py:911 cps/admin.py:921 #: cps/templates/modal_dialogs.html:28 cps/templates/user_table.html:44 #: cps/templates/user_table.html:61 msgid "Allow" msgstr "" -#: cps/admin.py:913 +#: cps/admin.py:936 msgid "{} sync entries deleted" msgstr "" -#: cps/admin.py:1036 +#: cps/admin.py:1059 msgid "client_secrets.json Is Not Configured For Web Application" msgstr "" -#: cps/admin.py:1081 +#: cps/admin.py:1104 msgid "Logfile Location is not Valid, Please Enter Correct Path" msgstr "" -#: cps/admin.py:1087 +#: cps/admin.py:1110 msgid "Access Logfile Location is not Valid, Please Enter Correct Path" msgstr "" -#: cps/admin.py:1117 +#: cps/admin.py:1140 msgid "Please Enter a LDAP Provider, Port, DN and User Object Identifier" msgstr "" -#: cps/admin.py:1123 +#: cps/admin.py:1146 #, fuzzy msgid "Please Enter a LDAP Service Account and Password" msgstr "Şifrenizi sıfırlayabilmek için lütfen geçerli bir kullanıcı adı giriniz" -#: cps/admin.py:1126 +#: cps/admin.py:1149 msgid "Please Enter a LDAP Service Account" msgstr "" -#: cps/admin.py:1131 +#: cps/admin.py:1154 #, python-format msgid "LDAP Group Object Filter Needs to Have One \"%s\" Format Identifier" msgstr "" -#: cps/admin.py:1133 +#: cps/admin.py:1156 msgid "LDAP Group Object Filter Has Unmatched Parenthesis" msgstr "" -#: cps/admin.py:1137 +#: cps/admin.py:1160 #, python-format msgid "LDAP User Object Filter needs to Have One \"%s\" Format Identifier" msgstr "" -#: cps/admin.py:1139 +#: cps/admin.py:1162 msgid "LDAP User Object Filter Has Unmatched Parenthesis" msgstr "" -#: cps/admin.py:1146 +#: cps/admin.py:1169 #, python-format msgid "LDAP Member User Filter needs to Have One \"%s\" Format Identifier" msgstr "" -#: cps/admin.py:1148 +#: cps/admin.py:1171 msgid "LDAP Member User Filter Has Unmatched Parenthesis" msgstr "" -#: cps/admin.py:1155 +#: cps/admin.py:1178 msgid "LDAP CACertificate, Certificate or Key Location is not Valid, Please Enter Correct Path" msgstr "" -#: cps/admin.py:1197 cps/admin.py:1308 cps/admin.py:1405 cps/admin.py:1521 -#: cps/admin.py:1590 cps/shelf.py:100 cps/shelf.py:160 cps/shelf.py:203 -#: cps/shelf.py:279 cps/shelf.py:341 cps/shelf.py:376 cps/shelf.py:451 -msgid "Settings DB is not Writeable" -msgstr "" - -#: cps/admin.py:1208 -msgid "DB Location is not Valid, Please Enter Correct Path" -msgstr "" - -#: cps/admin.py:1223 -msgid "DB is not Writeable" -msgstr "" - -#: cps/admin.py:1235 -msgid "Keyfile Location is not Valid, Please Enter Correct Path" -msgstr "" - -#: cps/admin.py:1239 -msgid "Certfile Location is not Valid, Please Enter Correct Path" -msgstr "" - -#: cps/admin.py:1346 -#, fuzzy -msgid "Database Settings updated" -msgstr "E-posta sunucusu ayarları güncellendi" - -#: cps/admin.py:1354 -#, fuzzy -msgid "Database Configuration" -msgstr "Özellik Yapılandırması" - -#: cps/admin.py:1370 cps/web.py:1479 -msgid "Please fill out all fields!" -msgstr "Lütfen tüm alanları doldurun!" - -#: cps/admin.py:1378 -msgid "E-mail is not from valid domain" -msgstr "E-posta izin verilen bir servisten değil" - -#: cps/admin.py:1384 cps/admin.py:1543 -msgid "Add new user" -msgstr "Yeni kullanıcı ekle" - -#: cps/admin.py:1395 -#, python-format -msgid "User '%(user)s' created" -msgstr "'%(user)s' kullanıcısı oluşturuldu" - -#: cps/admin.py:1401 -#, fuzzy -msgid "Found an existing account for this e-mail address or name." -msgstr "Bu e-posta adresi veya kullanıcı adı için zaten bir hesap var." - -#: cps/admin.py:1430 -#, python-format -msgid "User '%(nick)s' deleted" -msgstr "Kullanıcı '%(nick)s' silindi" - -#: cps/admin.py:1432 cps/admin.py:1433 -msgid "Can't delete Guest User" -msgstr "" - -#: cps/admin.py:1436 -msgid "No admin user remaining, can't delete user" -msgstr "Başka yönetici kullanıcı olmadığından silinemedi" - -#: cps/admin.py:1509 cps/admin.py:1634 -#, python-format -msgid "Edit User %(nick)s" -msgstr "%(nick)s kullanıcısını düzenle" - -#: cps/admin.py:1513 -#, python-format -msgid "User '%(nick)s' updated" -msgstr "'%(nick)s' kullanıcısı güncellendi" - -#: cps/admin.py:1517 cps/admin.py:1649 cps/web.py:1504 cps/web.py:1564 -msgid "An unknown error occurred. Please try again later." -msgstr "Bilinmeyen bir hata oluştu. Lütfen daha sonra tekrar deneyiniz." - -#: cps/admin.py:1552 cps/templates/admin.html:98 -msgid "Edit E-mail Server Settings" -msgstr "" - -#: cps/admin.py:1571 -msgid "Gmail Account Verification Successful" -msgstr "" - -#: cps/admin.py:1597 -#, python-format -msgid "Test e-mail queued for sending to %(email)s, please check Tasks for result" -msgstr "" - -#: cps/admin.py:1600 -#, python-format -msgid "There was an error sending the Test e-mail: %(res)s" -msgstr "Deneme e-postası gönderilirken bir hata oluştu: %(res)s" - -#: cps/admin.py:1602 -msgid "Please configure your e-mail address first..." -msgstr "Lütfen önce e-posta adresinizi ayarlayın..." - -#: cps/admin.py:1604 -msgid "E-mail server settings updated" -msgstr "E-posta sunucusu ayarları güncellendi" - -#: cps/admin.py:1646 -#, python-format -msgid "Password for user %(user)s reset" -msgstr "%(user)s kullanıcısının şifresi sıfırlandı" - -#: cps/admin.py:1652 cps/web.py:1444 -msgid "Please configure the SMTP mail settings first..." -msgstr "Lütfen önce SMTP e-posta ayarlarını ayarlayın..." - -#: cps/admin.py:1663 -msgid "Logfile viewer" -msgstr "Log dosyası görüntüleyici" - -#: cps/admin.py:1729 -msgid "Requesting update package" -msgstr "Güncelleme paketi isteniyor" - -#: cps/admin.py:1730 -msgid "Downloading update package" -msgstr "Güncelleme paketi indiriliyor" - -#: cps/admin.py:1731 -msgid "Unzipping update package" -msgstr "Güncelleme paketi ayıklanıyor" - -#: cps/admin.py:1732 -msgid "Replacing files" -msgstr "Dosyalar değiştiriliyor" - -#: cps/admin.py:1733 -msgid "Database connections are closed" -msgstr "Veritabanı bağlantıları kapalı" - -#: cps/admin.py:1734 -msgid "Stopping server" -msgstr "Sunucu durduruyor" - -#: cps/admin.py:1735 -msgid "Update finished, please press okay and reload page" -msgstr "Güncelleme tamamlandı, sayfayı yenilemek için lütfen Tamam'a tıklayınız" - -#: cps/admin.py:1736 cps/admin.py:1737 cps/admin.py:1738 cps/admin.py:1739 -#: cps/admin.py:1740 cps/admin.py:1741 -msgid "Update failed:" -msgstr "Güncelleme başarısız:" - -#: cps/admin.py:1736 cps/updater.py:385 cps/updater.py:595 cps/updater.py:597 -msgid "HTTP Error" -msgstr "HTTP Hatası" - -#: cps/admin.py:1737 cps/updater.py:387 cps/updater.py:599 -msgid "Connection error" -msgstr "Bağlantı hatası" - -#: cps/admin.py:1738 cps/updater.py:389 cps/updater.py:601 -msgid "Timeout while establishing connection" -msgstr "Bağlantı kurulmaya çalışırken zaman aşımına uğradı" - -#: cps/admin.py:1739 cps/updater.py:391 cps/updater.py:603 -msgid "General error" -msgstr "Genel hata" - -#: cps/admin.py:1740 -#, fuzzy -msgid "Update file could not be saved in temp dir" -msgstr "%(filename)s dosyası geçici dizine kaydedilemedi" - -#: cps/admin.py:1741 -msgid "Files could not be replaced during update" -msgstr "" - -#: cps/admin.py:1765 -msgid "Failed to extract at least One LDAP User" -msgstr "" - -#: cps/admin.py:1810 -msgid "Failed to Create at Least One LDAP User" -msgstr "" - -#: cps/admin.py:1823 -#, python-format -msgid "Error: %(ldaperror)s" -msgstr "" - -#: cps/admin.py:1827 -msgid "Error: No user returned in response of LDAP server" -msgstr "" - -#: cps/admin.py:1860 -msgid "At Least One LDAP User Not Found in Database" -msgstr "" - -#: cps/admin.py:1862 -msgid "{} User Successfully Imported" -msgstr "" - -#: cps/converter.py:30 -msgid "not configured" -msgstr "ayarlanmadı" - -#: cps/converter.py:32 -msgid "Execution permissions missing" -msgstr "" - -#: cps/db.py:651 cps/web.py:667 cps/web.py:1155 -#, python-format -msgid "Custom Column No.%(column)d is not existing in calibre database" -msgstr "" - -#: cps/editbooks.py:300 cps/editbooks.py:302 -msgid "Book Format Successfully Deleted" -msgstr "" - -#: cps/editbooks.py:309 cps/editbooks.py:311 -msgid "Book Successfully Deleted" -msgstr "" - -#: cps/editbooks.py:361 -msgid "You are missing permissions to delete books" -msgstr "" - -#: cps/editbooks.py:376 cps/editbooks.py:763 cps/web.py:523 cps/web.py:1703 -#: cps/web.py:1744 cps/web.py:1811 -msgid "Oops! Selected book title is unavailable. File does not exist or is not accessible" -msgstr "" - -#: cps/editbooks.py:410 -msgid "edit metadata" -msgstr "metaveri düzenle" - -#: cps/editbooks.py:458 -#, python-format -msgid "%(seriesindex)s is not a valid number, skipping" -msgstr "" - -#: cps/editbooks.py:494 cps/editbooks.py:958 -#, fuzzy, python-format -msgid "'%(langname)s' is not a valid language" -msgstr "%(langname)s geçerli bir dil değil" - -#: cps/editbooks.py:634 cps/editbooks.py:985 -#, python-format -msgid "File extension '%(ext)s' is not allowed to be uploaded to this server" -msgstr "'%(ext)s' uzantılı dosyaların bu sunucuya yüklenmesine izin verilmiyor" - -#: cps/editbooks.py:638 cps/editbooks.py:989 -msgid "File to be uploaded must have an extension" -msgstr "Yüklenecek dosyanın mutlaka bir uzantısı olması gerekli" - -#: cps/editbooks.py:650 -#, python-format -msgid "Failed to create path %(path)s (Permission denied)." -msgstr "%(path)s dizini oluşturulamadı. (İzin reddedildi)" - -#: cps/editbooks.py:655 -#, python-format -msgid "Failed to store file %(file)s." -msgstr "%(file)s dosyası kaydedilemedi." - -#: cps/editbooks.py:673 cps/editbooks.py:1076 cps/web.py:1664 +#: cps/admin.py:1223 cps/admin.py:1339 cps/admin.py:1437 cps/admin.py:1554 +#: cps/admin.py:1623 cps/editbooks.py:678 cps/editbooks.py:882 +#: cps/editbooks.py:1130 cps/shelf.py:100 cps/shelf.py:160 cps/shelf.py:203 +#: cps/shelf.py:278 cps/shelf.py:343 cps/shelf.py:380 cps/shelf.py:456 +#: cps/web.py:1742 #, python-format msgid "Database error: %(error)s." msgstr "" -#: cps/editbooks.py:678 +#: cps/admin.py:1235 +msgid "DB Location is not Valid, Please Enter Correct Path" +msgstr "" + +#: cps/admin.py:1253 +msgid "DB is not Writeable" +msgstr "" + +#: cps/admin.py:1266 +msgid "Keyfile Location is not Valid, Please Enter Correct Path" +msgstr "" + +#: cps/admin.py:1270 +msgid "Certfile Location is not Valid, Please Enter Correct Path" +msgstr "" + +#: cps/admin.py:1378 +#, fuzzy +msgid "Database Settings updated" +msgstr "E-posta sunucusu ayarları güncellendi" + +#: cps/admin.py:1386 +#, fuzzy +msgid "Database Configuration" +msgstr "Özellik Yapılandırması" + +#: cps/admin.py:1402 cps/web.py:1557 +msgid "Please fill out all fields!" +msgstr "Lütfen tüm alanları doldurun!" + +#: cps/admin.py:1410 +msgid "E-mail is not from valid domain" +msgstr "E-posta izin verilen bir servisten değil" + +#: cps/admin.py:1416 cps/admin.py:1576 +msgid "Add new user" +msgstr "Yeni kullanıcı ekle" + +#: cps/admin.py:1427 +#, python-format +msgid "User '%(user)s' created" +msgstr "'%(user)s' kullanıcısı oluşturuldu" + +#: cps/admin.py:1433 +#, fuzzy +msgid "Found an existing account for this e-mail address or name." +msgstr "Bu e-posta adresi veya kullanıcı adı için zaten bir hesap var." + +#: cps/admin.py:1463 +#, python-format +msgid "User '%(nick)s' deleted" +msgstr "Kullanıcı '%(nick)s' silindi" + +#: cps/admin.py:1465 cps/admin.py:1466 +msgid "Can't delete Guest User" +msgstr "" + +#: cps/admin.py:1469 +msgid "No admin user remaining, can't delete user" +msgstr "Başka yönetici kullanıcı olmadığından silinemedi" + +#: cps/admin.py:1542 cps/admin.py:1667 +#, python-format +msgid "Edit User %(nick)s" +msgstr "%(nick)s kullanıcısını düzenle" + +#: cps/admin.py:1546 +#, python-format +msgid "User '%(nick)s' updated" +msgstr "'%(nick)s' kullanıcısı güncellendi" + +#: cps/admin.py:1550 cps/admin.py:1682 cps/web.py:1582 cps/web.py:1642 +msgid "An unknown error occurred. Please try again later." +msgstr "Bilinmeyen bir hata oluştu. Lütfen daha sonra tekrar deneyiniz." + +#: cps/admin.py:1585 cps/templates/admin.html:100 +msgid "Edit E-mail Server Settings" +msgstr "" + +#: cps/admin.py:1604 +msgid "Gmail Account Verification Successful" +msgstr "" + +#: cps/admin.py:1630 +#, python-format +msgid "Test e-mail queued for sending to %(email)s, please check Tasks for result" +msgstr "" + +#: cps/admin.py:1633 +#, python-format +msgid "There was an error sending the Test e-mail: %(res)s" +msgstr "Deneme e-postası gönderilirken bir hata oluştu: %(res)s" + +#: cps/admin.py:1635 +msgid "Please configure your e-mail address first..." +msgstr "Lütfen önce e-posta adresinizi ayarlayın..." + +#: cps/admin.py:1637 +msgid "E-mail server settings updated" +msgstr "E-posta sunucusu ayarları güncellendi" + +#: cps/admin.py:1679 +#, python-format +msgid "Password for user %(user)s reset" +msgstr "%(user)s kullanıcısının şifresi sıfırlandı" + +#: cps/admin.py:1685 cps/web.py:1522 +msgid "Please configure the SMTP mail settings first..." +msgstr "Lütfen önce SMTP e-posta ayarlarını ayarlayın..." + +#: cps/admin.py:1696 +msgid "Logfile viewer" +msgstr "Log dosyası görüntüleyici" + +#: cps/admin.py:1762 +msgid "Requesting update package" +msgstr "Güncelleme paketi isteniyor" + +#: cps/admin.py:1763 +msgid "Downloading update package" +msgstr "Güncelleme paketi indiriliyor" + +#: cps/admin.py:1764 +msgid "Unzipping update package" +msgstr "Güncelleme paketi ayıklanıyor" + +#: cps/admin.py:1765 +msgid "Replacing files" +msgstr "Dosyalar değiştiriliyor" + +#: cps/admin.py:1766 +msgid "Database connections are closed" +msgstr "Veritabanı bağlantıları kapalı" + +#: cps/admin.py:1767 +msgid "Stopping server" +msgstr "Sunucu durduruyor" + +#: cps/admin.py:1768 +msgid "Update finished, please press okay and reload page" +msgstr "Güncelleme tamamlandı, sayfayı yenilemek için lütfen Tamam'a tıklayınız" + +#: cps/admin.py:1769 cps/admin.py:1770 cps/admin.py:1771 cps/admin.py:1772 +#: cps/admin.py:1773 cps/admin.py:1774 +msgid "Update failed:" +msgstr "Güncelleme başarısız:" + +#: cps/admin.py:1769 cps/updater.py:384 cps/updater.py:619 cps/updater.py:621 +msgid "HTTP Error" +msgstr "HTTP Hatası" + +#: cps/admin.py:1770 cps/updater.py:386 cps/updater.py:623 +msgid "Connection error" +msgstr "Bağlantı hatası" + +#: cps/admin.py:1771 cps/updater.py:388 cps/updater.py:625 +msgid "Timeout while establishing connection" +msgstr "Bağlantı kurulmaya çalışırken zaman aşımına uğradı" + +#: cps/admin.py:1772 cps/updater.py:390 cps/updater.py:627 +msgid "General error" +msgstr "Genel hata" + +#: cps/admin.py:1773 +#, fuzzy +msgid "Update file could not be saved in temp dir" +msgstr "%(filename)s dosyası geçici dizine kaydedilemedi" + +#: cps/admin.py:1774 +msgid "Files could not be replaced during update" +msgstr "" + +#: cps/admin.py:1798 +msgid "Failed to extract at least One LDAP User" +msgstr "" + +#: cps/admin.py:1843 +msgid "Failed to Create at Least One LDAP User" +msgstr "" + +#: cps/admin.py:1856 +#, python-format +msgid "Error: %(ldaperror)s" +msgstr "" + +#: cps/admin.py:1860 +msgid "Error: No user returned in response of LDAP server" +msgstr "" + +#: cps/admin.py:1893 +msgid "At Least One LDAP User Not Found in Database" +msgstr "" + +#: cps/admin.py:1895 +msgid "{} User Successfully Imported" +msgstr "" + +#: cps/converter.py:30 +msgid "not installed" +msgstr "yüklü değil" + +#: cps/converter.py:31 +msgid "Execution permissions missing" +msgstr "" + +#: cps/db.py:674 cps/web.py:710 cps/web.py:1222 +#, python-format +msgid "Custom Column No.%(column)d is not existing in calibre database" +msgstr "" + +#: cps/db.py:917 cps/templates/config_edit.html:204 +#: cps/templates/config_view_edit.html:62 cps/templates/email_edit.html:41 +#: cps/web.py:551 cps/web.py:585 cps/web.py:646 cps/web.py:671 cps/web.py:1003 +#: cps/web.py:1032 cps/web.py:1066 cps/web.py:1093 cps/web.py:1132 +msgid "None" +msgstr "Hiçbiri" + +#: cps/editbooks.py:295 cps/editbooks.py:297 +msgid "Book Format Successfully Deleted" +msgstr "" + +#: cps/editbooks.py:304 cps/editbooks.py:306 +msgid "Book Successfully Deleted" +msgstr "" + +#: cps/editbooks.py:358 +msgid "You are missing permissions to delete books" +msgstr "" + +#: cps/editbooks.py:373 cps/editbooks.py:765 cps/web.py:518 cps/web.py:1783 +#: cps/web.py:1825 cps/web.py:1870 +msgid "Oops! Selected book title is unavailable. File does not exist or is not accessible" +msgstr "" + +#: cps/editbooks.py:408 +msgid "edit metadata" +msgstr "metaveri düzenle" + +#: cps/editbooks.py:457 +#, python-format +msgid "%(seriesindex)s is not a valid number, skipping" +msgstr "" + +#: cps/editbooks.py:493 cps/editbooks.py:1001 +#, fuzzy, python-format +msgid "'%(langname)s' is not a valid language" +msgstr "%(langname)s geçerli bir dil değil" + +#: cps/editbooks.py:634 +msgid "User has no rights to upload additional file formats" +msgstr "" + +#: cps/editbooks.py:639 cps/editbooks.py:1029 +#, python-format +msgid "File extension '%(ext)s' is not allowed to be uploaded to this server" +msgstr "'%(ext)s' uzantılı dosyaların bu sunucuya yüklenmesine izin verilmiyor" + +#: cps/editbooks.py:643 cps/editbooks.py:1033 +msgid "File to be uploaded must have an extension" +msgstr "Yüklenecek dosyanın mutlaka bir uzantısı olması gerekli" + +#: cps/editbooks.py:655 +#, python-format +msgid "Failed to create path %(path)s (Permission denied)." +msgstr "%(path)s dizini oluşturulamadı. (İzin reddedildi)" + +#: cps/editbooks.py:660 +#, python-format +msgid "Failed to store file %(file)s." +msgstr "%(file)s dosyası kaydedilemedi." + +#: cps/editbooks.py:683 #, python-format msgid "File format %(ext)s added to %(book)s" msgstr "%(book)s kitabına %(ext)s dosya biçimi eklendi" -#: cps/editbooks.py:814 +#: cps/editbooks.py:697 cps/editbooks.py:809 +msgid "User has no rights to upload cover" +msgstr "" + +#: cps/editbooks.py:828 msgid "Identifiers are not Case Sensitive, Overwriting Old Identifier" msgstr "" -#: cps/editbooks.py:848 +#: cps/editbooks.py:869 msgid "Metadata successfully updated" msgstr "Metaveri başarıyla güncellendi" -#: cps/editbooks.py:861 -msgid "Error editing book, please check logfile for details" -msgstr "eKitap düzenlenirken hata oluştu, detaylar için lütfen log dosyasını kontrol edin" +#: cps/editbooks.py:887 +msgid "Error editing book: {}" +msgstr "" -#: cps/editbooks.py:899 +#: cps/editbooks.py:951 msgid "Uploaded book probably exists in the library, consider to change before upload new: " msgstr "Yüklenen eKitap muhtemelen kitaplıkta zaten var. Yenisini yüklemeden değiştirmeyi düşünün: " -#: cps/editbooks.py:997 +#: cps/editbooks.py:1041 #, python-format msgid "File %(filename)s could not saved to temp dir" msgstr "%(filename)s dosyası geçici dizine kaydedilemedi" -#: cps/editbooks.py:1016 +#: cps/editbooks.py:1061 #, python-format msgid "Failed to Move Cover File %(file)s: %(error)s" msgstr "" -#: cps/editbooks.py:1063 +#: cps/editbooks.py:1117 #, python-format msgid "File %(file)s uploaded" msgstr "%(file)s dosyası yüklendi" -#: cps/editbooks.py:1088 +#: cps/editbooks.py:1143 msgid "Source or destination format for conversion missing" msgstr "Dönüştürme için kaynak ya da hedef biçimi eksik" -#: cps/editbooks.py:1096 +#: cps/editbooks.py:1151 #, python-format msgid "Book successfully queued for converting to %(book_format)s" msgstr "eKitap %(book_format)s formatlarına dönüştürülmek üzere başarıyla sıraya alındı" -#: cps/editbooks.py:1100 +#: cps/editbooks.py:1155 #, python-format msgid "There was an error converting this book: %(res)s" msgstr "Bu eKitabı dönüştürürken bir hata oluştu: %(res)s" @@ -605,175 +608,191 @@ msgstr "Google Drive kurulumu tamamlanmadı, Google Drive'ı devre dışı bıra msgid "Callback domain is not verified, please follow steps to verify domain in google developer console" msgstr "Geri yönlendirme alanı (callback domain) doğrulanamadı, lütfen Google geliştirici konsolunda alan adını doğrulamak için gerekli adımları izleyin." -#: cps/helper.py:77 +#: cps/helper.py:81 #, python-format msgid "%(format)s format not found for book id: %(book)d" msgstr "%(book)d nolu kitap için %(format)s biçimi bulunamadı" -#: cps/helper.py:83 cps/tasks/convert.py:73 +#: cps/helper.py:87 cps/tasks/convert.py:75 #, python-format msgid "%(format)s not found on Google Drive: %(fn)s" msgstr "%(fn)s eKitabı için %(format)s biçimi Google Drive'da bulunamadı" -#: cps/helper.py:88 +#: cps/helper.py:92 #, python-format msgid "%(format)s not found: %(fn)s" msgstr "%(format)s bulunamadı: %(fn)s" -#: cps/helper.py:93 cps/helper.py:217 cps/templates/detail.html:41 +#: cps/helper.py:97 cps/helper.py:221 cps/templates/detail.html:41 #: cps/templates/detail.html:45 msgid "Send to Kindle" msgstr "Kindle'a gönder" -#: cps/helper.py:94 cps/helper.py:111 cps/helper.py:219 +#: cps/helper.py:98 cps/helper.py:115 cps/helper.py:223 msgid "This e-mail has been sent via Calibre-Web." msgstr "Bu e-Posta Calibre-Web ile gönderilmiştir." -#: cps/helper.py:109 +#: cps/helper.py:113 msgid "Calibre-Web test e-mail" msgstr "Calibre-Web deneme e-Postası" -#: cps/helper.py:110 +#: cps/helper.py:114 msgid "Test e-mail" msgstr "Deneme e-Postası" -#: cps/helper.py:127 +#: cps/helper.py:131 msgid "Get Started with Calibre-Web" msgstr "Calibre-Web'i Kullanmaya Başlayın" -#: cps/helper.py:132 +#: cps/helper.py:136 #, python-format msgid "Registration e-mail for user: %(name)s" msgstr "Kullanıcı Kayıt e-Postası: %(name)s" -#: cps/helper.py:143 cps/helper.py:149 +#: cps/helper.py:147 cps/helper.py:153 #, python-format msgid "Convert %(orig)s to %(format)s and send to Kindle" msgstr "%(orig)s'dan %(format)s biçimine çevir ve Kindle'a gönder" -#: cps/helper.py:168 cps/helper.py:172 cps/helper.py:176 +#: cps/helper.py:172 cps/helper.py:176 cps/helper.py:180 #, python-format msgid "Send %(format)s to Kindle" msgstr "%(format)s biçimlerini Kindle'a gönder" -#: cps/helper.py:216 cps/tasks/convert.py:90 +#: cps/helper.py:220 cps/tasks/convert.py:92 #, fuzzy, python-format msgid "%(book)s send to Kindle" msgstr "Kindle'a gönder" -#: cps/helper.py:221 +#: cps/helper.py:225 msgid "The requested file could not be read. Maybe wrong permissions?" msgstr "İstenilen dosya okunamadı. Yanlış izinlerden kaynaklanabilir?" -#: cps/helper.py:313 +#: cps/helper.py:353 +msgid "Read status could not set: {}" +msgstr "" + +#: cps/helper.py:376 #, python-format msgid "Deleting bookfolder for book %(id)s failed, path has subfolders: %(path)s" msgstr "" -#: cps/helper.py:319 +#: cps/helper.py:382 #, python-format msgid "Deleting book %(id)s failed: %(message)s" msgstr "" -#: cps/helper.py:330 +#: cps/helper.py:393 #, python-format msgid "Deleting book %(id)s from database only, book path in database not valid: %(path)s" msgstr "" -#: cps/helper.py:385 -#, python-format -msgid "Rename title from: '%(src)s' to '%(dest)s' failed with error: %(error)s" +#: cps/helper.py:458 +#, fuzzy, python-format +msgid "Rename author from: '%(src)s' to '%(dest)s' failed with error: %(error)s" msgstr "Kitap adını değiştirme sırasında hata oluştu ('%(src)s' → '%(dest)s'): %(error)s" -#: cps/helper.py:400 -#, python-format -msgid "Rename file in path '%(src)s' to '%(dest)s' failed with error: %(error)s" -msgstr "Dosya adını değiştirme sırasında hata oluştu ('%(src)s' → '%(dest)s'): %(error)s" - -#: cps/helper.py:425 cps/helper.py:435 cps/helper.py:443 +#: cps/helper.py:529 cps/helper.py:538 #, python-format msgid "File %(file)s not found on Google Drive" msgstr "%(file)s dosyası Google Drive'da bulunamadı" -#: cps/helper.py:464 +#: cps/helper.py:572 +#, python-format +msgid "Rename title from: '%(src)s' to '%(dest)s' failed with error: %(error)s" +msgstr "Kitap adını değiştirme sırasında hata oluştu ('%(src)s' → '%(dest)s'): %(error)s" + +#: cps/helper.py:592 +msgid "Error in rename file in path: {}" +msgstr "" + +#: cps/helper.py:610 #, python-format msgid "Book path %(path)s not found on Google Drive" msgstr "eKitap yolu %(path)s Google Drive'da bulunamadı" -#: cps/helper.py:504 cps/web.py:1659 +#: cps/helper.py:651 cps/web.py:1737 #, fuzzy msgid "Found an existing account for this e-mail address" msgstr "Bu e-posta adresi için bir hesap mevcut." -#: cps/helper.py:512 +#: cps/helper.py:659 msgid "This username is already taken" msgstr "Bu kullanıcı adı zaten alındı" -#: cps/helper.py:522 +#: cps/helper.py:669 msgid "Invalid e-mail address format" msgstr "" -#: cps/helper.py:595 +#: cps/helper.py:754 +msgid "Python modul 'advocate' is not installed but is needed for cover downloads" +msgstr "" + +#: cps/helper.py:767 msgid "Error Downloading Cover" msgstr "" -#: cps/helper.py:598 +#: cps/helper.py:770 msgid "Cover Format Error" msgstr "" -#: cps/helper.py:608 +#: cps/helper.py:773 +msgid "You are not allowed to access localhost or the local network for cover uploads" +msgstr "" + +#: cps/helper.py:783 msgid "Failed to create path for cover" msgstr "" -#: cps/helper.py:624 +#: cps/helper.py:799 msgid "Cover-file is not a valid image file, or could not be stored" msgstr "" -#: cps/helper.py:635 +#: cps/helper.py:810 msgid "Only jpg/jpeg/png/webp/bmp files are supported as coverfile" msgstr "" -#: cps/helper.py:648 +#: cps/helper.py:822 msgid "Invalid cover file content" msgstr "" -#: cps/helper.py:652 +#: cps/helper.py:826 msgid "Only jpg/jpeg files are supported as coverfile" msgstr "" -#: cps/helper.py:704 +#: cps/helper.py:878 msgid "Unrar binary file not found" msgstr "" -#: cps/helper.py:715 +#: cps/helper.py:889 msgid "Error excecuting UnRar" msgstr "" -#: cps/helper.py:763 +#: cps/helper.py:937 msgid "Waiting" msgstr "Bekleniyor" -#: cps/helper.py:765 +#: cps/helper.py:939 msgid "Failed" msgstr "Başarısız" -#: cps/helper.py:767 +#: cps/helper.py:941 msgid "Started" msgstr "Başladı" -#: cps/helper.py:769 +#: cps/helper.py:943 msgid "Finished" msgstr "Bitti" -#: cps/helper.py:771 +#: cps/helper.py:945 msgid "Unknown Status" msgstr "Bilinmeyen Durum" -#: cps/kobo_auth.py:127 -msgid "PLease access calibre-web from non localhost to get valid api_endpoint for kobo device" +#: cps/kobo_auth.py:128 +msgid "Please access Calibre-Web from non localhost to get valid api_endpoint for kobo device" msgstr "" -#: cps/kobo_auth.py:130 cps/kobo_auth.py:158 +#: cps/kobo_auth.py:154 msgid "Kobo Setup" msgstr "" @@ -782,7 +801,7 @@ msgstr "" msgid "Register with %(provider)s" msgstr "%(provider)s ile Kaydol" -#: cps/oauth_bb.py:138 cps/remotelogin.py:133 cps/web.py:1535 +#: cps/oauth_bb.py:138 cps/remotelogin.py:130 cps/web.py:1613 #, python-format msgid "you are now logged in as: '%(nickname)s'" msgstr "giriş yaptınız: '%(nickname)s'" @@ -843,163 +862,163 @@ msgstr "Google Oauth hatası, lütfen tekrar deneyin." msgid "Google Oauth error: {}" msgstr "" -#: cps/opds.py:384 +#: cps/opds.py:298 msgid "{} Stars" msgstr "" -#: cps/remotelogin.py:65 cps/templates/layout.html:84 -#: cps/templates/login.html:4 cps/templates/login.html:21 cps/web.py:1584 +#: cps/remotelogin.py:62 cps/templates/layout.html:84 +#: cps/templates/login.html:4 cps/templates/login.html:21 cps/web.py:1662 msgid "Login" msgstr "Giriş" -#: cps/remotelogin.py:77 cps/remotelogin.py:111 +#: cps/remotelogin.py:74 cps/remotelogin.py:108 msgid "Token not found" msgstr "Token bulunamadı" -#: cps/remotelogin.py:86 cps/remotelogin.py:119 +#: cps/remotelogin.py:83 cps/remotelogin.py:116 msgid "Token has expired" msgstr "Token süresi doldu" -#: cps/remotelogin.py:95 +#: cps/remotelogin.py:92 msgid "Success! Please return to your device" msgstr "Başarılı! Lütfen cihazınıza dönün" -#: cps/render_template.py:39 cps/web.py:416 +#: cps/render_template.py:41 cps/web.py:407 msgid "Books" msgstr "eKitaplar" -#: cps/render_template.py:41 +#: cps/render_template.py:43 msgid "Show recent books" msgstr "Son eKitapları göster" -#: cps/render_template.py:42 cps/templates/index.xml:25 +#: cps/render_template.py:44 cps/templates/index.xml:25 msgid "Hot Books" msgstr "Popüler" -#: cps/render_template.py:44 +#: cps/render_template.py:46 msgid "Show Hot Books" msgstr "" -#: cps/render_template.py:46 cps/render_template.py:51 +#: cps/render_template.py:48 cps/render_template.py:53 msgid "Downloaded Books" msgstr "" -#: cps/render_template.py:48 cps/render_template.py:53 +#: cps/render_template.py:50 cps/render_template.py:55 #: cps/templates/user_table.html:167 msgid "Show Downloaded Books" msgstr "" -#: cps/render_template.py:56 cps/templates/index.xml:32 cps/web.py:430 +#: cps/render_template.py:58 cps/templates/index.xml:32 cps/web.py:422 msgid "Top Rated Books" msgstr "" -#: cps/render_template.py:58 cps/templates/user_table.html:161 +#: cps/render_template.py:60 cps/templates/user_table.html:161 msgid "Show Top Rated Books" msgstr "" -#: cps/render_template.py:59 cps/templates/index.xml:54 -#: cps/templates/index.xml:58 cps/web.py:676 +#: cps/render_template.py:61 cps/templates/index.xml:54 +#: cps/templates/index.xml:58 cps/web.py:729 msgid "Read Books" msgstr "Okunanlar" -#: cps/render_template.py:61 +#: cps/render_template.py:63 msgid "Show read and unread" msgstr "Okunan ve okunmayanları göster" -#: cps/render_template.py:63 cps/templates/index.xml:61 -#: cps/templates/index.xml:65 cps/web.py:679 +#: cps/render_template.py:65 cps/templates/index.xml:61 +#: cps/templates/index.xml:65 cps/web.py:732 msgid "Unread Books" msgstr "Okunmamışlar" -#: cps/render_template.py:65 +#: cps/render_template.py:67 msgid "Show unread" msgstr "Okunmamışları göster" -#: cps/render_template.py:66 +#: cps/render_template.py:68 msgid "Discover" msgstr "Keşfet" -#: cps/render_template.py:68 cps/templates/index.xml:50 +#: cps/render_template.py:70 cps/templates/index.xml:50 #: cps/templates/user_table.html:162 msgid "Show Random Books" msgstr "Rastgele Kitap Göster" -#: cps/render_template.py:69 cps/templates/book_table.html:67 -#: cps/templates/index.xml:83 cps/web.py:1041 +#: cps/render_template.py:71 cps/templates/book_table.html:67 +#: cps/templates/index.xml:83 cps/web.py:1135 msgid "Categories" msgstr "Kategoriler" -#: cps/render_template.py:71 cps/templates/user_table.html:158 +#: cps/render_template.py:73 cps/templates/user_table.html:158 msgid "Show category selection" msgstr "Kategori seçimini göster" -#: cps/render_template.py:72 cps/templates/book_edit.html:90 +#: cps/render_template.py:74 cps/templates/book_edit.html:90 #: cps/templates/book_table.html:68 cps/templates/index.xml:90 -#: cps/templates/search_form.html:69 cps/web.py:948 cps/web.py:959 +#: cps/templates/search_form.html:69 cps/web.py:1034 cps/web.py:1041 msgid "Series" msgstr "Seriler" -#: cps/render_template.py:74 cps/templates/user_table.html:157 +#: cps/render_template.py:76 cps/templates/user_table.html:157 msgid "Show series selection" msgstr "Seri seçimini göster" -#: cps/render_template.py:75 cps/templates/book_table.html:66 +#: cps/render_template.py:77 cps/templates/book_table.html:66 #: cps/templates/index.xml:69 msgid "Authors" msgstr "Yazarlar" -#: cps/render_template.py:77 cps/templates/user_table.html:160 +#: cps/render_template.py:79 cps/templates/user_table.html:160 msgid "Show author selection" msgstr "Yazar seçimini göster" -#: cps/render_template.py:79 cps/templates/book_table.html:72 -#: cps/templates/index.xml:76 cps/web.py:925 +#: cps/render_template.py:81 cps/templates/book_table.html:72 +#: cps/templates/index.xml:76 cps/web.py:1006 msgid "Publishers" msgstr "Yayıncılar" -#: cps/render_template.py:81 cps/templates/user_table.html:163 +#: cps/render_template.py:83 cps/templates/user_table.html:163 msgid "Show publisher selection" msgstr "Yayıncı seçimini göster" -#: cps/render_template.py:82 cps/templates/book_table.html:70 +#: cps/render_template.py:84 cps/templates/book_table.html:70 #: cps/templates/index.xml:97 cps/templates/search_form.html:107 -#: cps/web.py:1018 +#: cps/web.py:1108 msgid "Languages" msgstr "Diller" -#: cps/render_template.py:85 cps/templates/user_table.html:155 +#: cps/render_template.py:87 cps/templates/user_table.html:155 msgid "Show language selection" msgstr "Dil seçimini göster" -#: cps/render_template.py:86 cps/templates/index.xml:104 +#: cps/render_template.py:88 cps/templates/index.xml:104 msgid "Ratings" msgstr "Değerlendirmeler" -#: cps/render_template.py:88 cps/templates/user_table.html:164 +#: cps/render_template.py:90 cps/templates/user_table.html:164 msgid "Show ratings selection" msgstr "Değerlendirme seçimini göster" -#: cps/render_template.py:89 cps/templates/index.xml:112 +#: cps/render_template.py:91 cps/templates/index.xml:112 msgid "File formats" msgstr "Biçimler" -#: cps/render_template.py:91 cps/templates/user_table.html:165 +#: cps/render_template.py:93 cps/templates/user_table.html:165 msgid "Show file formats selection" msgstr "Dosya biçimi seçimini göster" -#: cps/render_template.py:93 cps/web.py:703 +#: cps/render_template.py:95 cps/web.py:755 msgid "Archived Books" msgstr "" -#: cps/render_template.py:95 cps/templates/user_table.html:166 +#: cps/render_template.py:97 cps/templates/user_table.html:166 msgid "Show archived books" msgstr "" -#: cps/render_template.py:97 cps/web.py:780 +#: cps/render_template.py:100 cps/web.py:837 msgid "Books List" msgstr "" -#: cps/render_template.py:99 cps/templates/user_table.html:168 +#: cps/render_template.py:102 cps/templates/user_table.html:168 msgid "Show Books List" msgstr "" @@ -1054,262 +1073,266 @@ msgstr "" msgid "Create a Shelf" msgstr "Kitaplık oluştur" -#: cps/shelf.py:237 +#: cps/shelf.py:236 #, fuzzy msgid "Sorry you are not allowed to edit this shelf" msgstr "Maalesef bu kitaplıktan eKitap silmenize izin verilmiyor: %(sname)s" -#: cps/shelf.py:239 +#: cps/shelf.py:238 msgid "Edit a shelf" msgstr "Kitaplığı düzenle" -#: cps/shelf.py:249 +#: cps/shelf.py:248 msgid "Sorry you are not allowed to create a public shelf" msgstr "" -#: cps/shelf.py:266 +#: cps/shelf.py:265 #, python-format msgid "Shelf %(title)s created" msgstr "%(title)s kitaplığı oluşturuldu." -#: cps/shelf.py:269 +#: cps/shelf.py:268 #, python-format msgid "Shelf %(title)s changed" msgstr "%(title)s kitaplığı değiştirildi" -#: cps/shelf.py:283 +#: cps/shelf.py:282 msgid "There was an error" msgstr "Bir hata oluştu" -#: cps/shelf.py:305 +#: cps/shelf.py:304 #, python-format msgid "A public shelf with the name '%(title)s' already exists." msgstr "" -#: cps/shelf.py:316 +#: cps/shelf.py:315 #, python-format msgid "A private shelf with the name '%(title)s' already exists." msgstr "" #: cps/shelf.py:337 +msgid "Error deleting Shelf" +msgstr "" + +#: cps/shelf.py:339 #, fuzzy msgid "Shelf successfully deleted" msgstr "Metaveri başarıyla güncellendi" -#: cps/shelf.py:386 +#: cps/shelf.py:389 #, python-format msgid "Change order of Shelf: '%(name)s'" msgstr "Kitaplık sıralamasını değiştir: '%(name)s'" -#: cps/shelf.py:456 +#: cps/shelf.py:461 #, python-format msgid "Shelf: '%(name)s'" msgstr "Kitaplık: '%(name)s'" -#: cps/shelf.py:460 +#: cps/shelf.py:465 msgid "Error opening shelf. Shelf does not exist or is not accessible" msgstr "Kitaplık açılırken hata oluştu. Kitaplık mevcut değil ya da erişilebilir değil" -#: cps/updater.py:403 cps/updater.py:414 cps/updater.py:514 cps/updater.py:529 +#: cps/updater.py:426 cps/updater.py:437 cps/updater.py:538 cps/updater.py:553 msgid "Unexpected data while reading update information" msgstr "Güncelleme bilgileri okunurken beklenmeyen veri" -#: cps/updater.py:410 cps/updater.py:521 +#: cps/updater.py:433 cps/updater.py:545 msgid "No update available. You already have the latest version installed" msgstr "Yeni güncelleme mevcut değil. Zaten en son sürüme sahipsiniz." -#: cps/updater.py:428 +#: cps/updater.py:451 msgid "A new update is available. Click on the button below to update to the latest version." msgstr "Yeni bir güncelleme mevcut. Son sürüme güncellemek için aşağıdaki düğmeye tıklayın." -#: cps/updater.py:446 +#: cps/updater.py:469 msgid "Could not fetch update information" msgstr "Güncelleme bilgileri alınamadı" -#: cps/updater.py:456 +#: cps/updater.py:479 msgid "Click on the button below to update to the latest stable version." msgstr "Son kararlı sürüme güncellemek için aşağıdaki düğmeye tıklayın." -#: cps/updater.py:465 cps/updater.py:479 cps/updater.py:490 +#: cps/updater.py:488 cps/updater.py:502 cps/updater.py:513 #, python-format msgid "A new update is available. Click on the button below to update to version: %(version)s" msgstr "Yeni bir güncelleme mevcut. Son sürüme güncellemek için aşağıdaki düğmeye tıklayın: %(version)s" -#: cps/updater.py:507 +#: cps/updater.py:531 msgid "No release information available" msgstr "Sürüm bilgisi mevcut değil" -#: cps/templates/index.html:5 cps/web.py:440 +#: cps/templates/index.html:5 cps/web.py:434 msgid "Discover (Random Books)" msgstr "Keşfet (Rastgele)" -#: cps/web.py:471 +#: cps/web.py:470 msgid "Hot Books (Most Downloaded)" msgstr "" -#: cps/web.py:507 +#: cps/web.py:501 #, python-format msgid "Downloaded books by %(user)s" msgstr "" -#: cps/web.py:539 +#: cps/web.py:534 #, python-format msgid "Author: %(name)s" msgstr "Yazar: %(name)s" -#: cps/web.py:554 +#: cps/web.py:570 #, python-format msgid "Publisher: %(name)s" msgstr "Yayınevi: %(name)s" -#: cps/web.py:569 +#: cps/web.py:598 #, python-format msgid "Series: %(serie)s" msgstr "Seri: %(serie)s" -#: cps/web.py:582 +#: cps/web.py:610 #, python-format msgid "Rating: %(rating)s stars" msgstr "Değerlendirme: %(rating)s yıldız" -#: cps/web.py:597 +#: cps/web.py:626 #, python-format msgid "File format: %(format)s" msgstr "Biçim: %(format)s" -#: cps/web.py:615 +#: cps/web.py:663 #, python-format msgid "Category: %(name)s" msgstr "Kategori: %(name)s" -#: cps/web.py:631 +#: cps/web.py:690 #, python-format msgid "Language: %(name)s" msgstr "Dil: %(name)s" -#: cps/templates/layout.html:56 cps/web.py:737 cps/web.py:1371 +#: cps/templates/layout.html:56 cps/web.py:789 cps/web.py:1444 msgid "Advanced Search" msgstr "Gelişmiş Arama" #: cps/templates/book_edit.html:235 cps/templates/feed.xml:33 #: cps/templates/index.xml:11 cps/templates/layout.html:45 #: cps/templates/layout.html:48 cps/templates/search_form.html:226 -#: cps/web.py:750 cps/web.py:1077 +#: cps/web.py:807 cps/web.py:1164 msgid "Search" msgstr "Ara" -#: cps/templates/admin.html:16 cps/web.py:903 +#: cps/templates/admin.html:16 cps/web.py:979 msgid "Downloads" msgstr "" -#: cps/web.py:980 +#: cps/web.py:1068 msgid "Ratings list" msgstr "Değerlendirme listesi" -#: cps/web.py:1001 +#: cps/web.py:1095 msgid "File formats list" msgstr "Biçim listesi" -#: cps/templates/layout.html:73 cps/templates/tasks.html:7 cps/web.py:1055 +#: cps/templates/layout.html:73 cps/templates/tasks.html:7 cps/web.py:1149 msgid "Tasks" msgstr "Görevler" -#: cps/web.py:1215 +#: cps/web.py:1286 msgid "Published after " msgstr "Yayınlanma (sonra)" -#: cps/web.py:1222 +#: cps/web.py:1293 msgid "Published before " msgstr "Yayınlanma (önce)" -#: cps/web.py:1244 +#: cps/web.py:1315 #, python-format msgid "Rating <= %(rating)s" msgstr "Değerlendirme <= %(rating)s" -#: cps/web.py:1246 +#: cps/web.py:1317 #, python-format msgid "Rating >= %(rating)s" msgstr "Değerlendirme >= %(rating)s" -#: cps/web.py:1248 +#: cps/web.py:1319 #, python-format msgid "Read Status = %(status)s" msgstr "" -#: cps/web.py:1353 +#: cps/web.py:1425 msgid "Error on search for custom columns, please restart Calibre-Web" msgstr "" -#: cps/web.py:1449 +#: cps/web.py:1527 #, python-format msgid "Book successfully queued for sending to %(kindlemail)s" msgstr "%(kindlemail)s'a gönderilmek üzere başarıyla sıraya alındı" -#: cps/web.py:1453 +#: cps/web.py:1531 #, python-format msgid "Oops! There was an error sending this book: %(res)s" msgstr "" -#: cps/web.py:1455 +#: cps/web.py:1533 msgid "Please update your profile with a valid Send to Kindle E-mail Address." msgstr "" -#: cps/web.py:1472 +#: cps/web.py:1550 msgid "E-Mail server is not configured, please contact your administrator!" msgstr "E-Posta sunucusu ayarlanmadı, lütfen yöneticinizle iletişime geçin!" -#: cps/templates/layout.html:85 cps/templates/register.html:17 cps/web.py:1473 -#: cps/web.py:1480 cps/web.py:1486 cps/web.py:1505 cps/web.py:1509 -#: cps/web.py:1515 +#: cps/templates/layout.html:85 cps/templates/register.html:17 cps/web.py:1551 +#: cps/web.py:1558 cps/web.py:1564 cps/web.py:1583 cps/web.py:1587 +#: cps/web.py:1593 msgid "Register" msgstr "Kayıt ol" -#: cps/web.py:1507 +#: cps/web.py:1585 msgid "Your e-mail is not allowed to register" msgstr "E-posta adresinizle kaydolunmasına izin verilmiyor" -#: cps/web.py:1510 +#: cps/web.py:1588 msgid "Confirmation e-mail was send to your e-mail account." msgstr "Onay e-Postası hesabınıza gönderildi." -#: cps/web.py:1524 +#: cps/web.py:1602 msgid "Cannot activate LDAP authentication" msgstr "LDAP Kimlik Doğrulaması etkinleştirilemiyor" -#: cps/web.py:1543 +#: cps/web.py:1621 #, python-format msgid "Fallback Login as: '%(nickname)s', LDAP Server not reachable, or user not known" msgstr "" -#: cps/web.py:1549 +#: cps/web.py:1627 #, python-format msgid "Could not login: %(message)s" msgstr "" -#: cps/web.py:1553 cps/web.py:1578 +#: cps/web.py:1631 cps/web.py:1656 msgid "Wrong Username or Password" msgstr "Yanlış Kullanıcı adı ya da Şifre" -#: cps/web.py:1560 +#: cps/web.py:1638 msgid "New Password was send to your email address" msgstr "Yeni şifre e-Posta adresinize gönderildi" -#: cps/web.py:1566 +#: cps/web.py:1644 msgid "Please enter valid username to reset password" msgstr "Şifrenizi sıfırlayabilmek için lütfen geçerli bir kullanıcı adı giriniz" -#: cps/web.py:1573 +#: cps/web.py:1651 #, python-format msgid "You are now logged in as: '%(nickname)s'" msgstr "Giriş yaptınız: '%(nickname)s'" -#: cps/web.py:1639 cps/web.py:1688 +#: cps/web.py:1717 cps/web.py:1766 #, python-format msgid "%(name)s's profile" msgstr "%(name)s Profili" -#: cps/web.py:1655 +#: cps/web.py:1733 msgid "Profile updated" msgstr "Profil güncellendi" @@ -1317,36 +1340,36 @@ msgstr "Profil güncellendi" msgid "Found no valid gmail.json file with OAuth information" msgstr "" -#: cps/tasks/convert.py:137 +#: cps/tasks/convert.py:154 #, python-format msgid "Calibre ebook-convert %(tool)s not found" msgstr "" -#: cps/tasks/convert.py:163 +#: cps/tasks/convert.py:187 #, python-format msgid "%(format)s format not found on disk" msgstr "" -#: cps/tasks/convert.py:167 +#: cps/tasks/convert.py:191 msgid "Ebook converter failed with unknown error" msgstr "" -#: cps/tasks/convert.py:177 +#: cps/tasks/convert.py:201 #, python-format msgid "Kepubify-converter failed: %(error)s" msgstr "" -#: cps/tasks/convert.py:199 +#: cps/tasks/convert.py:223 #, python-format msgid "Converted file not found or more than one file in folder %(folder)s" msgstr "" -#: cps/tasks/convert.py:222 +#: cps/tasks/convert.py:246 #, python-format msgid "Ebook-converter failed: %(error)s" msgstr "eKitap-Dönüştürücü hatası: %(error)s" -#: cps/tasks/convert.py:245 +#: cps/tasks/convert.py:269 #, python-format msgid "Calibre failed with error: %(error)s" msgstr "" @@ -1401,7 +1424,7 @@ msgid "Edit" msgstr "Düzenleme" #: cps/templates/admin.html:25 cps/templates/book_edit.html:16 -#: cps/templates/book_table.html:97 cps/templates/modal_dialogs.html:63 +#: cps/templates/book_table.html:100 cps/templates/modal_dialogs.html:63 #: cps/templates/modal_dialogs.html:116 cps/templates/user_edit.html:67 #: cps/templates/user_table.html:149 msgid "Delete" @@ -1411,180 +1434,180 @@ msgstr "Sil" msgid "Public Shelf" msgstr "" -#: cps/templates/admin.html:51 +#: cps/templates/admin.html:53 msgid "Add New User" msgstr "" -#: cps/templates/admin.html:53 +#: cps/templates/admin.html:55 msgid "Import LDAP Users" msgstr "" -#: cps/templates/admin.html:60 +#: cps/templates/admin.html:62 msgid "E-mail Server Settings" msgstr "" -#: cps/templates/admin.html:65 cps/templates/email_edit.html:31 +#: cps/templates/admin.html:67 cps/templates/email_edit.html:31 msgid "SMTP Hostname" msgstr "" -#: cps/templates/admin.html:69 cps/templates/email_edit.html:35 +#: cps/templates/admin.html:71 cps/templates/email_edit.html:35 msgid "SMTP Port" msgstr "" -#: cps/templates/admin.html:73 cps/templates/email_edit.html:39 +#: cps/templates/admin.html:75 cps/templates/email_edit.html:39 msgid "Encryption" msgstr "Şifreleme" -#: cps/templates/admin.html:77 cps/templates/email_edit.html:47 +#: cps/templates/admin.html:79 cps/templates/email_edit.html:47 msgid "SMTP Login" msgstr "" -#: cps/templates/admin.html:81 cps/templates/admin.html:92 +#: cps/templates/admin.html:83 cps/templates/admin.html:94 #: cps/templates/email_edit.html:55 msgid "From E-mail" msgstr "" -#: cps/templates/admin.html:88 +#: cps/templates/admin.html:90 msgid "E-Mail Service" msgstr "" -#: cps/templates/admin.html:89 +#: cps/templates/admin.html:91 msgid "Gmail via Oauth2" msgstr "" -#: cps/templates/admin.html:104 +#: cps/templates/admin.html:106 msgid "Configuration" msgstr "Ayarlar" -#: cps/templates/admin.html:107 +#: cps/templates/admin.html:109 msgid "Calibre Database Directory" msgstr "" -#: cps/templates/admin.html:111 cps/templates/config_edit.html:68 +#: cps/templates/admin.html:113 cps/templates/config_edit.html:68 msgid "Log Level" msgstr "Log Seviyesi" -#: cps/templates/admin.html:115 +#: cps/templates/admin.html:117 msgid "Port" msgstr "Port" -#: cps/templates/admin.html:120 +#: cps/templates/admin.html:122 msgid "External Port" msgstr "" -#: cps/templates/admin.html:127 cps/templates/config_view_edit.html:28 +#: cps/templates/admin.html:129 cps/templates/config_view_edit.html:28 msgid "Books per Page" msgstr "" -#: cps/templates/admin.html:131 +#: cps/templates/admin.html:133 msgid "Uploads" msgstr "" -#: cps/templates/admin.html:135 +#: cps/templates/admin.html:137 msgid "Anonymous Browsing" msgstr "" -#: cps/templates/admin.html:139 +#: cps/templates/admin.html:141 msgid "Public Registration" msgstr "" -#: cps/templates/admin.html:143 +#: cps/templates/admin.html:145 msgid "Magic Link Remote Login" msgstr "" -#: cps/templates/admin.html:147 +#: cps/templates/admin.html:149 msgid "Reverse Proxy Login" msgstr "" -#: cps/templates/admin.html:152 cps/templates/config_edit.html:173 +#: cps/templates/admin.html:154 cps/templates/config_edit.html:173 msgid "Reverse Proxy Header Name" msgstr "Ters Proxy Header Adı" -#: cps/templates/admin.html:157 +#: cps/templates/admin.html:159 #, fuzzy msgid "Edit Calibre Database Configuration" msgstr "Calibre-Web yapılandırması güncellendi" -#: cps/templates/admin.html:158 +#: cps/templates/admin.html:160 msgid "Edit Basic Configuration" msgstr "" -#: cps/templates/admin.html:159 +#: cps/templates/admin.html:161 msgid "Edit UI Configuration" msgstr "" -#: cps/templates/admin.html:164 +#: cps/templates/admin.html:166 msgid "Administration" msgstr "Yönetim" -#: cps/templates/admin.html:165 +#: cps/templates/admin.html:167 msgid "Download Debug Package" msgstr "" -#: cps/templates/admin.html:166 +#: cps/templates/admin.html:168 msgid "View Logs" msgstr "" -#: cps/templates/admin.html:169 +#: cps/templates/admin.html:171 msgid "Reconnect Calibre Database" msgstr "" -#: cps/templates/admin.html:170 +#: cps/templates/admin.html:172 msgid "Restart" msgstr "" -#: cps/templates/admin.html:171 +#: cps/templates/admin.html:173 msgid "Shutdown" msgstr "" -#: cps/templates/admin.html:176 +#: cps/templates/admin.html:178 msgid "Update" msgstr "Güncelleme" -#: cps/templates/admin.html:180 +#: cps/templates/admin.html:182 msgid "Version" msgstr "Sürüm" -#: cps/templates/admin.html:181 +#: cps/templates/admin.html:183 msgid "Details" msgstr "Detaylar" -#: cps/templates/admin.html:187 +#: cps/templates/admin.html:189 msgid "Current version" msgstr "Geçerli sürüm" -#: cps/templates/admin.html:194 +#: cps/templates/admin.html:196 msgid "Check for Update" msgstr "" -#: cps/templates/admin.html:195 +#: cps/templates/admin.html:197 msgid "Perform Update" msgstr "Güncelle" -#: cps/templates/admin.html:208 +#: cps/templates/admin.html:210 msgid "Are you sure you want to restart?" msgstr "" -#: cps/templates/admin.html:213 cps/templates/admin.html:227 -#: cps/templates/admin.html:247 cps/templates/config_db.html:70 +#: cps/templates/admin.html:215 cps/templates/admin.html:229 +#: cps/templates/admin.html:249 cps/templates/config_db.html:70 msgid "OK" msgstr "" -#: cps/templates/admin.html:214 cps/templates/admin.html:228 -#: cps/templates/book_edit.html:213 cps/templates/book_table.html:124 +#: cps/templates/admin.html:216 cps/templates/admin.html:230 +#: cps/templates/book_edit.html:213 cps/templates/book_table.html:127 #: cps/templates/config_db.html:54 cps/templates/config_edit.html:359 -#: cps/templates/config_view_edit.html:173 cps/templates/modal_dialogs.html:64 +#: cps/templates/config_view_edit.html:175 cps/templates/modal_dialogs.html:64 #: cps/templates/modal_dialogs.html:99 cps/templates/modal_dialogs.html:117 #: cps/templates/modal_dialogs.html:135 cps/templates/shelf_edit.html:27 #: cps/templates/user_edit.html:144 msgid "Cancel" msgstr "" -#: cps/templates/admin.html:226 +#: cps/templates/admin.html:228 msgid "Are you sure you want to shutdown?" msgstr "" -#: cps/templates/admin.html:238 +#: cps/templates/admin.html:240 msgid "Updating, please do not reload this page" msgstr "" @@ -1596,44 +1619,43 @@ msgstr "ile" msgid "In Library" msgstr "Kitaplıkta" -#: cps/templates/author.html:26 cps/templates/index.html:72 -#: cps/templates/search.html:29 cps/templates/shelf.html:19 +#: cps/templates/author.html:26 cps/templates/index.html:73 +#: cps/templates/search.html:30 cps/templates/shelf.html:19 msgid "Sort according to book date, newest first" msgstr "" -#: cps/templates/author.html:27 cps/templates/index.html:73 -#: cps/templates/search.html:30 cps/templates/shelf.html:20 +#: cps/templates/author.html:27 cps/templates/index.html:74 +#: cps/templates/search.html:31 cps/templates/shelf.html:20 msgid "Sort according to book date, oldest first" msgstr "" -#: cps/templates/author.html:28 cps/templates/index.html:74 -#: cps/templates/search.html:31 cps/templates/shelf.html:21 +#: cps/templates/author.html:28 cps/templates/index.html:75 +#: cps/templates/search.html:32 cps/templates/shelf.html:21 msgid "Sort title in alphabetical order" msgstr "" -#: cps/templates/author.html:29 cps/templates/index.html:75 -#: cps/templates/search.html:32 cps/templates/shelf.html:22 +#: cps/templates/author.html:29 cps/templates/index.html:76 +#: cps/templates/search.html:33 cps/templates/shelf.html:22 msgid "Sort title in reverse alphabetical order" msgstr "" -#: cps/templates/author.html:30 cps/templates/index.html:78 -#: cps/templates/search.html:35 cps/templates/shelf.html:25 +#: cps/templates/author.html:30 cps/templates/index.html:79 +#: cps/templates/search.html:36 cps/templates/shelf.html:25 msgid "Sort according to publishing date, newest first" msgstr "" -#: cps/templates/author.html:31 cps/templates/index.html:79 -#: cps/templates/search.html:36 cps/templates/shelf.html:26 +#: cps/templates/author.html:31 cps/templates/index.html:80 +#: cps/templates/search.html:37 cps/templates/shelf.html:26 msgid "Sort according to publishing date, oldest first" msgstr "" -#: cps/templates/author.html:57 cps/templates/author.html:117 -#: cps/templates/discover.html:30 cps/templates/index.html:29 -#: cps/templates/index.html:111 cps/templates/search.html:65 -#: cps/templates/shelf.html:54 +#: cps/templates/author.html:56 cps/templates/author.html:115 +#: cps/templates/index.html:29 cps/templates/index.html:112 +#: cps/templates/search.html:66 cps/templates/shelf.html:54 msgid "reduce" msgstr "azalt" -#: cps/templates/author.html:101 +#: cps/templates/author.html:99 msgid "More by" msgstr "daha fazla" @@ -1758,7 +1780,7 @@ msgid "Fetch Metadata" msgstr "" #: cps/templates/book_edit.html:212 cps/templates/config_db.html:53 -#: cps/templates/config_edit.html:358 cps/templates/config_view_edit.html:172 +#: cps/templates/config_edit.html:358 cps/templates/config_view_edit.html:174 #: cps/templates/email_edit.html:65 cps/templates/shelf_edit.html:25 #: cps/templates/shelf_order.html:41 cps/templates/user_edit.html:142 msgid "Save" @@ -1887,27 +1909,35 @@ msgstr "Servis adı girin" msgid "Comments" msgstr "" -#: cps/templates/book_table.html:77 cps/templates/book_table.html:79 -#: cps/templates/book_table.html:81 cps/templates/book_table.html:83 -#: cps/templates/book_table.html:87 cps/templates/book_table.html:89 -#: cps/templates/book_table.html:91 cps/templates/book_table.html:93 +#: cps/templates/book_table.html:75 +msgid "Archiv Status" +msgstr "" + +#: cps/templates/book_table.html:77 cps/templates/search_form.html:42 +msgid "Read Status" +msgstr "" + +#: cps/templates/book_table.html:80 cps/templates/book_table.html:82 +#: cps/templates/book_table.html:84 cps/templates/book_table.html:86 +#: cps/templates/book_table.html:90 cps/templates/book_table.html:92 +#: cps/templates/book_table.html:96 #, fuzzy msgid "Enter " msgstr "Kayıt ol" -#: cps/templates/book_table.html:110 cps/templates/modal_dialogs.html:46 +#: cps/templates/book_table.html:113 cps/templates/modal_dialogs.html:46 msgid "Are you really sure?" msgstr "Emin misiniz?" -#: cps/templates/book_table.html:114 +#: cps/templates/book_table.html:117 msgid "Books with Title will be merged from:" msgstr "" -#: cps/templates/book_table.html:118 +#: cps/templates/book_table.html:121 msgid "Into Book with Title:" msgstr "" -#: cps/templates/book_table.html:123 +#: cps/templates/book_table.html:126 msgid "Merge" msgstr "" @@ -2083,11 +2113,6 @@ msgstr "LDAP Sunucu Portu" msgid "LDAP Encryption" msgstr "" -#: cps/templates/config_edit.html:204 cps/templates/config_view_edit.html:62 -#: cps/templates/email_edit.html:41 -msgid "None" -msgstr "Hiçbiri" - #: cps/templates/config_edit.html:205 msgid "TLS" msgstr "" @@ -2305,11 +2330,11 @@ msgstr "" msgid "Show Random Books in Detail View" msgstr "" -#: cps/templates/config_view_edit.html:165 cps/templates/user_edit.html:87 +#: cps/templates/config_view_edit.html:166 cps/templates/user_edit.html:87 msgid "Add Allowed/Denied Tags" msgstr "" -#: cps/templates/config_view_edit.html:166 +#: cps/templates/config_view_edit.html:167 msgid "Add Allowed/Denied custom column values" msgstr "" @@ -2358,13 +2383,13 @@ msgstr "" msgid "Description:" msgstr "Açıklama:" -#: cps/templates/detail.html:256 cps/templates/search.html:14 +#: cps/templates/detail.html:256 cps/templates/search.html:15 msgid "Add to shelf" msgstr "Kitaplığa ekle" #: cps/templates/detail.html:267 cps/templates/detail.html:284 #: cps/templates/feed.xml:79 cps/templates/layout.html:137 -#: cps/templates/search.html:20 +#: cps/templates/search.html:21 msgid "(Public)" msgstr "" @@ -2442,10 +2467,14 @@ msgstr "" msgid "Next" msgstr "Sonraki" -#: cps/templates/generate_kobo_auth_url.html:5 +#: cps/templates/generate_kobo_auth_url.html:6 msgid "Open the .kobo/Kobo eReader.conf file in a text editor and add (or edit):" msgstr "" +#: cps/templates/generate_kobo_auth_url.html:11 +msgid "Kobo Token:" +msgstr "" + #: cps/templates/http_error.html:31 #, fuzzy msgid "Calibre-Web Instance is unconfigured, please contact your administrator" @@ -2463,29 +2492,29 @@ msgstr "" msgid "Logout User" msgstr "" -#: cps/templates/index.html:69 +#: cps/templates/index.html:70 msgid "Sort ascending according to download count" msgstr "" -#: cps/templates/index.html:70 +#: cps/templates/index.html:71 msgid "Sort descending according to download count" msgstr "" -#: cps/templates/index.html:76 cps/templates/search.html:33 +#: cps/templates/index.html:77 cps/templates/search.html:34 #: cps/templates/shelf.html:23 msgid "Sort authors in alphabetical order" msgstr "" -#: cps/templates/index.html:77 cps/templates/search.html:34 +#: cps/templates/index.html:78 cps/templates/search.html:35 #: cps/templates/shelf.html:24 msgid "Sort authors in reverse alphabetical order" msgstr "" -#: cps/templates/index.html:81 +#: cps/templates/index.html:82 msgid "Sort ascending according to series index" msgstr "" -#: cps/templates/index.html:82 +#: cps/templates/index.html:83 msgid "Sort descending according to series index" msgstr "" @@ -2921,10 +2950,6 @@ msgstr "" msgid "Published Date To" msgstr "" -#: cps/templates/search_form.html:42 -msgid "Read Status" -msgstr "" - #: cps/templates/search_form.html:59 msgid "Exclude Tags" msgstr "Etiketleri Hariç Tut" diff --git a/cps/translations/uk/LC_MESSAGES/messages.mo b/cps/translations/uk/LC_MESSAGES/messages.mo index 16a29dec..7dd8dec3 100644 Binary files a/cps/translations/uk/LC_MESSAGES/messages.mo and b/cps/translations/uk/LC_MESSAGES/messages.mo differ diff --git a/cps/translations/uk/LC_MESSAGES/messages.po b/cps/translations/uk/LC_MESSAGES/messages.po index 8cca1d0c..ae89e56d 100644 --- a/cps/translations/uk/LC_MESSAGES/messages.po +++ b/cps/translations/uk/LC_MESSAGES/messages.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: Calibre-web\n" "Report-Msgid-Bugs-To: https://github.com/janeczku/calibre-web\n" -"POT-Creation-Date: 2022-01-15 09:19+0100\n" +"POT-Creation-Date: 2022-04-18 20:01+0200\n" "PO-Revision-Date: 2017-04-30 00:47+0300\n" "Last-Translator: ABIS Team \n" "Language: uk\n" @@ -15,585 +15,588 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.9.0\n" +"Generated-By: Babel 2.9.1\n" -#: cps/about.py:34 cps/about.py:49 cps/about.py:65 cps/converter.py:31 -msgid "not installed" -msgstr "не встановлено" - -#: cps/about.py:47 cps/about.py:63 -msgid "installed" -msgstr "" - -#: cps/about.py:145 +#: cps/about.py:86 msgid "Statistics" msgstr "Статистика" -#: cps/admin.py:144 +#: cps/admin.py:141 msgid "Server restarted, please reload page" msgstr "Сервер перезавантажено, будь-ласка, перезавантажте сторінку" -#: cps/admin.py:146 +#: cps/admin.py:143 msgid "Performing shutdown of server, please close window" msgstr "Виконується зупинка серверу, будь-ласка, закрийте вікно" -#: cps/admin.py:154 +#: cps/admin.py:151 msgid "Reconnect successful" msgstr "" -#: cps/admin.py:157 +#: cps/admin.py:154 msgid "Unknown command" msgstr "" -#: cps/admin.py:167 cps/editbooks.py:707 cps/editbooks.py:721 -#: cps/editbooks.py:866 cps/editbooks.py:868 cps/editbooks.py:895 -#: cps/editbooks.py:911 cps/updater.py:584 cps/uploader.py:93 -#: cps/uploader.py:103 +#: cps/admin.py:176 cps/editbooks.py:713 cps/editbooks.py:892 +#: cps/editbooks.py:894 cps/editbooks.py:930 cps/editbooks.py:947 +#: cps/updater.py:608 cps/uploader.py:93 cps/uploader.py:103 msgid "Unknown" msgstr "Невідомий" -#: cps/admin.py:188 +#: cps/admin.py:197 msgid "Admin page" msgstr "Сторінка адміністратора" -#: cps/admin.py:207 +#: cps/admin.py:217 msgid "Basic Configuration" msgstr "Настройки сервера" -#: cps/admin.py:244 +#: cps/admin.py:255 msgid "UI Configuration" msgstr "Конфігурація інтерфейсу" -#: cps/admin.py:277 cps/templates/admin.html:50 +#: cps/admin.py:289 cps/templates/admin.html:51 #, fuzzy msgid "Edit Users" msgstr "Керування сервером" -#: cps/admin.py:318 cps/opds.py:109 cps/opds.py:198 cps/opds.py:275 -#: cps/opds.py:327 cps/templates/grid.html:13 cps/templates/languages.html:9 +#: cps/admin.py:333 cps/opds.py:529 cps/templates/grid.html:13 #: cps/templates/list.html:13 msgid "All" msgstr "" -#: cps/admin.py:343 cps/admin.py:1615 +#: cps/admin.py:360 cps/admin.py:1648 msgid "User not found" msgstr "" -#: cps/admin.py:357 +#: cps/admin.py:374 msgid "{} users deleted successfully" msgstr "" -#: cps/admin.py:379 cps/templates/config_view_edit.html:133 +#: cps/admin.py:397 cps/templates/config_view_edit.html:133 #: cps/templates/user_edit.html:45 cps/templates/user_table.html:81 msgid "Show All" msgstr "Показати всі" -#: cps/admin.py:400 cps/admin.py:406 +#: cps/admin.py:418 cps/admin.py:424 msgid "Malformed request" msgstr "" -#: cps/admin.py:418 cps/admin.py:1493 +#: cps/admin.py:436 cps/admin.py:1526 msgid "Guest Name can't be changed" msgstr "" -#: cps/admin.py:430 +#: cps/admin.py:448 msgid "Guest can't have this role" msgstr "" -#: cps/admin.py:442 cps/admin.py:1451 +#: cps/admin.py:460 cps/admin.py:1484 msgid "No admin user remaining, can't remove admin role" msgstr "" -#: cps/admin.py:446 cps/admin.py:460 +#: cps/admin.py:464 cps/admin.py:478 msgid "Value has to be true or false" msgstr "" -#: cps/admin.py:448 +#: cps/admin.py:466 msgid "Invalid role" msgstr "" -#: cps/admin.py:452 +#: cps/admin.py:470 msgid "Guest can't have this view" msgstr "" -#: cps/admin.py:462 +#: cps/admin.py:480 msgid "Invalid view" msgstr "" -#: cps/admin.py:465 +#: cps/admin.py:483 msgid "Guest's Locale is determined automatically and can't be set" msgstr "" -#: cps/admin.py:469 +#: cps/admin.py:487 msgid "No Valid Locale Given" msgstr "" -#: cps/admin.py:480 +#: cps/admin.py:498 msgid "No Valid Book Language Given" msgstr "" -#: cps/admin.py:482 +#: cps/admin.py:500 cps/editbooks.py:1267 msgid "Parameter not found" msgstr "" -#: cps/admin.py:533 +#: cps/admin.py:553 msgid "Invalid Read Column" msgstr "" -#: cps/admin.py:539 +#: cps/admin.py:559 msgid "Invalid Restricted Column" msgstr "" -#: cps/admin.py:560 cps/admin.py:1323 +#: cps/admin.py:579 cps/admin.py:1355 msgid "Calibre-Web configuration updated" msgstr "" -#: cps/admin.py:572 +#: cps/admin.py:591 msgid "Do you really want to delete the Kobo Token?" msgstr "" -#: cps/admin.py:574 +#: cps/admin.py:593 msgid "Do you really want to delete this domain?" msgstr "" -#: cps/admin.py:576 +#: cps/admin.py:595 msgid "Do you really want to delete this user?" msgstr "" -#: cps/admin.py:578 +#: cps/admin.py:597 msgid "Are you sure you want to delete this shelf?" msgstr "Ви справді хочете видалити книжкову полицю?" -#: cps/admin.py:580 +#: cps/admin.py:599 #, fuzzy msgid "Are you sure you want to change locales of selected user(s)?" msgstr "Ви справді хочете видалити книжкову полицю?" -#: cps/admin.py:582 +#: cps/admin.py:601 msgid "Are you sure you want to change visible book languages for selected user(s)?" msgstr "" -#: cps/admin.py:584 +#: cps/admin.py:603 msgid "Are you sure you want to change the selected role for the selected user(s)?" msgstr "" -#: cps/admin.py:586 +#: cps/admin.py:605 #, fuzzy msgid "Are you sure you want to change the selected restrictions for the selected user(s)?" msgstr "Ви справді хочете видалити книжкову полицю?" -#: cps/admin.py:588 +#: cps/admin.py:607 msgid "Are you sure you want to change the selected visibility restrictions for the selected user(s)?" msgstr "" -#: cps/admin.py:590 +#: cps/admin.py:610 #, fuzzy msgid "Are you sure you want to change shelf sync behavior for the selected user(s)?" msgstr "Ви справді хочете видалити книжкову полицю?" -#: cps/admin.py:592 +#: cps/admin.py:612 #, fuzzy msgid "Are you sure you want to change Calibre library location?" msgstr "Ви справді хочете видалити книжкову полицю?" -#: cps/admin.py:594 +#: cps/admin.py:614 msgid "Are you sure you want delete Calibre-Web's sync database to force a full sync with your Kobo Reader?" msgstr "" -#: cps/admin.py:743 +#: cps/admin.py:764 msgid "Tag not found" msgstr "" -#: cps/admin.py:755 +#: cps/admin.py:776 msgid "Invalid Action" msgstr "" -#: cps/admin.py:871 cps/admin.py:877 cps/admin.py:887 cps/admin.py:897 +#: cps/admin.py:893 cps/admin.py:899 cps/admin.py:909 cps/admin.py:919 #: cps/templates/modal_dialogs.html:29 cps/templates/user_table.html:41 #: cps/templates/user_table.html:58 msgid "Deny" msgstr "" -#: cps/admin.py:873 cps/admin.py:879 cps/admin.py:889 cps/admin.py:899 +#: cps/admin.py:895 cps/admin.py:901 cps/admin.py:911 cps/admin.py:921 #: cps/templates/modal_dialogs.html:28 cps/templates/user_table.html:44 #: cps/templates/user_table.html:61 msgid "Allow" msgstr "" -#: cps/admin.py:913 +#: cps/admin.py:936 msgid "{} sync entries deleted" msgstr "" -#: cps/admin.py:1036 +#: cps/admin.py:1059 msgid "client_secrets.json Is Not Configured For Web Application" msgstr "" -#: cps/admin.py:1081 +#: cps/admin.py:1104 msgid "Logfile Location is not Valid, Please Enter Correct Path" msgstr "" -#: cps/admin.py:1087 +#: cps/admin.py:1110 msgid "Access Logfile Location is not Valid, Please Enter Correct Path" msgstr "" -#: cps/admin.py:1117 +#: cps/admin.py:1140 msgid "Please Enter a LDAP Provider, Port, DN and User Object Identifier" msgstr "" -#: cps/admin.py:1123 +#: cps/admin.py:1146 msgid "Please Enter a LDAP Service Account and Password" msgstr "" -#: cps/admin.py:1126 +#: cps/admin.py:1149 msgid "Please Enter a LDAP Service Account" msgstr "" -#: cps/admin.py:1131 +#: cps/admin.py:1154 #, python-format msgid "LDAP Group Object Filter Needs to Have One \"%s\" Format Identifier" msgstr "" -#: cps/admin.py:1133 +#: cps/admin.py:1156 msgid "LDAP Group Object Filter Has Unmatched Parenthesis" msgstr "" -#: cps/admin.py:1137 +#: cps/admin.py:1160 #, python-format msgid "LDAP User Object Filter needs to Have One \"%s\" Format Identifier" msgstr "" -#: cps/admin.py:1139 +#: cps/admin.py:1162 msgid "LDAP User Object Filter Has Unmatched Parenthesis" msgstr "" -#: cps/admin.py:1146 +#: cps/admin.py:1169 #, python-format msgid "LDAP Member User Filter needs to Have One \"%s\" Format Identifier" msgstr "" -#: cps/admin.py:1148 +#: cps/admin.py:1171 msgid "LDAP Member User Filter Has Unmatched Parenthesis" msgstr "" -#: cps/admin.py:1155 +#: cps/admin.py:1178 msgid "LDAP CACertificate, Certificate or Key Location is not Valid, Please Enter Correct Path" msgstr "" -#: cps/admin.py:1197 cps/admin.py:1308 cps/admin.py:1405 cps/admin.py:1521 -#: cps/admin.py:1590 cps/shelf.py:100 cps/shelf.py:160 cps/shelf.py:203 -#: cps/shelf.py:279 cps/shelf.py:341 cps/shelf.py:376 cps/shelf.py:451 -msgid "Settings DB is not Writeable" -msgstr "" - -#: cps/admin.py:1208 -msgid "DB Location is not Valid, Please Enter Correct Path" -msgstr "" - -#: cps/admin.py:1223 -msgid "DB is not Writeable" -msgstr "" - -#: cps/admin.py:1235 -msgid "Keyfile Location is not Valid, Please Enter Correct Path" -msgstr "" - -#: cps/admin.py:1239 -msgid "Certfile Location is not Valid, Please Enter Correct Path" -msgstr "" - -#: cps/admin.py:1346 -#, fuzzy -msgid "Database Settings updated" -msgstr "З'єднання з базою даних закрите" - -#: cps/admin.py:1354 -#, fuzzy -msgid "Database Configuration" -msgstr "Особливі налаштування" - -#: cps/admin.py:1370 cps/web.py:1479 -msgid "Please fill out all fields!" -msgstr "Будь-ласка, заповніть всі поля!" - -#: cps/admin.py:1378 -msgid "E-mail is not from valid domain" -msgstr "" - -#: cps/admin.py:1384 cps/admin.py:1543 -msgid "Add new user" -msgstr "Додати користувача" - -#: cps/admin.py:1395 -#, python-format -msgid "User '%(user)s' created" -msgstr "Користувач '%(user)s' додан" - -#: cps/admin.py:1401 -msgid "Found an existing account for this e-mail address or name." -msgstr "" - -#: cps/admin.py:1430 -#, python-format -msgid "User '%(nick)s' deleted" -msgstr "Користувача '%(nick)s' видалено" - -#: cps/admin.py:1432 cps/admin.py:1433 -msgid "Can't delete Guest User" -msgstr "" - -#: cps/admin.py:1436 -msgid "No admin user remaining, can't delete user" -msgstr "" - -#: cps/admin.py:1509 cps/admin.py:1634 -#, python-format -msgid "Edit User %(nick)s" -msgstr "Змінити користувача %(nick)s" - -#: cps/admin.py:1513 -#, python-format -msgid "User '%(nick)s' updated" -msgstr "Користувача '%(nick)s' оновлено" - -#: cps/admin.py:1517 cps/admin.py:1649 cps/web.py:1504 cps/web.py:1564 -msgid "An unknown error occurred. Please try again later." -msgstr "" - -#: cps/admin.py:1552 cps/templates/admin.html:98 -msgid "Edit E-mail Server Settings" -msgstr "Змінити налаштування SMTP" - -#: cps/admin.py:1571 -msgid "Gmail Account Verification Successful" -msgstr "" - -#: cps/admin.py:1597 -#, python-format -msgid "Test e-mail queued for sending to %(email)s, please check Tasks for result" -msgstr "" - -#: cps/admin.py:1600 -#, python-format -msgid "There was an error sending the Test e-mail: %(res)s" -msgstr "" - -#: cps/admin.py:1602 -msgid "Please configure your e-mail address first..." -msgstr "" - -#: cps/admin.py:1604 -msgid "E-mail server settings updated" -msgstr "" - -#: cps/admin.py:1646 -#, python-format -msgid "Password for user %(user)s reset" -msgstr "" - -#: cps/admin.py:1652 cps/web.py:1444 -msgid "Please configure the SMTP mail settings first..." -msgstr "Будь-ласка, спочатку сконфігуруйте параметри SMTP" - -#: cps/admin.py:1663 -msgid "Logfile viewer" -msgstr "" - -#: cps/admin.py:1729 -msgid "Requesting update package" -msgstr "Перевірка оновлень" - -#: cps/admin.py:1730 -msgid "Downloading update package" -msgstr "Завантаження оновлень" - -#: cps/admin.py:1731 -msgid "Unzipping update package" -msgstr "Розпакування оновлення" - -#: cps/admin.py:1732 -msgid "Replacing files" -msgstr "" - -#: cps/admin.py:1733 -msgid "Database connections are closed" -msgstr "З'єднання з базою даних закрите" - -#: cps/admin.py:1734 -msgid "Stopping server" -msgstr "" - -#: cps/admin.py:1735 -msgid "Update finished, please press okay and reload page" -msgstr "Оновлення встановлені, натисніть ok і перезавантажте сторінку" - -#: cps/admin.py:1736 cps/admin.py:1737 cps/admin.py:1738 cps/admin.py:1739 -#: cps/admin.py:1740 cps/admin.py:1741 -msgid "Update failed:" -msgstr "" - -#: cps/admin.py:1736 cps/updater.py:385 cps/updater.py:595 cps/updater.py:597 -msgid "HTTP Error" -msgstr "" - -#: cps/admin.py:1737 cps/updater.py:387 cps/updater.py:599 -msgid "Connection error" -msgstr "" - -#: cps/admin.py:1738 cps/updater.py:389 cps/updater.py:601 -msgid "Timeout while establishing connection" -msgstr "" - -#: cps/admin.py:1739 cps/updater.py:391 cps/updater.py:603 -msgid "General error" -msgstr "" - -#: cps/admin.py:1740 -msgid "Update file could not be saved in temp dir" -msgstr "" - -#: cps/admin.py:1741 -msgid "Files could not be replaced during update" -msgstr "" - -#: cps/admin.py:1765 -msgid "Failed to extract at least One LDAP User" -msgstr "" - -#: cps/admin.py:1810 -msgid "Failed to Create at Least One LDAP User" -msgstr "" - -#: cps/admin.py:1823 -#, python-format -msgid "Error: %(ldaperror)s" -msgstr "" - -#: cps/admin.py:1827 -msgid "Error: No user returned in response of LDAP server" -msgstr "" - -#: cps/admin.py:1860 -msgid "At Least One LDAP User Not Found in Database" -msgstr "" - -#: cps/admin.py:1862 -msgid "{} User Successfully Imported" -msgstr "" - -#: cps/converter.py:30 -msgid "not configured" -msgstr "" - -#: cps/converter.py:32 -msgid "Execution permissions missing" -msgstr "" - -#: cps/db.py:651 cps/web.py:667 cps/web.py:1155 -#, python-format -msgid "Custom Column No.%(column)d is not existing in calibre database" -msgstr "" - -#: cps/editbooks.py:300 cps/editbooks.py:302 -msgid "Book Format Successfully Deleted" -msgstr "" - -#: cps/editbooks.py:309 cps/editbooks.py:311 -msgid "Book Successfully Deleted" -msgstr "" - -#: cps/editbooks.py:361 -msgid "You are missing permissions to delete books" -msgstr "" - -#: cps/editbooks.py:376 cps/editbooks.py:763 cps/web.py:523 cps/web.py:1703 -#: cps/web.py:1744 cps/web.py:1811 -msgid "Oops! Selected book title is unavailable. File does not exist or is not accessible" -msgstr "Неможливо відкрити книгу. Файл не існує або немає доступу." - -#: cps/editbooks.py:410 -msgid "edit metadata" -msgstr "змінити метадані" - -#: cps/editbooks.py:458 -#, python-format -msgid "%(seriesindex)s is not a valid number, skipping" -msgstr "" - -#: cps/editbooks.py:494 cps/editbooks.py:958 -#, python-format -msgid "'%(langname)s' is not a valid language" -msgstr "" - -#: cps/editbooks.py:634 cps/editbooks.py:985 -#, python-format -msgid "File extension '%(ext)s' is not allowed to be uploaded to this server" -msgstr "" - -#: cps/editbooks.py:638 cps/editbooks.py:989 -msgid "File to be uploaded must have an extension" -msgstr "Завантажувальний файл повинен мати розширення" - -#: cps/editbooks.py:650 -#, python-format -msgid "Failed to create path %(path)s (Permission denied)." -msgstr "" - -#: cps/editbooks.py:655 -#, python-format -msgid "Failed to store file %(file)s." -msgstr "" - -#: cps/editbooks.py:673 cps/editbooks.py:1076 cps/web.py:1664 +#: cps/admin.py:1223 cps/admin.py:1339 cps/admin.py:1437 cps/admin.py:1554 +#: cps/admin.py:1623 cps/editbooks.py:678 cps/editbooks.py:882 +#: cps/editbooks.py:1130 cps/shelf.py:100 cps/shelf.py:160 cps/shelf.py:203 +#: cps/shelf.py:278 cps/shelf.py:343 cps/shelf.py:380 cps/shelf.py:456 +#: cps/web.py:1742 #, python-format msgid "Database error: %(error)s." msgstr "" -#: cps/editbooks.py:678 +#: cps/admin.py:1235 +msgid "DB Location is not Valid, Please Enter Correct Path" +msgstr "" + +#: cps/admin.py:1253 +msgid "DB is not Writeable" +msgstr "" + +#: cps/admin.py:1266 +msgid "Keyfile Location is not Valid, Please Enter Correct Path" +msgstr "" + +#: cps/admin.py:1270 +msgid "Certfile Location is not Valid, Please Enter Correct Path" +msgstr "" + +#: cps/admin.py:1378 +#, fuzzy +msgid "Database Settings updated" +msgstr "З'єднання з базою даних закрите" + +#: cps/admin.py:1386 +#, fuzzy +msgid "Database Configuration" +msgstr "Особливі налаштування" + +#: cps/admin.py:1402 cps/web.py:1557 +msgid "Please fill out all fields!" +msgstr "Будь-ласка, заповніть всі поля!" + +#: cps/admin.py:1410 +msgid "E-mail is not from valid domain" +msgstr "" + +#: cps/admin.py:1416 cps/admin.py:1576 +msgid "Add new user" +msgstr "Додати користувача" + +#: cps/admin.py:1427 +#, python-format +msgid "User '%(user)s' created" +msgstr "Користувач '%(user)s' додан" + +#: cps/admin.py:1433 +msgid "Found an existing account for this e-mail address or name." +msgstr "" + +#: cps/admin.py:1463 +#, python-format +msgid "User '%(nick)s' deleted" +msgstr "Користувача '%(nick)s' видалено" + +#: cps/admin.py:1465 cps/admin.py:1466 +msgid "Can't delete Guest User" +msgstr "" + +#: cps/admin.py:1469 +msgid "No admin user remaining, can't delete user" +msgstr "" + +#: cps/admin.py:1542 cps/admin.py:1667 +#, python-format +msgid "Edit User %(nick)s" +msgstr "Змінити користувача %(nick)s" + +#: cps/admin.py:1546 +#, python-format +msgid "User '%(nick)s' updated" +msgstr "Користувача '%(nick)s' оновлено" + +#: cps/admin.py:1550 cps/admin.py:1682 cps/web.py:1582 cps/web.py:1642 +msgid "An unknown error occurred. Please try again later." +msgstr "" + +#: cps/admin.py:1585 cps/templates/admin.html:100 +msgid "Edit E-mail Server Settings" +msgstr "Змінити налаштування SMTP" + +#: cps/admin.py:1604 +msgid "Gmail Account Verification Successful" +msgstr "" + +#: cps/admin.py:1630 +#, python-format +msgid "Test e-mail queued for sending to %(email)s, please check Tasks for result" +msgstr "" + +#: cps/admin.py:1633 +#, python-format +msgid "There was an error sending the Test e-mail: %(res)s" +msgstr "" + +#: cps/admin.py:1635 +msgid "Please configure your e-mail address first..." +msgstr "" + +#: cps/admin.py:1637 +msgid "E-mail server settings updated" +msgstr "" + +#: cps/admin.py:1679 +#, python-format +msgid "Password for user %(user)s reset" +msgstr "" + +#: cps/admin.py:1685 cps/web.py:1522 +msgid "Please configure the SMTP mail settings first..." +msgstr "Будь-ласка, спочатку сконфігуруйте параметри SMTP" + +#: cps/admin.py:1696 +msgid "Logfile viewer" +msgstr "" + +#: cps/admin.py:1762 +msgid "Requesting update package" +msgstr "Перевірка оновлень" + +#: cps/admin.py:1763 +msgid "Downloading update package" +msgstr "Завантаження оновлень" + +#: cps/admin.py:1764 +msgid "Unzipping update package" +msgstr "Розпакування оновлення" + +#: cps/admin.py:1765 +msgid "Replacing files" +msgstr "" + +#: cps/admin.py:1766 +msgid "Database connections are closed" +msgstr "З'єднання з базою даних закрите" + +#: cps/admin.py:1767 +msgid "Stopping server" +msgstr "" + +#: cps/admin.py:1768 +msgid "Update finished, please press okay and reload page" +msgstr "Оновлення встановлені, натисніть ok і перезавантажте сторінку" + +#: cps/admin.py:1769 cps/admin.py:1770 cps/admin.py:1771 cps/admin.py:1772 +#: cps/admin.py:1773 cps/admin.py:1774 +msgid "Update failed:" +msgstr "" + +#: cps/admin.py:1769 cps/updater.py:384 cps/updater.py:619 cps/updater.py:621 +msgid "HTTP Error" +msgstr "" + +#: cps/admin.py:1770 cps/updater.py:386 cps/updater.py:623 +msgid "Connection error" +msgstr "" + +#: cps/admin.py:1771 cps/updater.py:388 cps/updater.py:625 +msgid "Timeout while establishing connection" +msgstr "" + +#: cps/admin.py:1772 cps/updater.py:390 cps/updater.py:627 +msgid "General error" +msgstr "" + +#: cps/admin.py:1773 +msgid "Update file could not be saved in temp dir" +msgstr "" + +#: cps/admin.py:1774 +msgid "Files could not be replaced during update" +msgstr "" + +#: cps/admin.py:1798 +msgid "Failed to extract at least One LDAP User" +msgstr "" + +#: cps/admin.py:1843 +msgid "Failed to Create at Least One LDAP User" +msgstr "" + +#: cps/admin.py:1856 +#, python-format +msgid "Error: %(ldaperror)s" +msgstr "" + +#: cps/admin.py:1860 +msgid "Error: No user returned in response of LDAP server" +msgstr "" + +#: cps/admin.py:1893 +msgid "At Least One LDAP User Not Found in Database" +msgstr "" + +#: cps/admin.py:1895 +msgid "{} User Successfully Imported" +msgstr "" + +#: cps/converter.py:30 +msgid "not installed" +msgstr "не встановлено" + +#: cps/converter.py:31 +msgid "Execution permissions missing" +msgstr "" + +#: cps/db.py:674 cps/web.py:710 cps/web.py:1222 +#, python-format +msgid "Custom Column No.%(column)d is not existing in calibre database" +msgstr "" + +#: cps/db.py:917 cps/templates/config_edit.html:204 +#: cps/templates/config_view_edit.html:62 cps/templates/email_edit.html:41 +#: cps/web.py:551 cps/web.py:585 cps/web.py:646 cps/web.py:671 cps/web.py:1003 +#: cps/web.py:1032 cps/web.py:1066 cps/web.py:1093 cps/web.py:1132 +msgid "None" +msgstr "Ні" + +#: cps/editbooks.py:295 cps/editbooks.py:297 +msgid "Book Format Successfully Deleted" +msgstr "" + +#: cps/editbooks.py:304 cps/editbooks.py:306 +msgid "Book Successfully Deleted" +msgstr "" + +#: cps/editbooks.py:358 +msgid "You are missing permissions to delete books" +msgstr "" + +#: cps/editbooks.py:373 cps/editbooks.py:765 cps/web.py:518 cps/web.py:1783 +#: cps/web.py:1825 cps/web.py:1870 +msgid "Oops! Selected book title is unavailable. File does not exist or is not accessible" +msgstr "Неможливо відкрити книгу. Файл не існує або немає доступу." + +#: cps/editbooks.py:408 +msgid "edit metadata" +msgstr "змінити метадані" + +#: cps/editbooks.py:457 +#, python-format +msgid "%(seriesindex)s is not a valid number, skipping" +msgstr "" + +#: cps/editbooks.py:493 cps/editbooks.py:1001 +#, python-format +msgid "'%(langname)s' is not a valid language" +msgstr "" + +#: cps/editbooks.py:634 +msgid "User has no rights to upload additional file formats" +msgstr "" + +#: cps/editbooks.py:639 cps/editbooks.py:1029 +#, python-format +msgid "File extension '%(ext)s' is not allowed to be uploaded to this server" +msgstr "" + +#: cps/editbooks.py:643 cps/editbooks.py:1033 +msgid "File to be uploaded must have an extension" +msgstr "Завантажувальний файл повинен мати розширення" + +#: cps/editbooks.py:655 +#, python-format +msgid "Failed to create path %(path)s (Permission denied)." +msgstr "" + +#: cps/editbooks.py:660 +#, python-format +msgid "Failed to store file %(file)s." +msgstr "" + +#: cps/editbooks.py:683 #, python-format msgid "File format %(ext)s added to %(book)s" msgstr "" -#: cps/editbooks.py:814 +#: cps/editbooks.py:697 cps/editbooks.py:809 +msgid "User has no rights to upload cover" +msgstr "" + +#: cps/editbooks.py:828 msgid "Identifiers are not Case Sensitive, Overwriting Old Identifier" msgstr "" -#: cps/editbooks.py:848 +#: cps/editbooks.py:869 msgid "Metadata successfully updated" msgstr "" -#: cps/editbooks.py:861 -msgid "Error editing book, please check logfile for details" -msgstr "Сталась помилка при редагуванні книги. Будь-ласка, перевірте лог-файл для деталей" +#: cps/editbooks.py:887 +msgid "Error editing book: {}" +msgstr "" -#: cps/editbooks.py:899 +#: cps/editbooks.py:951 msgid "Uploaded book probably exists in the library, consider to change before upload new: " msgstr "" -#: cps/editbooks.py:997 +#: cps/editbooks.py:1041 #, python-format msgid "File %(filename)s could not saved to temp dir" msgstr "" -#: cps/editbooks.py:1016 +#: cps/editbooks.py:1061 #, python-format msgid "Failed to Move Cover File %(file)s: %(error)s" msgstr "" -#: cps/editbooks.py:1063 +#: cps/editbooks.py:1117 #, python-format msgid "File %(file)s uploaded" msgstr "" -#: cps/editbooks.py:1088 +#: cps/editbooks.py:1143 msgid "Source or destination format for conversion missing" msgstr "" -#: cps/editbooks.py:1096 +#: cps/editbooks.py:1151 #, python-format msgid "Book successfully queued for converting to %(book_format)s" msgstr "" -#: cps/editbooks.py:1100 +#: cps/editbooks.py:1155 #, python-format msgid "There was an error converting this book: %(res)s" msgstr "" @@ -606,174 +609,190 @@ msgstr "" msgid "Callback domain is not verified, please follow steps to verify domain in google developer console" msgstr "Домен зворотнього зв'язку не підтверджено. Виконайте дії для підтвердження домену, будь-ласка" -#: cps/helper.py:77 +#: cps/helper.py:81 #, python-format msgid "%(format)s format not found for book id: %(book)d" msgstr "" -#: cps/helper.py:83 cps/tasks/convert.py:73 +#: cps/helper.py:87 cps/tasks/convert.py:75 #, python-format msgid "%(format)s not found on Google Drive: %(fn)s" msgstr "" -#: cps/helper.py:88 +#: cps/helper.py:92 #, python-format msgid "%(format)s not found: %(fn)s" msgstr "" -#: cps/helper.py:93 cps/helper.py:217 cps/templates/detail.html:41 +#: cps/helper.py:97 cps/helper.py:221 cps/templates/detail.html:41 #: cps/templates/detail.html:45 msgid "Send to Kindle" msgstr "Відправити на Kindle" -#: cps/helper.py:94 cps/helper.py:111 cps/helper.py:219 +#: cps/helper.py:98 cps/helper.py:115 cps/helper.py:223 msgid "This e-mail has been sent via Calibre-Web." msgstr "" -#: cps/helper.py:109 +#: cps/helper.py:113 msgid "Calibre-Web test e-mail" msgstr "" -#: cps/helper.py:110 +#: cps/helper.py:114 msgid "Test e-mail" msgstr "" -#: cps/helper.py:127 +#: cps/helper.py:131 msgid "Get Started with Calibre-Web" msgstr "" -#: cps/helper.py:132 +#: cps/helper.py:136 #, python-format msgid "Registration e-mail for user: %(name)s" msgstr "" -#: cps/helper.py:143 cps/helper.py:149 +#: cps/helper.py:147 cps/helper.py:153 #, python-format msgid "Convert %(orig)s to %(format)s and send to Kindle" msgstr "" -#: cps/helper.py:168 cps/helper.py:172 cps/helper.py:176 +#: cps/helper.py:172 cps/helper.py:176 cps/helper.py:180 #, python-format msgid "Send %(format)s to Kindle" msgstr "" -#: cps/helper.py:216 cps/tasks/convert.py:90 +#: cps/helper.py:220 cps/tasks/convert.py:92 #, fuzzy, python-format msgid "%(book)s send to Kindle" msgstr "Відправити на Kindle" -#: cps/helper.py:221 +#: cps/helper.py:225 msgid "The requested file could not be read. Maybe wrong permissions?" msgstr "" -#: cps/helper.py:313 +#: cps/helper.py:353 +msgid "Read status could not set: {}" +msgstr "" + +#: cps/helper.py:376 #, python-format msgid "Deleting bookfolder for book %(id)s failed, path has subfolders: %(path)s" msgstr "" -#: cps/helper.py:319 +#: cps/helper.py:382 #, python-format msgid "Deleting book %(id)s failed: %(message)s" msgstr "" -#: cps/helper.py:330 +#: cps/helper.py:393 #, python-format msgid "Deleting book %(id)s from database only, book path in database not valid: %(path)s" msgstr "" -#: cps/helper.py:385 +#: cps/helper.py:458 #, python-format -msgid "Rename title from: '%(src)s' to '%(dest)s' failed with error: %(error)s" +msgid "Rename author from: '%(src)s' to '%(dest)s' failed with error: %(error)s" msgstr "" -#: cps/helper.py:400 -#, python-format -msgid "Rename file in path '%(src)s' to '%(dest)s' failed with error: %(error)s" -msgstr "" - -#: cps/helper.py:425 cps/helper.py:435 cps/helper.py:443 +#: cps/helper.py:529 cps/helper.py:538 #, python-format msgid "File %(file)s not found on Google Drive" msgstr "" -#: cps/helper.py:464 +#: cps/helper.py:572 +#, python-format +msgid "Rename title from: '%(src)s' to '%(dest)s' failed with error: %(error)s" +msgstr "" + +#: cps/helper.py:592 +msgid "Error in rename file in path: {}" +msgstr "" + +#: cps/helper.py:610 #, python-format msgid "Book path %(path)s not found on Google Drive" msgstr "" -#: cps/helper.py:504 cps/web.py:1659 +#: cps/helper.py:651 cps/web.py:1737 msgid "Found an existing account for this e-mail address" msgstr "" -#: cps/helper.py:512 +#: cps/helper.py:659 msgid "This username is already taken" msgstr "" -#: cps/helper.py:522 +#: cps/helper.py:669 msgid "Invalid e-mail address format" msgstr "" -#: cps/helper.py:595 -msgid "Error Downloading Cover" -msgstr "" - -#: cps/helper.py:598 -msgid "Cover Format Error" -msgstr "" - -#: cps/helper.py:608 -msgid "Failed to create path for cover" -msgstr "" - -#: cps/helper.py:624 -msgid "Cover-file is not a valid image file, or could not be stored" -msgstr "" - -#: cps/helper.py:635 -msgid "Only jpg/jpeg/png/webp/bmp files are supported as coverfile" -msgstr "" - -#: cps/helper.py:648 -msgid "Invalid cover file content" -msgstr "" - -#: cps/helper.py:652 -msgid "Only jpg/jpeg files are supported as coverfile" -msgstr "" - -#: cps/helper.py:704 -msgid "Unrar binary file not found" -msgstr "" - -#: cps/helper.py:715 -msgid "Error excecuting UnRar" -msgstr "" - -#: cps/helper.py:763 -msgid "Waiting" -msgstr "" - -#: cps/helper.py:765 -msgid "Failed" +#: cps/helper.py:754 +msgid "Python modul 'advocate' is not installed but is needed for cover downloads" msgstr "" #: cps/helper.py:767 +msgid "Error Downloading Cover" +msgstr "" + +#: cps/helper.py:770 +msgid "Cover Format Error" +msgstr "" + +#: cps/helper.py:773 +msgid "You are not allowed to access localhost or the local network for cover uploads" +msgstr "" + +#: cps/helper.py:783 +msgid "Failed to create path for cover" +msgstr "" + +#: cps/helper.py:799 +msgid "Cover-file is not a valid image file, or could not be stored" +msgstr "" + +#: cps/helper.py:810 +msgid "Only jpg/jpeg/png/webp/bmp files are supported as coverfile" +msgstr "" + +#: cps/helper.py:822 +msgid "Invalid cover file content" +msgstr "" + +#: cps/helper.py:826 +msgid "Only jpg/jpeg files are supported as coverfile" +msgstr "" + +#: cps/helper.py:878 +msgid "Unrar binary file not found" +msgstr "" + +#: cps/helper.py:889 +msgid "Error excecuting UnRar" +msgstr "" + +#: cps/helper.py:937 +msgid "Waiting" +msgstr "" + +#: cps/helper.py:939 +msgid "Failed" +msgstr "" + +#: cps/helper.py:941 msgid "Started" msgstr "" -#: cps/helper.py:769 +#: cps/helper.py:943 msgid "Finished" msgstr "" -#: cps/helper.py:771 +#: cps/helper.py:945 msgid "Unknown Status" msgstr "" -#: cps/kobo_auth.py:127 -msgid "PLease access calibre-web from non localhost to get valid api_endpoint for kobo device" +#: cps/kobo_auth.py:128 +msgid "Please access Calibre-Web from non localhost to get valid api_endpoint for kobo device" msgstr "" -#: cps/kobo_auth.py:130 cps/kobo_auth.py:158 +#: cps/kobo_auth.py:154 msgid "Kobo Setup" msgstr "" @@ -782,7 +801,7 @@ msgstr "" msgid "Register with %(provider)s" msgstr "" -#: cps/oauth_bb.py:138 cps/remotelogin.py:133 cps/web.py:1535 +#: cps/oauth_bb.py:138 cps/remotelogin.py:130 cps/web.py:1613 #, python-format msgid "you are now logged in as: '%(nickname)s'" msgstr "Ви увійшли як користувач: '%(nickname)s'" @@ -843,163 +862,163 @@ msgstr "" msgid "Google Oauth error: {}" msgstr "" -#: cps/opds.py:384 +#: cps/opds.py:298 msgid "{} Stars" msgstr "" -#: cps/remotelogin.py:65 cps/templates/layout.html:84 -#: cps/templates/login.html:4 cps/templates/login.html:21 cps/web.py:1584 +#: cps/remotelogin.py:62 cps/templates/layout.html:84 +#: cps/templates/login.html:4 cps/templates/login.html:21 cps/web.py:1662 msgid "Login" msgstr "Ім'я користувача" -#: cps/remotelogin.py:77 cps/remotelogin.py:111 +#: cps/remotelogin.py:74 cps/remotelogin.py:108 msgid "Token not found" msgstr "Токен не знайдено" -#: cps/remotelogin.py:86 cps/remotelogin.py:119 +#: cps/remotelogin.py:83 cps/remotelogin.py:116 msgid "Token has expired" msgstr "Час дії токено вичерпано" -#: cps/remotelogin.py:95 +#: cps/remotelogin.py:92 msgid "Success! Please return to your device" msgstr "Вдалося! Будь-ласка, поверніться до вашого пристрою" -#: cps/render_template.py:39 cps/web.py:416 +#: cps/render_template.py:41 cps/web.py:407 msgid "Books" msgstr "" -#: cps/render_template.py:41 +#: cps/render_template.py:43 msgid "Show recent books" msgstr "Показувати останні книги" -#: cps/render_template.py:42 cps/templates/index.xml:25 +#: cps/render_template.py:44 cps/templates/index.xml:25 msgid "Hot Books" msgstr "Популярні книги" -#: cps/render_template.py:44 +#: cps/render_template.py:46 msgid "Show Hot Books" msgstr "Показувати популярні книги" -#: cps/render_template.py:46 cps/render_template.py:51 +#: cps/render_template.py:48 cps/render_template.py:53 msgid "Downloaded Books" msgstr "" -#: cps/render_template.py:48 cps/render_template.py:53 +#: cps/render_template.py:50 cps/render_template.py:55 #: cps/templates/user_table.html:167 msgid "Show Downloaded Books" msgstr "" -#: cps/render_template.py:56 cps/templates/index.xml:32 cps/web.py:430 +#: cps/render_template.py:58 cps/templates/index.xml:32 cps/web.py:422 msgid "Top Rated Books" msgstr "Книги з найкращим рейтингом" -#: cps/render_template.py:58 cps/templates/user_table.html:161 +#: cps/render_template.py:60 cps/templates/user_table.html:161 msgid "Show Top Rated Books" msgstr "Показувати книги з найвищим рейтингом" -#: cps/render_template.py:59 cps/templates/index.xml:54 -#: cps/templates/index.xml:58 cps/web.py:676 +#: cps/render_template.py:61 cps/templates/index.xml:54 +#: cps/templates/index.xml:58 cps/web.py:729 msgid "Read Books" msgstr "Прочитані книги" -#: cps/render_template.py:61 +#: cps/render_template.py:63 msgid "Show read and unread" msgstr "Показувати прочитані та непрочитані книги" -#: cps/render_template.py:63 cps/templates/index.xml:61 -#: cps/templates/index.xml:65 cps/web.py:679 +#: cps/render_template.py:65 cps/templates/index.xml:61 +#: cps/templates/index.xml:65 cps/web.py:732 msgid "Unread Books" msgstr "Непрочитані книги" -#: cps/render_template.py:65 +#: cps/render_template.py:67 msgid "Show unread" msgstr "" -#: cps/render_template.py:66 +#: cps/render_template.py:68 msgid "Discover" msgstr "Огляд" -#: cps/render_template.py:68 cps/templates/index.xml:50 +#: cps/render_template.py:70 cps/templates/index.xml:50 #: cps/templates/user_table.html:162 msgid "Show Random Books" msgstr "Показувати випадкові книги" -#: cps/render_template.py:69 cps/templates/book_table.html:67 -#: cps/templates/index.xml:83 cps/web.py:1041 +#: cps/render_template.py:71 cps/templates/book_table.html:67 +#: cps/templates/index.xml:83 cps/web.py:1135 msgid "Categories" msgstr "Категорії" -#: cps/render_template.py:71 cps/templates/user_table.html:158 +#: cps/render_template.py:73 cps/templates/user_table.html:158 msgid "Show category selection" msgstr "Показувати вибір категорії" -#: cps/render_template.py:72 cps/templates/book_edit.html:90 +#: cps/render_template.py:74 cps/templates/book_edit.html:90 #: cps/templates/book_table.html:68 cps/templates/index.xml:90 -#: cps/templates/search_form.html:69 cps/web.py:948 cps/web.py:959 +#: cps/templates/search_form.html:69 cps/web.py:1034 cps/web.py:1041 msgid "Series" msgstr "Серії" -#: cps/render_template.py:74 cps/templates/user_table.html:157 +#: cps/render_template.py:76 cps/templates/user_table.html:157 msgid "Show series selection" msgstr "Показувати вибір серії" -#: cps/render_template.py:75 cps/templates/book_table.html:66 +#: cps/render_template.py:77 cps/templates/book_table.html:66 #: cps/templates/index.xml:69 msgid "Authors" msgstr "Автори" -#: cps/render_template.py:77 cps/templates/user_table.html:160 +#: cps/render_template.py:79 cps/templates/user_table.html:160 msgid "Show author selection" msgstr "Показувати вибір автора" -#: cps/render_template.py:79 cps/templates/book_table.html:72 -#: cps/templates/index.xml:76 cps/web.py:925 +#: cps/render_template.py:81 cps/templates/book_table.html:72 +#: cps/templates/index.xml:76 cps/web.py:1006 msgid "Publishers" msgstr "" -#: cps/render_template.py:81 cps/templates/user_table.html:163 +#: cps/render_template.py:83 cps/templates/user_table.html:163 msgid "Show publisher selection" msgstr "" -#: cps/render_template.py:82 cps/templates/book_table.html:70 +#: cps/render_template.py:84 cps/templates/book_table.html:70 #: cps/templates/index.xml:97 cps/templates/search_form.html:107 -#: cps/web.py:1018 +#: cps/web.py:1108 msgid "Languages" msgstr "Мови" -#: cps/render_template.py:85 cps/templates/user_table.html:155 +#: cps/render_template.py:87 cps/templates/user_table.html:155 msgid "Show language selection" msgstr "Показувати вибір мови" -#: cps/render_template.py:86 cps/templates/index.xml:104 +#: cps/render_template.py:88 cps/templates/index.xml:104 msgid "Ratings" msgstr "" -#: cps/render_template.py:88 cps/templates/user_table.html:164 +#: cps/render_template.py:90 cps/templates/user_table.html:164 msgid "Show ratings selection" msgstr "" -#: cps/render_template.py:89 cps/templates/index.xml:112 +#: cps/render_template.py:91 cps/templates/index.xml:112 msgid "File formats" msgstr "" -#: cps/render_template.py:91 cps/templates/user_table.html:165 +#: cps/render_template.py:93 cps/templates/user_table.html:165 msgid "Show file formats selection" msgstr "" -#: cps/render_template.py:93 cps/web.py:703 +#: cps/render_template.py:95 cps/web.py:755 msgid "Archived Books" msgstr "" -#: cps/render_template.py:95 cps/templates/user_table.html:166 +#: cps/render_template.py:97 cps/templates/user_table.html:166 msgid "Show archived books" msgstr "" -#: cps/render_template.py:97 cps/web.py:780 +#: cps/render_template.py:100 cps/web.py:837 msgid "Books List" msgstr "" -#: cps/render_template.py:99 cps/templates/user_table.html:168 +#: cps/render_template.py:102 cps/templates/user_table.html:168 msgid "Show Books List" msgstr "" @@ -1054,261 +1073,265 @@ msgstr "" msgid "Create a Shelf" msgstr "створити книжкову полицю" -#: cps/shelf.py:237 +#: cps/shelf.py:236 #, fuzzy msgid "Sorry you are not allowed to edit this shelf" msgstr "Вибачте, але у вас немає дозволу для видалення книги з цієї полиці" -#: cps/shelf.py:239 +#: cps/shelf.py:238 msgid "Edit a shelf" msgstr "Змінити книжкову полицю" -#: cps/shelf.py:249 +#: cps/shelf.py:248 msgid "Sorry you are not allowed to create a public shelf" msgstr "" -#: cps/shelf.py:266 +#: cps/shelf.py:265 #, python-format msgid "Shelf %(title)s created" msgstr "Створена книжкова полиця %(title)s" -#: cps/shelf.py:269 +#: cps/shelf.py:268 #, python-format msgid "Shelf %(title)s changed" msgstr "Книжкова полиця %(title)s змінена" -#: cps/shelf.py:283 +#: cps/shelf.py:282 msgid "There was an error" msgstr "Сталась помилка" -#: cps/shelf.py:305 +#: cps/shelf.py:304 #, python-format msgid "A public shelf with the name '%(title)s' already exists." msgstr "" -#: cps/shelf.py:316 +#: cps/shelf.py:315 #, python-format msgid "A private shelf with the name '%(title)s' already exists." msgstr "" #: cps/shelf.py:337 +msgid "Error deleting Shelf" +msgstr "" + +#: cps/shelf.py:339 msgid "Shelf successfully deleted" msgstr "" -#: cps/shelf.py:386 +#: cps/shelf.py:389 #, python-format msgid "Change order of Shelf: '%(name)s'" msgstr "Змінити розташування книжкової полиці '%(name)s'" -#: cps/shelf.py:456 +#: cps/shelf.py:461 #, python-format msgid "Shelf: '%(name)s'" msgstr "Книжкова полиця: '%(name)s'" -#: cps/shelf.py:460 +#: cps/shelf.py:465 msgid "Error opening shelf. Shelf does not exist or is not accessible" msgstr "Помилка при відкриванні полиці. Полиця не існує або до неї відсутній доступ" -#: cps/updater.py:403 cps/updater.py:414 cps/updater.py:514 cps/updater.py:529 +#: cps/updater.py:426 cps/updater.py:437 cps/updater.py:538 cps/updater.py:553 msgid "Unexpected data while reading update information" msgstr "" -#: cps/updater.py:410 cps/updater.py:521 +#: cps/updater.py:433 cps/updater.py:545 msgid "No update available. You already have the latest version installed" msgstr "" -#: cps/updater.py:428 +#: cps/updater.py:451 msgid "A new update is available. Click on the button below to update to the latest version." msgstr "" -#: cps/updater.py:446 +#: cps/updater.py:469 msgid "Could not fetch update information" msgstr "" -#: cps/updater.py:456 +#: cps/updater.py:479 msgid "Click on the button below to update to the latest stable version." msgstr "" -#: cps/updater.py:465 cps/updater.py:479 cps/updater.py:490 +#: cps/updater.py:488 cps/updater.py:502 cps/updater.py:513 #, python-format msgid "A new update is available. Click on the button below to update to version: %(version)s" msgstr "" -#: cps/updater.py:507 +#: cps/updater.py:531 msgid "No release information available" msgstr "" -#: cps/templates/index.html:5 cps/web.py:440 +#: cps/templates/index.html:5 cps/web.py:434 msgid "Discover (Random Books)" msgstr "Огляд (випадкові книги)" -#: cps/web.py:471 +#: cps/web.py:470 msgid "Hot Books (Most Downloaded)" msgstr "Популярні книги (найбільш завантажувані)" -#: cps/web.py:507 +#: cps/web.py:501 #, python-format msgid "Downloaded books by %(user)s" msgstr "" -#: cps/web.py:539 +#: cps/web.py:534 #, python-format msgid "Author: %(name)s" msgstr "" -#: cps/web.py:554 +#: cps/web.py:570 #, python-format msgid "Publisher: %(name)s" msgstr "" -#: cps/web.py:569 +#: cps/web.py:598 #, python-format msgid "Series: %(serie)s" msgstr "Серії: %(serie)s" -#: cps/web.py:582 +#: cps/web.py:610 #, python-format msgid "Rating: %(rating)s stars" msgstr "" -#: cps/web.py:597 +#: cps/web.py:626 #, python-format msgid "File format: %(format)s" msgstr "" -#: cps/web.py:615 +#: cps/web.py:663 #, python-format msgid "Category: %(name)s" msgstr "Категорія: %(name)s" -#: cps/web.py:631 +#: cps/web.py:690 #, python-format msgid "Language: %(name)s" msgstr "Мова: %(name)s" -#: cps/templates/layout.html:56 cps/web.py:737 cps/web.py:1371 +#: cps/templates/layout.html:56 cps/web.py:789 cps/web.py:1444 msgid "Advanced Search" msgstr "Розширений пошук" #: cps/templates/book_edit.html:235 cps/templates/feed.xml:33 #: cps/templates/index.xml:11 cps/templates/layout.html:45 #: cps/templates/layout.html:48 cps/templates/search_form.html:226 -#: cps/web.py:750 cps/web.py:1077 +#: cps/web.py:807 cps/web.py:1164 msgid "Search" msgstr "Пошук" -#: cps/templates/admin.html:16 cps/web.py:903 +#: cps/templates/admin.html:16 cps/web.py:979 msgid "Downloads" msgstr "DLS" -#: cps/web.py:980 +#: cps/web.py:1068 msgid "Ratings list" msgstr "" -#: cps/web.py:1001 +#: cps/web.py:1095 msgid "File formats list" msgstr "" -#: cps/templates/layout.html:73 cps/templates/tasks.html:7 cps/web.py:1055 +#: cps/templates/layout.html:73 cps/templates/tasks.html:7 cps/web.py:1149 msgid "Tasks" msgstr "" -#: cps/web.py:1215 +#: cps/web.py:1286 msgid "Published after " msgstr "" -#: cps/web.py:1222 +#: cps/web.py:1293 msgid "Published before " msgstr "Опубліковано до" -#: cps/web.py:1244 +#: cps/web.py:1315 #, python-format msgid "Rating <= %(rating)s" msgstr "" -#: cps/web.py:1246 +#: cps/web.py:1317 #, python-format msgid "Rating >= %(rating)s" msgstr "" -#: cps/web.py:1248 +#: cps/web.py:1319 #, python-format msgid "Read Status = %(status)s" msgstr "" -#: cps/web.py:1353 +#: cps/web.py:1425 msgid "Error on search for custom columns, please restart Calibre-Web" msgstr "" -#: cps/web.py:1449 +#: cps/web.py:1527 #, python-format msgid "Book successfully queued for sending to %(kindlemail)s" msgstr "" -#: cps/web.py:1453 +#: cps/web.py:1531 #, python-format msgid "Oops! There was an error sending this book: %(res)s" msgstr "Помилка при відправці книги: %(res)s" -#: cps/web.py:1455 +#: cps/web.py:1533 msgid "Please update your profile with a valid Send to Kindle E-mail Address." msgstr "" -#: cps/web.py:1472 +#: cps/web.py:1550 msgid "E-Mail server is not configured, please contact your administrator!" msgstr "" -#: cps/templates/layout.html:85 cps/templates/register.html:17 cps/web.py:1473 -#: cps/web.py:1480 cps/web.py:1486 cps/web.py:1505 cps/web.py:1509 -#: cps/web.py:1515 +#: cps/templates/layout.html:85 cps/templates/register.html:17 cps/web.py:1551 +#: cps/web.py:1558 cps/web.py:1564 cps/web.py:1583 cps/web.py:1587 +#: cps/web.py:1593 msgid "Register" msgstr "Зареєструватись" -#: cps/web.py:1507 +#: cps/web.py:1585 msgid "Your e-mail is not allowed to register" msgstr "" -#: cps/web.py:1510 +#: cps/web.py:1588 msgid "Confirmation e-mail was send to your e-mail account." msgstr "" -#: cps/web.py:1524 +#: cps/web.py:1602 msgid "Cannot activate LDAP authentication" msgstr "" -#: cps/web.py:1543 +#: cps/web.py:1621 #, python-format msgid "Fallback Login as: '%(nickname)s', LDAP Server not reachable, or user not known" msgstr "" -#: cps/web.py:1549 +#: cps/web.py:1627 #, python-format msgid "Could not login: %(message)s" msgstr "" -#: cps/web.py:1553 cps/web.py:1578 +#: cps/web.py:1631 cps/web.py:1656 msgid "Wrong Username or Password" msgstr "Помилка в імені користувача або паролі" -#: cps/web.py:1560 +#: cps/web.py:1638 msgid "New Password was send to your email address" msgstr "" -#: cps/web.py:1566 +#: cps/web.py:1644 msgid "Please enter valid username to reset password" msgstr "" -#: cps/web.py:1573 +#: cps/web.py:1651 #, python-format msgid "You are now logged in as: '%(nickname)s'" msgstr "" -#: cps/web.py:1639 cps/web.py:1688 +#: cps/web.py:1717 cps/web.py:1766 #, python-format msgid "%(name)s's profile" msgstr "Профіль %(name)s" -#: cps/web.py:1655 +#: cps/web.py:1733 msgid "Profile updated" msgstr "Профіль оновлено" @@ -1316,36 +1339,36 @@ msgstr "Профіль оновлено" msgid "Found no valid gmail.json file with OAuth information" msgstr "" -#: cps/tasks/convert.py:137 +#: cps/tasks/convert.py:154 #, python-format msgid "Calibre ebook-convert %(tool)s not found" msgstr "" -#: cps/tasks/convert.py:163 +#: cps/tasks/convert.py:187 #, python-format msgid "%(format)s format not found on disk" msgstr "" -#: cps/tasks/convert.py:167 +#: cps/tasks/convert.py:191 msgid "Ebook converter failed with unknown error" msgstr "" -#: cps/tasks/convert.py:177 +#: cps/tasks/convert.py:201 #, python-format msgid "Kepubify-converter failed: %(error)s" msgstr "" -#: cps/tasks/convert.py:199 +#: cps/tasks/convert.py:223 #, python-format msgid "Converted file not found or more than one file in folder %(folder)s" msgstr "" -#: cps/tasks/convert.py:222 +#: cps/tasks/convert.py:246 #, python-format msgid "Ebook-converter failed: %(error)s" msgstr "" -#: cps/tasks/convert.py:245 +#: cps/tasks/convert.py:269 #, python-format msgid "Calibre failed with error: %(error)s" msgstr "" @@ -1400,7 +1423,7 @@ msgid "Edit" msgstr "Редагувати" #: cps/templates/admin.html:25 cps/templates/book_edit.html:16 -#: cps/templates/book_table.html:97 cps/templates/modal_dialogs.html:63 +#: cps/templates/book_table.html:100 cps/templates/modal_dialogs.html:63 #: cps/templates/modal_dialogs.html:116 cps/templates/user_edit.html:67 #: cps/templates/user_table.html:149 msgid "Delete" @@ -1410,180 +1433,180 @@ msgstr "Видалити" msgid "Public Shelf" msgstr "" -#: cps/templates/admin.html:51 +#: cps/templates/admin.html:53 msgid "Add New User" msgstr "" -#: cps/templates/admin.html:53 +#: cps/templates/admin.html:55 msgid "Import LDAP Users" msgstr "" -#: cps/templates/admin.html:60 +#: cps/templates/admin.html:62 msgid "E-mail Server Settings" msgstr "" -#: cps/templates/admin.html:65 cps/templates/email_edit.html:31 +#: cps/templates/admin.html:67 cps/templates/email_edit.html:31 msgid "SMTP Hostname" msgstr "SMTP-сервер" -#: cps/templates/admin.html:69 cps/templates/email_edit.html:35 +#: cps/templates/admin.html:71 cps/templates/email_edit.html:35 msgid "SMTP Port" msgstr "SMTP-порт" -#: cps/templates/admin.html:73 cps/templates/email_edit.html:39 +#: cps/templates/admin.html:75 cps/templates/email_edit.html:39 msgid "Encryption" msgstr "SSL" -#: cps/templates/admin.html:77 cps/templates/email_edit.html:47 +#: cps/templates/admin.html:79 cps/templates/email_edit.html:47 msgid "SMTP Login" msgstr "SMTP логін" -#: cps/templates/admin.html:81 cps/templates/admin.html:92 +#: cps/templates/admin.html:83 cps/templates/admin.html:94 #: cps/templates/email_edit.html:55 msgid "From E-mail" msgstr "Відправник" -#: cps/templates/admin.html:88 +#: cps/templates/admin.html:90 msgid "E-Mail Service" msgstr "" -#: cps/templates/admin.html:89 +#: cps/templates/admin.html:91 msgid "Gmail via Oauth2" msgstr "" -#: cps/templates/admin.html:104 +#: cps/templates/admin.html:106 msgid "Configuration" msgstr "Налаштування сервера" -#: cps/templates/admin.html:107 +#: cps/templates/admin.html:109 msgid "Calibre Database Directory" msgstr "Папка Calibre DB" -#: cps/templates/admin.html:111 cps/templates/config_edit.html:68 +#: cps/templates/admin.html:113 cps/templates/config_edit.html:68 msgid "Log Level" msgstr "" -#: cps/templates/admin.html:115 +#: cps/templates/admin.html:117 msgid "Port" msgstr "Порт" -#: cps/templates/admin.html:120 +#: cps/templates/admin.html:122 msgid "External Port" msgstr "" -#: cps/templates/admin.html:127 cps/templates/config_view_edit.html:28 +#: cps/templates/admin.html:129 cps/templates/config_view_edit.html:28 msgid "Books per Page" msgstr "Кількість книг на сторінці" -#: cps/templates/admin.html:131 +#: cps/templates/admin.html:133 msgid "Uploads" msgstr "Загрузка на сервер" -#: cps/templates/admin.html:135 +#: cps/templates/admin.html:137 msgid "Anonymous Browsing" msgstr "Анонімний перегляд" -#: cps/templates/admin.html:139 +#: cps/templates/admin.html:141 msgid "Public Registration" msgstr "Публічна реєстрація" -#: cps/templates/admin.html:143 +#: cps/templates/admin.html:145 msgid "Magic Link Remote Login" msgstr "" -#: cps/templates/admin.html:147 +#: cps/templates/admin.html:149 msgid "Reverse Proxy Login" msgstr "" -#: cps/templates/admin.html:152 cps/templates/config_edit.html:173 +#: cps/templates/admin.html:154 cps/templates/config_edit.html:173 msgid "Reverse Proxy Header Name" msgstr "" -#: cps/templates/admin.html:157 +#: cps/templates/admin.html:159 #, fuzzy msgid "Edit Calibre Database Configuration" msgstr "Папка Calibre DB" -#: cps/templates/admin.html:158 +#: cps/templates/admin.html:160 msgid "Edit Basic Configuration" msgstr "" -#: cps/templates/admin.html:159 +#: cps/templates/admin.html:161 msgid "Edit UI Configuration" msgstr "" -#: cps/templates/admin.html:164 +#: cps/templates/admin.html:166 msgid "Administration" msgstr "Адміністрування" -#: cps/templates/admin.html:165 +#: cps/templates/admin.html:167 msgid "Download Debug Package" msgstr "" -#: cps/templates/admin.html:166 +#: cps/templates/admin.html:168 msgid "View Logs" msgstr "" -#: cps/templates/admin.html:169 +#: cps/templates/admin.html:171 msgid "Reconnect Calibre Database" msgstr "Повторне підключення до БД Calibre" -#: cps/templates/admin.html:170 +#: cps/templates/admin.html:172 msgid "Restart" msgstr "" -#: cps/templates/admin.html:171 +#: cps/templates/admin.html:173 msgid "Shutdown" msgstr "" -#: cps/templates/admin.html:176 +#: cps/templates/admin.html:178 msgid "Update" msgstr "" -#: cps/templates/admin.html:180 +#: cps/templates/admin.html:182 msgid "Version" msgstr "" -#: cps/templates/admin.html:181 +#: cps/templates/admin.html:183 msgid "Details" msgstr "" -#: cps/templates/admin.html:187 +#: cps/templates/admin.html:189 msgid "Current version" msgstr "" -#: cps/templates/admin.html:194 +#: cps/templates/admin.html:196 msgid "Check for Update" msgstr "Перевірка оновлень" -#: cps/templates/admin.html:195 +#: cps/templates/admin.html:197 msgid "Perform Update" msgstr "Встановити оновлення" -#: cps/templates/admin.html:208 +#: cps/templates/admin.html:210 msgid "Are you sure you want to restart?" msgstr "" -#: cps/templates/admin.html:213 cps/templates/admin.html:227 -#: cps/templates/admin.html:247 cps/templates/config_db.html:70 +#: cps/templates/admin.html:215 cps/templates/admin.html:229 +#: cps/templates/admin.html:249 cps/templates/config_db.html:70 msgid "OK" msgstr "Ok" -#: cps/templates/admin.html:214 cps/templates/admin.html:228 -#: cps/templates/book_edit.html:213 cps/templates/book_table.html:124 +#: cps/templates/admin.html:216 cps/templates/admin.html:230 +#: cps/templates/book_edit.html:213 cps/templates/book_table.html:127 #: cps/templates/config_db.html:54 cps/templates/config_edit.html:359 -#: cps/templates/config_view_edit.html:173 cps/templates/modal_dialogs.html:64 +#: cps/templates/config_view_edit.html:175 cps/templates/modal_dialogs.html:64 #: cps/templates/modal_dialogs.html:99 cps/templates/modal_dialogs.html:117 #: cps/templates/modal_dialogs.html:135 cps/templates/shelf_edit.html:27 #: cps/templates/user_edit.html:144 msgid "Cancel" msgstr "" -#: cps/templates/admin.html:226 +#: cps/templates/admin.html:228 msgid "Are you sure you want to shutdown?" msgstr "" -#: cps/templates/admin.html:238 +#: cps/templates/admin.html:240 msgid "Updating, please do not reload this page" msgstr "Встановлення оновлень, будь-ласка, не оновлюйте сторінку" @@ -1595,44 +1618,43 @@ msgstr "через" msgid "In Library" msgstr "У бібліотеці" -#: cps/templates/author.html:26 cps/templates/index.html:72 -#: cps/templates/search.html:29 cps/templates/shelf.html:19 +#: cps/templates/author.html:26 cps/templates/index.html:73 +#: cps/templates/search.html:30 cps/templates/shelf.html:19 msgid "Sort according to book date, newest first" msgstr "" -#: cps/templates/author.html:27 cps/templates/index.html:73 -#: cps/templates/search.html:30 cps/templates/shelf.html:20 +#: cps/templates/author.html:27 cps/templates/index.html:74 +#: cps/templates/search.html:31 cps/templates/shelf.html:20 msgid "Sort according to book date, oldest first" msgstr "" -#: cps/templates/author.html:28 cps/templates/index.html:74 -#: cps/templates/search.html:31 cps/templates/shelf.html:21 +#: cps/templates/author.html:28 cps/templates/index.html:75 +#: cps/templates/search.html:32 cps/templates/shelf.html:21 msgid "Sort title in alphabetical order" msgstr "" -#: cps/templates/author.html:29 cps/templates/index.html:75 -#: cps/templates/search.html:32 cps/templates/shelf.html:22 +#: cps/templates/author.html:29 cps/templates/index.html:76 +#: cps/templates/search.html:33 cps/templates/shelf.html:22 msgid "Sort title in reverse alphabetical order" msgstr "" -#: cps/templates/author.html:30 cps/templates/index.html:78 -#: cps/templates/search.html:35 cps/templates/shelf.html:25 +#: cps/templates/author.html:30 cps/templates/index.html:79 +#: cps/templates/search.html:36 cps/templates/shelf.html:25 msgid "Sort according to publishing date, newest first" msgstr "" -#: cps/templates/author.html:31 cps/templates/index.html:79 -#: cps/templates/search.html:36 cps/templates/shelf.html:26 +#: cps/templates/author.html:31 cps/templates/index.html:80 +#: cps/templates/search.html:37 cps/templates/shelf.html:26 msgid "Sort according to publishing date, oldest first" msgstr "" -#: cps/templates/author.html:57 cps/templates/author.html:117 -#: cps/templates/discover.html:30 cps/templates/index.html:29 -#: cps/templates/index.html:111 cps/templates/search.html:65 -#: cps/templates/shelf.html:54 +#: cps/templates/author.html:56 cps/templates/author.html:115 +#: cps/templates/index.html:29 cps/templates/index.html:112 +#: cps/templates/search.html:66 cps/templates/shelf.html:54 msgid "reduce" msgstr "" -#: cps/templates/author.html:101 +#: cps/templates/author.html:99 msgid "More by" msgstr "Більше за" @@ -1757,7 +1779,7 @@ msgid "Fetch Metadata" msgstr "Отримати метадані" #: cps/templates/book_edit.html:212 cps/templates/config_db.html:53 -#: cps/templates/config_edit.html:358 cps/templates/config_view_edit.html:172 +#: cps/templates/config_edit.html:358 cps/templates/config_view_edit.html:174 #: cps/templates/email_edit.html:65 cps/templates/shelf_edit.html:25 #: cps/templates/shelf_order.html:41 cps/templates/user_edit.html:142 msgid "Save" @@ -1885,27 +1907,35 @@ msgstr "" msgid "Comments" msgstr "" -#: cps/templates/book_table.html:77 cps/templates/book_table.html:79 -#: cps/templates/book_table.html:81 cps/templates/book_table.html:83 -#: cps/templates/book_table.html:87 cps/templates/book_table.html:89 -#: cps/templates/book_table.html:91 cps/templates/book_table.html:93 +#: cps/templates/book_table.html:75 +msgid "Archiv Status" +msgstr "" + +#: cps/templates/book_table.html:77 cps/templates/search_form.html:42 +msgid "Read Status" +msgstr "" + +#: cps/templates/book_table.html:80 cps/templates/book_table.html:82 +#: cps/templates/book_table.html:84 cps/templates/book_table.html:86 +#: cps/templates/book_table.html:90 cps/templates/book_table.html:92 +#: cps/templates/book_table.html:96 #, fuzzy msgid "Enter " msgstr "Зареєструватись" -#: cps/templates/book_table.html:110 cps/templates/modal_dialogs.html:46 +#: cps/templates/book_table.html:113 cps/templates/modal_dialogs.html:46 msgid "Are you really sure?" msgstr "" -#: cps/templates/book_table.html:114 +#: cps/templates/book_table.html:117 msgid "Books with Title will be merged from:" msgstr "" -#: cps/templates/book_table.html:118 +#: cps/templates/book_table.html:121 msgid "Into Book with Title:" msgstr "" -#: cps/templates/book_table.html:123 +#: cps/templates/book_table.html:126 msgid "Merge" msgstr "" @@ -2081,11 +2111,6 @@ msgstr "" msgid "LDAP Encryption" msgstr "" -#: cps/templates/config_edit.html:204 cps/templates/config_view_edit.html:62 -#: cps/templates/email_edit.html:41 -msgid "None" -msgstr "Ні" - #: cps/templates/config_edit.html:205 msgid "TLS" msgstr "" @@ -2304,11 +2329,11 @@ msgstr "Можливості за замовчуванням для нових msgid "Show Random Books in Detail View" msgstr "Показувати випадкові книги при перегляді деталей" -#: cps/templates/config_view_edit.html:165 cps/templates/user_edit.html:87 +#: cps/templates/config_view_edit.html:166 cps/templates/user_edit.html:87 msgid "Add Allowed/Denied Tags" msgstr "" -#: cps/templates/config_view_edit.html:166 +#: cps/templates/config_view_edit.html:167 msgid "Add Allowed/Denied custom column values" msgstr "" @@ -2357,13 +2382,13 @@ msgstr "" msgid "Description:" msgstr "Опис:" -#: cps/templates/detail.html:256 cps/templates/search.html:14 +#: cps/templates/detail.html:256 cps/templates/search.html:15 msgid "Add to shelf" msgstr "Додати на книжкову полицю" #: cps/templates/detail.html:267 cps/templates/detail.html:284 #: cps/templates/feed.xml:79 cps/templates/layout.html:137 -#: cps/templates/search.html:20 +#: cps/templates/search.html:21 msgid "(Public)" msgstr "" @@ -2441,10 +2466,14 @@ msgstr "" msgid "Next" msgstr "Далі" -#: cps/templates/generate_kobo_auth_url.html:5 +#: cps/templates/generate_kobo_auth_url.html:6 msgid "Open the .kobo/Kobo eReader.conf file in a text editor and add (or edit):" msgstr "" +#: cps/templates/generate_kobo_auth_url.html:11 +msgid "Kobo Token:" +msgstr "" + #: cps/templates/http_error.html:31 msgid "Calibre-Web Instance is unconfigured, please contact your administrator" msgstr "" @@ -2461,29 +2490,29 @@ msgstr "" msgid "Logout User" msgstr "" -#: cps/templates/index.html:69 +#: cps/templates/index.html:70 msgid "Sort ascending according to download count" msgstr "" -#: cps/templates/index.html:70 +#: cps/templates/index.html:71 msgid "Sort descending according to download count" msgstr "" -#: cps/templates/index.html:76 cps/templates/search.html:33 +#: cps/templates/index.html:77 cps/templates/search.html:34 #: cps/templates/shelf.html:23 msgid "Sort authors in alphabetical order" msgstr "" -#: cps/templates/index.html:77 cps/templates/search.html:34 +#: cps/templates/index.html:78 cps/templates/search.html:35 #: cps/templates/shelf.html:24 msgid "Sort authors in reverse alphabetical order" msgstr "" -#: cps/templates/index.html:81 +#: cps/templates/index.html:82 msgid "Sort ascending according to series index" msgstr "" -#: cps/templates/index.html:82 +#: cps/templates/index.html:83 msgid "Sort descending according to series index" msgstr "" @@ -2915,10 +2944,6 @@ msgstr "Дата публікації з" msgid "Published Date To" msgstr "Дата публікації до" -#: cps/templates/search_form.html:42 -msgid "Read Status" -msgstr "" - #: cps/templates/search_form.html:59 msgid "Exclude Tags" msgstr "Виключити теги" diff --git a/cps/translations/zh_Hans_CN/LC_MESSAGES/messages.mo b/cps/translations/zh_Hans_CN/LC_MESSAGES/messages.mo index d0ffc14c..a771e299 100644 Binary files a/cps/translations/zh_Hans_CN/LC_MESSAGES/messages.mo and b/cps/translations/zh_Hans_CN/LC_MESSAGES/messages.mo differ diff --git a/cps/translations/zh_Hans_CN/LC_MESSAGES/messages.po b/cps/translations/zh_Hans_CN/LC_MESSAGES/messages.po index 73bc4efa..2cd0a4ca 100644 --- a/cps/translations/zh_Hans_CN/LC_MESSAGES/messages.po +++ b/cps/translations/zh_Hans_CN/LC_MESSAGES/messages.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Calibre-Web\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2022-01-15 09:19+0100\n" +"POT-Creation-Date: 2022-04-18 20:01+0200\n" "PO-Revision-Date: 2020-09-27 22:18+0800\n" "Last-Translator: xlivevil \n" "Language: zh_CN\n" @@ -16,578 +16,581 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.9.0\n" +"Generated-By: Babel 2.9.1\n" -#: cps/about.py:34 cps/about.py:49 cps/about.py:65 cps/converter.py:31 -msgid "not installed" -msgstr "未安装" - -#: cps/about.py:47 cps/about.py:63 -msgid "installed" -msgstr "已安装" - -#: cps/about.py:145 +#: cps/about.py:86 msgid "Statistics" msgstr "统计" -#: cps/admin.py:144 +#: cps/admin.py:141 msgid "Server restarted, please reload page" msgstr "服务器已重启,请刷新页面" -#: cps/admin.py:146 +#: cps/admin.py:143 msgid "Performing shutdown of server, please close window" msgstr "正在关闭服务器,请关闭窗口" -#: cps/admin.py:154 +#: cps/admin.py:151 msgid "Reconnect successful" msgstr "重新连接成功" -#: cps/admin.py:157 +#: cps/admin.py:154 msgid "Unknown command" msgstr "未知命令" -#: cps/admin.py:167 cps/editbooks.py:707 cps/editbooks.py:721 -#: cps/editbooks.py:866 cps/editbooks.py:868 cps/editbooks.py:895 -#: cps/editbooks.py:911 cps/updater.py:584 cps/uploader.py:93 -#: cps/uploader.py:103 +#: cps/admin.py:176 cps/editbooks.py:713 cps/editbooks.py:892 +#: cps/editbooks.py:894 cps/editbooks.py:930 cps/editbooks.py:947 +#: cps/updater.py:608 cps/uploader.py:93 cps/uploader.py:103 msgid "Unknown" msgstr "未知" -#: cps/admin.py:188 +#: cps/admin.py:197 msgid "Admin page" msgstr "管理页" -#: cps/admin.py:207 +#: cps/admin.py:217 msgid "Basic Configuration" msgstr "基本配置" -#: cps/admin.py:244 +#: cps/admin.py:255 msgid "UI Configuration" msgstr "界面配置" -#: cps/admin.py:277 cps/templates/admin.html:50 +#: cps/admin.py:289 cps/templates/admin.html:51 msgid "Edit Users" msgstr "管理用户" -#: cps/admin.py:318 cps/opds.py:109 cps/opds.py:198 cps/opds.py:275 -#: cps/opds.py:327 cps/templates/grid.html:13 cps/templates/languages.html:9 +#: cps/admin.py:333 cps/opds.py:529 cps/templates/grid.html:13 #: cps/templates/list.html:13 msgid "All" msgstr "全部" -#: cps/admin.py:343 cps/admin.py:1615 +#: cps/admin.py:360 cps/admin.py:1648 msgid "User not found" msgstr "找不到用户" -#: cps/admin.py:357 +#: cps/admin.py:374 msgid "{} users deleted successfully" msgstr "成功删除 {} 个用户" -#: cps/admin.py:379 cps/templates/config_view_edit.html:133 +#: cps/admin.py:397 cps/templates/config_view_edit.html:133 #: cps/templates/user_edit.html:45 cps/templates/user_table.html:81 msgid "Show All" msgstr "显示全部" -#: cps/admin.py:400 cps/admin.py:406 +#: cps/admin.py:418 cps/admin.py:424 msgid "Malformed request" msgstr "格式错误的请求" -#: cps/admin.py:418 cps/admin.py:1493 +#: cps/admin.py:436 cps/admin.py:1526 msgid "Guest Name can't be changed" msgstr "访客名称无法更改" -#: cps/admin.py:430 +#: cps/admin.py:448 msgid "Guest can't have this role" msgstr "游客无法拥有此角色" -#: cps/admin.py:442 cps/admin.py:1451 +#: cps/admin.py:460 cps/admin.py:1484 msgid "No admin user remaining, can't remove admin role" msgstr "理员账户不存在,无法删除管理员角色" -#: cps/admin.py:446 cps/admin.py:460 +#: cps/admin.py:464 cps/admin.py:478 msgid "Value has to be true or false" msgstr "值必须是 true 或 false" -#: cps/admin.py:448 +#: cps/admin.py:466 msgid "Invalid role" msgstr "无效角色" -#: cps/admin.py:452 +#: cps/admin.py:470 msgid "Guest can't have this view" msgstr "游客无法拥有此视图" -#: cps/admin.py:462 +#: cps/admin.py:480 msgid "Invalid view" msgstr "无效视图" -#: cps/admin.py:465 +#: cps/admin.py:483 msgid "Guest's Locale is determined automatically and can't be set" msgstr "游客的本地化是自动侦测而无法设置的" -#: cps/admin.py:469 +#: cps/admin.py:487 msgid "No Valid Locale Given" msgstr "无可用本地化" -#: cps/admin.py:480 +#: cps/admin.py:498 msgid "No Valid Book Language Given" msgstr "无有效书籍语言" -#: cps/admin.py:482 +#: cps/admin.py:500 cps/editbooks.py:1267 msgid "Parameter not found" msgstr "参数未找到" -#: cps/admin.py:533 +#: cps/admin.py:553 msgid "Invalid Read Column" msgstr "无效的阅读列" -#: cps/admin.py:539 +#: cps/admin.py:559 msgid "Invalid Restricted Column" msgstr "无效的限制列" -#: cps/admin.py:560 cps/admin.py:1323 +#: cps/admin.py:579 cps/admin.py:1355 msgid "Calibre-Web configuration updated" msgstr "Calibre-Web配置已更新" -#: cps/admin.py:572 +#: cps/admin.py:591 msgid "Do you really want to delete the Kobo Token?" msgstr "您确定删除Kobo Token吗?" -#: cps/admin.py:574 +#: cps/admin.py:593 msgid "Do you really want to delete this domain?" msgstr "您确定要删除此域吗?" -#: cps/admin.py:576 +#: cps/admin.py:595 msgid "Do you really want to delete this user?" msgstr "您确定要删除此用户吗?" -#: cps/admin.py:578 +#: cps/admin.py:597 msgid "Are you sure you want to delete this shelf?" msgstr "您确定要删除此书架吗?" -#: cps/admin.py:580 +#: cps/admin.py:599 msgid "Are you sure you want to change locales of selected user(s)?" msgstr "您确定要修改选定用户的本地化设置吗?" -#: cps/admin.py:582 +#: cps/admin.py:601 msgid "Are you sure you want to change visible book languages for selected user(s)?" msgstr "您确定要修改选定用户的可见书籍语言吗?" -#: cps/admin.py:584 +#: cps/admin.py:603 msgid "Are you sure you want to change the selected role for the selected user(s)?" msgstr "您确定要修改选定用户的选定角色吗?" -#: cps/admin.py:586 +#: cps/admin.py:605 msgid "Are you sure you want to change the selected restrictions for the selected user(s)?" msgstr "您确定要修改选定用户的选定限制吗?" -#: cps/admin.py:588 +#: cps/admin.py:607 msgid "Are you sure you want to change the selected visibility restrictions for the selected user(s)?" msgstr "您确定要修改选定用户的选定可视化限制吗?" -#: cps/admin.py:590 +#: cps/admin.py:610 msgid "Are you sure you want to change shelf sync behavior for the selected user(s)?" msgstr "您确定要更改所选用户的书架同步行为吗?" -#: cps/admin.py:592 +#: cps/admin.py:612 msgid "Are you sure you want to change Calibre library location?" msgstr "您确定要更改 Calibre 库位置吗?" -#: cps/admin.py:594 +#: cps/admin.py:614 msgid "Are you sure you want delete Calibre-Web's sync database to force a full sync with your Kobo Reader?" -msgstr "" +msgstr "您确定要删除 Calibre-Web 的同步数据库以强制与您的 Kobo Reader 进行完全同步吗" -#: cps/admin.py:743 +#: cps/admin.py:764 msgid "Tag not found" msgstr "标签未找到" -#: cps/admin.py:755 +#: cps/admin.py:776 msgid "Invalid Action" msgstr "无效的动作" -#: cps/admin.py:871 cps/admin.py:877 cps/admin.py:887 cps/admin.py:897 +#: cps/admin.py:893 cps/admin.py:899 cps/admin.py:909 cps/admin.py:919 #: cps/templates/modal_dialogs.html:29 cps/templates/user_table.html:41 #: cps/templates/user_table.html:58 msgid "Deny" msgstr "拒绝" -#: cps/admin.py:873 cps/admin.py:879 cps/admin.py:889 cps/admin.py:899 +#: cps/admin.py:895 cps/admin.py:901 cps/admin.py:911 cps/admin.py:921 #: cps/templates/modal_dialogs.html:28 cps/templates/user_table.html:44 #: cps/templates/user_table.html:61 msgid "Allow" msgstr "允许" -#: cps/admin.py:913 +#: cps/admin.py:936 msgid "{} sync entries deleted" -msgstr "" +msgstr "{} 同步项目被删除" -#: cps/admin.py:1036 +#: cps/admin.py:1059 msgid "client_secrets.json Is Not Configured For Web Application" msgstr "client_secrets.json 未为 Web 应用程序配置" -#: cps/admin.py:1081 +#: cps/admin.py:1104 msgid "Logfile Location is not Valid, Please Enter Correct Path" msgstr "日志文件路径无效,请输入正确的路径" -#: cps/admin.py:1087 +#: cps/admin.py:1110 msgid "Access Logfile Location is not Valid, Please Enter Correct Path" msgstr "访问日志路径无效,请输入正确的路径" -#: cps/admin.py:1117 +#: cps/admin.py:1140 msgid "Please Enter a LDAP Provider, Port, DN and User Object Identifier" msgstr "请输入LDAP主机、端口、DN和用户对象标识符" -#: cps/admin.py:1123 +#: cps/admin.py:1146 msgid "Please Enter a LDAP Service Account and Password" msgstr "请输入一个LDAP服务账号和密码 " -#: cps/admin.py:1126 +#: cps/admin.py:1149 msgid "Please Enter a LDAP Service Account" msgstr "请输入一个LDAP服务账号" -#: cps/admin.py:1131 +#: cps/admin.py:1154 #, python-format msgid "LDAP Group Object Filter Needs to Have One \"%s\" Format Identifier" msgstr "LDAP组对象过滤器需要一个具有“%s”格式标识符" -#: cps/admin.py:1133 +#: cps/admin.py:1156 msgid "LDAP Group Object Filter Has Unmatched Parenthesis" msgstr "LDAP组对象过滤器的括号不匹配" -#: cps/admin.py:1137 +#: cps/admin.py:1160 #, python-format msgid "LDAP User Object Filter needs to Have One \"%s\" Format Identifier" msgstr "LDAP用户对象过滤器需要一个具有“%s”格式标识符" -#: cps/admin.py:1139 +#: cps/admin.py:1162 msgid "LDAP User Object Filter Has Unmatched Parenthesis" msgstr "LDAP用户对象过滤器的括号不匹配" -#: cps/admin.py:1146 +#: cps/admin.py:1169 #, python-format msgid "LDAP Member User Filter needs to Have One \"%s\" Format Identifier" msgstr "LDAP成员用户过滤器需要有一个“%s”格式标识符" -#: cps/admin.py:1148 +#: cps/admin.py:1171 msgid "LDAP Member User Filter Has Unmatched Parenthesis" msgstr "LDAP成员用户过滤器中有不匹配的括号" -#: cps/admin.py:1155 +#: cps/admin.py:1178 msgid "LDAP CACertificate, Certificate or Key Location is not Valid, Please Enter Correct Path" msgstr "LDAP CA证书、证书或密钥位置无效,请输入正确的路径" -#: cps/admin.py:1197 cps/admin.py:1308 cps/admin.py:1405 cps/admin.py:1521 -#: cps/admin.py:1590 cps/shelf.py:100 cps/shelf.py:160 cps/shelf.py:203 -#: cps/shelf.py:279 cps/shelf.py:341 cps/shelf.py:376 cps/shelf.py:451 -msgid "Settings DB is not Writeable" -msgstr "设置数据库不可写入" - -#: cps/admin.py:1208 -msgid "DB Location is not Valid, Please Enter Correct Path" -msgstr "数据库路径无效,请输入正确的路径" - -#: cps/admin.py:1223 -msgid "DB is not Writeable" -msgstr "数据库不可写入" - -#: cps/admin.py:1235 -msgid "Keyfile Location is not Valid, Please Enter Correct Path" -msgstr "密钥文件路径无效,请输入正确的路径" - -#: cps/admin.py:1239 -msgid "Certfile Location is not Valid, Please Enter Correct Path" -msgstr "证书文件路径无效,请输入正确的路径" - -#: cps/admin.py:1346 -msgid "Database Settings updated" -msgstr "数据库设置已更新" - -#: cps/admin.py:1354 -msgid "Database Configuration" -msgstr "数据库配置" - -#: cps/admin.py:1370 cps/web.py:1479 -msgid "Please fill out all fields!" -msgstr "请填写所有字段!" - -#: cps/admin.py:1378 -msgid "E-mail is not from valid domain" -msgstr "邮箱不在有效域中" - -#: cps/admin.py:1384 cps/admin.py:1543 -msgid "Add new user" -msgstr "添加新用户" - -#: cps/admin.py:1395 -#, python-format -msgid "User '%(user)s' created" -msgstr "用户“%(user)s”已创建" - -#: cps/admin.py:1401 -msgid "Found an existing account for this e-mail address or name." -msgstr "使用此邮箱或用户名的账号已经存在。" - -#: cps/admin.py:1430 -#, python-format -msgid "User '%(nick)s' deleted" -msgstr "用户“%(nick)s”已删除" - -#: cps/admin.py:1432 cps/admin.py:1433 -msgid "Can't delete Guest User" -msgstr "无法删除游客用户" - -#: cps/admin.py:1436 -msgid "No admin user remaining, can't delete user" -msgstr "管理员账户不存在,无法删除用户" - -#: cps/admin.py:1509 cps/admin.py:1634 -#, python-format -msgid "Edit User %(nick)s" -msgstr "编辑用户 %(nick)s" - -#: cps/admin.py:1513 -#, python-format -msgid "User '%(nick)s' updated" -msgstr "用户“%(nick)s”已更新" - -#: cps/admin.py:1517 cps/admin.py:1649 cps/web.py:1504 cps/web.py:1564 -msgid "An unknown error occurred. Please try again later." -msgstr "发生一个未知错误,请稍后再试。" - -#: cps/admin.py:1552 cps/templates/admin.html:98 -msgid "Edit E-mail Server Settings" -msgstr "编辑邮件服务器设置" - -#: cps/admin.py:1571 -msgid "Gmail Account Verification Successful" -msgstr "G-Mail账号校验成功" - -#: cps/admin.py:1597 -#, python-format -msgid "Test e-mail queued for sending to %(email)s, please check Tasks for result" -msgstr "发送给%(email)s的测试邮件已进入队列。请检查任务结果" - -#: cps/admin.py:1600 -#, python-format -msgid "There was an error sending the Test e-mail: %(res)s" -msgstr "发送测试邮件时出错:%(res)s" - -#: cps/admin.py:1602 -msgid "Please configure your e-mail address first..." -msgstr "请先配置您的邮箱地址..." - -#: cps/admin.py:1604 -msgid "E-mail server settings updated" -msgstr "邮件服务器设置已更新" - -#: cps/admin.py:1646 -#, python-format -msgid "Password for user %(user)s reset" -msgstr "用户 %(user)s 的密码已重置" - -#: cps/admin.py:1652 cps/web.py:1444 -msgid "Please configure the SMTP mail settings first..." -msgstr "请先配置SMTP邮箱设置..." - -#: cps/admin.py:1663 -msgid "Logfile viewer" -msgstr "日志文件查看器" - -#: cps/admin.py:1729 -msgid "Requesting update package" -msgstr "正在请求更新包" - -#: cps/admin.py:1730 -msgid "Downloading update package" -msgstr "正在下载更新包" - -#: cps/admin.py:1731 -msgid "Unzipping update package" -msgstr "正在解压更新包" - -#: cps/admin.py:1732 -msgid "Replacing files" -msgstr "正在替换文件" - -#: cps/admin.py:1733 -msgid "Database connections are closed" -msgstr "数据库连接已关闭" - -#: cps/admin.py:1734 -msgid "Stopping server" -msgstr "正在停止服务器" - -#: cps/admin.py:1735 -msgid "Update finished, please press okay and reload page" -msgstr "更新完成,请点击确定并刷新页面" - -#: cps/admin.py:1736 cps/admin.py:1737 cps/admin.py:1738 cps/admin.py:1739 -#: cps/admin.py:1740 cps/admin.py:1741 -msgid "Update failed:" -msgstr "更新失败:" - -#: cps/admin.py:1736 cps/updater.py:385 cps/updater.py:595 cps/updater.py:597 -msgid "HTTP Error" -msgstr "HTTP错误" - -#: cps/admin.py:1737 cps/updater.py:387 cps/updater.py:599 -msgid "Connection error" -msgstr "连接错误" - -#: cps/admin.py:1738 cps/updater.py:389 cps/updater.py:601 -msgid "Timeout while establishing connection" -msgstr "建立连接超时" - -#: cps/admin.py:1739 cps/updater.py:391 cps/updater.py:603 -msgid "General error" -msgstr "一般错误" - -#: cps/admin.py:1740 -msgid "Update file could not be saved in temp dir" -msgstr "更新文件无法保存在临时目录中" - -#: cps/admin.py:1741 -msgid "Files could not be replaced during update" -msgstr "更新期间无法替换文件" - -#: cps/admin.py:1765 -msgid "Failed to extract at least One LDAP User" -msgstr "未能提取至少一个LDAP用户" - -#: cps/admin.py:1810 -msgid "Failed to Create at Least One LDAP User" -msgstr "未能创建至少一个LDAP用户" - -#: cps/admin.py:1823 -#, python-format -msgid "Error: %(ldaperror)s" -msgstr "错误:%(ldaperror)s" - -#: cps/admin.py:1827 -msgid "Error: No user returned in response of LDAP server" -msgstr "错误:在LDAP服务器的响应中没有返回用户" - -#: cps/admin.py:1860 -msgid "At Least One LDAP User Not Found in Database" -msgstr "数据库中没有找到至少一个LDAP用户" - -#: cps/admin.py:1862 -msgid "{} User Successfully Imported" -msgstr "{} 用户被成功导入" - -#: cps/converter.py:30 -msgid "not configured" -msgstr "未配置" - -#: cps/converter.py:32 -msgid "Execution permissions missing" -msgstr "缺少执行权限" - -#: cps/db.py:651 cps/web.py:667 cps/web.py:1155 -#, python-format -msgid "Custom Column No.%(column)d is not existing in calibre database" -msgstr "自定义列号:%(column)d在Calibre数据库中不存在" - -#: cps/editbooks.py:300 cps/editbooks.py:302 -msgid "Book Format Successfully Deleted" -msgstr "书籍格式已成功删除" - -#: cps/editbooks.py:309 cps/editbooks.py:311 -msgid "Book Successfully Deleted" -msgstr "书籍已成功删除" - -#: cps/editbooks.py:361 -msgid "You are missing permissions to delete books" -msgstr "" - -#: cps/editbooks.py:376 cps/editbooks.py:763 cps/web.py:523 cps/web.py:1703 -#: cps/web.py:1744 cps/web.py:1811 -msgid "Oops! Selected book title is unavailable. File does not exist or is not accessible" -msgstr "糟糕!选择书名无法打开。文件不存在或者文件不可访问" - -#: cps/editbooks.py:410 -msgid "edit metadata" -msgstr "编辑元数据" - -#: cps/editbooks.py:458 -#, python-format -msgid "%(seriesindex)s is not a valid number, skipping" -msgstr "%(seriesindex)s 不是一个有效的数值,忽略" - -#: cps/editbooks.py:494 cps/editbooks.py:958 -#, python-format -msgid "'%(langname)s' is not a valid language" -msgstr "'%(langname)s' 不是一种有效语言" - -#: cps/editbooks.py:634 cps/editbooks.py:985 -#, python-format -msgid "File extension '%(ext)s' is not allowed to be uploaded to this server" -msgstr "不能上传文件扩展名为“%(ext)s”的文件到此服务器" - -#: cps/editbooks.py:638 cps/editbooks.py:989 -msgid "File to be uploaded must have an extension" -msgstr "要上传的文件必须具有扩展名" - -#: cps/editbooks.py:650 -#, python-format -msgid "Failed to create path %(path)s (Permission denied)." -msgstr "创建路径 %(path)s 失败(权限拒绝)。" - -#: cps/editbooks.py:655 -#, python-format -msgid "Failed to store file %(file)s." -msgstr "保存文件 %(file)s 失败。" - -#: cps/editbooks.py:673 cps/editbooks.py:1076 cps/web.py:1664 +#: cps/admin.py:1223 cps/admin.py:1339 cps/admin.py:1437 cps/admin.py:1554 +#: cps/admin.py:1623 cps/editbooks.py:678 cps/editbooks.py:882 +#: cps/editbooks.py:1130 cps/shelf.py:100 cps/shelf.py:160 cps/shelf.py:203 +#: cps/shelf.py:278 cps/shelf.py:343 cps/shelf.py:380 cps/shelf.py:456 +#: cps/web.py:1742 #, python-format msgid "Database error: %(error)s." msgstr "数据库错误:%(error)s。" -#: cps/editbooks.py:678 +#: cps/admin.py:1235 +msgid "DB Location is not Valid, Please Enter Correct Path" +msgstr "数据库路径无效,请输入正确的路径" + +#: cps/admin.py:1253 +msgid "DB is not Writeable" +msgstr "数据库不可写入" + +#: cps/admin.py:1266 +msgid "Keyfile Location is not Valid, Please Enter Correct Path" +msgstr "密钥文件路径无效,请输入正确的路径" + +#: cps/admin.py:1270 +msgid "Certfile Location is not Valid, Please Enter Correct Path" +msgstr "证书文件路径无效,请输入正确的路径" + +#: cps/admin.py:1378 +msgid "Database Settings updated" +msgstr "数据库设置已更新" + +#: cps/admin.py:1386 +msgid "Database Configuration" +msgstr "数据库配置" + +#: cps/admin.py:1402 cps/web.py:1557 +msgid "Please fill out all fields!" +msgstr "请填写所有字段!" + +#: cps/admin.py:1410 +msgid "E-mail is not from valid domain" +msgstr "邮箱不在有效域中" + +#: cps/admin.py:1416 cps/admin.py:1576 +msgid "Add new user" +msgstr "添加新用户" + +#: cps/admin.py:1427 +#, python-format +msgid "User '%(user)s' created" +msgstr "用户“%(user)s”已创建" + +#: cps/admin.py:1433 +msgid "Found an existing account for this e-mail address or name." +msgstr "使用此邮箱或用户名的账号已经存在。" + +#: cps/admin.py:1463 +#, python-format +msgid "User '%(nick)s' deleted" +msgstr "用户“%(nick)s”已删除" + +#: cps/admin.py:1465 cps/admin.py:1466 +msgid "Can't delete Guest User" +msgstr "无法删除游客用户" + +#: cps/admin.py:1469 +msgid "No admin user remaining, can't delete user" +msgstr "管理员账户不存在,无法删除用户" + +#: cps/admin.py:1542 cps/admin.py:1667 +#, python-format +msgid "Edit User %(nick)s" +msgstr "编辑用户 %(nick)s" + +#: cps/admin.py:1546 +#, python-format +msgid "User '%(nick)s' updated" +msgstr "用户“%(nick)s”已更新" + +#: cps/admin.py:1550 cps/admin.py:1682 cps/web.py:1582 cps/web.py:1642 +msgid "An unknown error occurred. Please try again later." +msgstr "发生一个未知错误,请稍后再试。" + +#: cps/admin.py:1585 cps/templates/admin.html:100 +msgid "Edit E-mail Server Settings" +msgstr "编辑邮件服务器设置" + +#: cps/admin.py:1604 +msgid "Gmail Account Verification Successful" +msgstr "G-Mail账号校验成功" + +#: cps/admin.py:1630 +#, python-format +msgid "Test e-mail queued for sending to %(email)s, please check Tasks for result" +msgstr "发送给%(email)s的测试邮件已进入队列。请检查任务结果" + +#: cps/admin.py:1633 +#, python-format +msgid "There was an error sending the Test e-mail: %(res)s" +msgstr "发送测试邮件时出错:%(res)s" + +#: cps/admin.py:1635 +msgid "Please configure your e-mail address first..." +msgstr "请先配置您的邮箱地址..." + +#: cps/admin.py:1637 +msgid "E-mail server settings updated" +msgstr "邮件服务器设置已更新" + +#: cps/admin.py:1679 +#, python-format +msgid "Password for user %(user)s reset" +msgstr "用户 %(user)s 的密码已重置" + +#: cps/admin.py:1685 cps/web.py:1522 +msgid "Please configure the SMTP mail settings first..." +msgstr "请先配置SMTP邮箱设置..." + +#: cps/admin.py:1696 +msgid "Logfile viewer" +msgstr "日志文件查看器" + +#: cps/admin.py:1762 +msgid "Requesting update package" +msgstr "正在请求更新包" + +#: cps/admin.py:1763 +msgid "Downloading update package" +msgstr "正在下载更新包" + +#: cps/admin.py:1764 +msgid "Unzipping update package" +msgstr "正在解压更新包" + +#: cps/admin.py:1765 +msgid "Replacing files" +msgstr "正在替换文件" + +#: cps/admin.py:1766 +msgid "Database connections are closed" +msgstr "数据库连接已关闭" + +#: cps/admin.py:1767 +msgid "Stopping server" +msgstr "正在停止服务器" + +#: cps/admin.py:1768 +msgid "Update finished, please press okay and reload page" +msgstr "更新完成,请点击确定并刷新页面" + +#: cps/admin.py:1769 cps/admin.py:1770 cps/admin.py:1771 cps/admin.py:1772 +#: cps/admin.py:1773 cps/admin.py:1774 +msgid "Update failed:" +msgstr "更新失败:" + +#: cps/admin.py:1769 cps/updater.py:384 cps/updater.py:619 cps/updater.py:621 +msgid "HTTP Error" +msgstr "HTTP错误" + +#: cps/admin.py:1770 cps/updater.py:386 cps/updater.py:623 +msgid "Connection error" +msgstr "连接错误" + +#: cps/admin.py:1771 cps/updater.py:388 cps/updater.py:625 +msgid "Timeout while establishing connection" +msgstr "建立连接超时" + +#: cps/admin.py:1772 cps/updater.py:390 cps/updater.py:627 +msgid "General error" +msgstr "一般错误" + +#: cps/admin.py:1773 +msgid "Update file could not be saved in temp dir" +msgstr "更新文件无法保存在临时目录中" + +#: cps/admin.py:1774 +msgid "Files could not be replaced during update" +msgstr "更新期间无法替换文件" + +#: cps/admin.py:1798 +msgid "Failed to extract at least One LDAP User" +msgstr "未能提取至少一个LDAP用户" + +#: cps/admin.py:1843 +msgid "Failed to Create at Least One LDAP User" +msgstr "未能创建至少一个LDAP用户" + +#: cps/admin.py:1856 +#, python-format +msgid "Error: %(ldaperror)s" +msgstr "错误:%(ldaperror)s" + +#: cps/admin.py:1860 +msgid "Error: No user returned in response of LDAP server" +msgstr "错误:在LDAP服务器的响应中没有返回用户" + +#: cps/admin.py:1893 +msgid "At Least One LDAP User Not Found in Database" +msgstr "数据库中没有找到至少一个LDAP用户" + +#: cps/admin.py:1895 +msgid "{} User Successfully Imported" +msgstr "{} 用户被成功导入" + +#: cps/converter.py:30 +msgid "not installed" +msgstr "未安装" + +#: cps/converter.py:31 +msgid "Execution permissions missing" +msgstr "缺少执行权限" + +#: cps/db.py:674 cps/web.py:710 cps/web.py:1222 +#, python-format +msgid "Custom Column No.%(column)d is not existing in calibre database" +msgstr "自定义列号:%(column)d在Calibre数据库中不存在" + +#: cps/db.py:917 cps/templates/config_edit.html:204 +#: cps/templates/config_view_edit.html:62 cps/templates/email_edit.html:41 +#: cps/web.py:551 cps/web.py:585 cps/web.py:646 cps/web.py:671 cps/web.py:1003 +#: cps/web.py:1032 cps/web.py:1066 cps/web.py:1093 cps/web.py:1132 +msgid "None" +msgstr "无" + +#: cps/editbooks.py:295 cps/editbooks.py:297 +msgid "Book Format Successfully Deleted" +msgstr "书籍格式已成功删除" + +#: cps/editbooks.py:304 cps/editbooks.py:306 +msgid "Book Successfully Deleted" +msgstr "书籍已成功删除" + +#: cps/editbooks.py:358 +msgid "You are missing permissions to delete books" +msgstr "您没有删除书籍的权限" + +#: cps/editbooks.py:373 cps/editbooks.py:765 cps/web.py:518 cps/web.py:1783 +#: cps/web.py:1825 cps/web.py:1870 +msgid "Oops! Selected book title is unavailable. File does not exist or is not accessible" +msgstr "糟糕!选择书名无法打开。文件不存在或者文件不可访问" + +#: cps/editbooks.py:408 +msgid "edit metadata" +msgstr "编辑元数据" + +#: cps/editbooks.py:457 +#, python-format +msgid "%(seriesindex)s is not a valid number, skipping" +msgstr "%(seriesindex)s 不是一个有效的数值,忽略" + +#: cps/editbooks.py:493 cps/editbooks.py:1001 +#, python-format +msgid "'%(langname)s' is not a valid language" +msgstr "'%(langname)s' 不是一种有效语言" + +#: cps/editbooks.py:634 +msgid "User has no rights to upload additional file formats" +msgstr "用户没有权限上传其他文件格式" + +#: cps/editbooks.py:639 cps/editbooks.py:1029 +#, python-format +msgid "File extension '%(ext)s' is not allowed to be uploaded to this server" +msgstr "不能上传文件扩展名为“%(ext)s”的文件到此服务器" + +#: cps/editbooks.py:643 cps/editbooks.py:1033 +msgid "File to be uploaded must have an extension" +msgstr "要上传的文件必须具有扩展名" + +#: cps/editbooks.py:655 +#, python-format +msgid "Failed to create path %(path)s (Permission denied)." +msgstr "创建路径 %(path)s 失败(权限拒绝)。" + +#: cps/editbooks.py:660 +#, python-format +msgid "Failed to store file %(file)s." +msgstr "保存文件 %(file)s 失败。" + +#: cps/editbooks.py:683 #, python-format msgid "File format %(ext)s added to %(book)s" msgstr "已添加 %(ext)s 格式到 %(book)s" -#: cps/editbooks.py:814 +#: cps/editbooks.py:697 cps/editbooks.py:809 +msgid "User has no rights to upload cover" +msgstr "用户没有权限上传封面" + +#: cps/editbooks.py:828 msgid "Identifiers are not Case Sensitive, Overwriting Old Identifier" msgstr "标识符不区分大小写,覆盖旧标识符" -#: cps/editbooks.py:848 +#: cps/editbooks.py:869 msgid "Metadata successfully updated" msgstr "已成功更新元数据" -#: cps/editbooks.py:861 -msgid "Error editing book, please check logfile for details" -msgstr "编辑书籍出错,请检查日志文件以获取详细信息" +#: cps/editbooks.py:887 +msgid "Error editing book: {}" +msgstr "编辑书籍时出错: {}" -#: cps/editbooks.py:899 +#: cps/editbooks.py:951 msgid "Uploaded book probably exists in the library, consider to change before upload new: " msgstr "上传的书籍可能已经存在,建议修改后重新上传: " -#: cps/editbooks.py:997 +#: cps/editbooks.py:1041 #, python-format msgid "File %(filename)s could not saved to temp dir" msgstr "文件 %(filename)s 无法保存到临时目录" -#: cps/editbooks.py:1016 +#: cps/editbooks.py:1061 #, python-format msgid "Failed to Move Cover File %(file)s: %(error)s" msgstr "移动封面文件失败 %(file)s:%(error)s" -#: cps/editbooks.py:1063 +#: cps/editbooks.py:1117 #, python-format msgid "File %(file)s uploaded" msgstr "文件 %(file)s 已上传" -#: cps/editbooks.py:1088 +#: cps/editbooks.py:1143 msgid "Source or destination format for conversion missing" msgstr "转换的源或目的格式缺失" -#: cps/editbooks.py:1096 +#: cps/editbooks.py:1151 #, python-format msgid "Book successfully queued for converting to %(book_format)s" msgstr "书籍已经被成功加入到 %(book_format)s 格式转换队列" -#: cps/editbooks.py:1100 +#: cps/editbooks.py:1155 #, python-format msgid "There was an error converting this book: %(res)s" msgstr "转换此书籍时出现错误: %(res)s" @@ -600,174 +603,190 @@ msgstr "Google Drive 设置未完成,请尝试停用并再次激活Google云 msgid "Callback domain is not verified, please follow steps to verify domain in google developer console" msgstr "回调域名尚未被校验,请在google开发者控制台按步骤校验域名" -#: cps/helper.py:77 +#: cps/helper.py:81 #, python-format msgid "%(format)s format not found for book id: %(book)d" msgstr "找不到id为 %(book)d 的书籍的 %(format)s 格式" -#: cps/helper.py:83 cps/tasks/convert.py:73 +#: cps/helper.py:87 cps/tasks/convert.py:75 #, python-format msgid "%(format)s not found on Google Drive: %(fn)s" msgstr "Google Drive %(fn)s 上找不到 %(format)s" -#: cps/helper.py:88 +#: cps/helper.py:92 #, python-format msgid "%(format)s not found: %(fn)s" msgstr "找不到 %(format)s:%(fn)s" -#: cps/helper.py:93 cps/helper.py:217 cps/templates/detail.html:41 +#: cps/helper.py:97 cps/helper.py:221 cps/templates/detail.html:41 #: cps/templates/detail.html:45 msgid "Send to Kindle" msgstr "发送到Kindle" -#: cps/helper.py:94 cps/helper.py:111 cps/helper.py:219 +#: cps/helper.py:98 cps/helper.py:115 cps/helper.py:223 msgid "This e-mail has been sent via Calibre-Web." msgstr "此邮件已经通过Calibre-Web发送。" -#: cps/helper.py:109 +#: cps/helper.py:113 msgid "Calibre-Web test e-mail" msgstr "Calibre-Web测试邮件" -#: cps/helper.py:110 +#: cps/helper.py:114 msgid "Test e-mail" msgstr "测试邮件" -#: cps/helper.py:127 +#: cps/helper.py:131 msgid "Get Started with Calibre-Web" msgstr "开启Calibre-Web之旅" -#: cps/helper.py:132 +#: cps/helper.py:136 #, python-format msgid "Registration e-mail for user: %(name)s" msgstr "用户注册电子邮件:%(name)s" -#: cps/helper.py:143 cps/helper.py:149 +#: cps/helper.py:147 cps/helper.py:153 #, python-format msgid "Convert %(orig)s to %(format)s and send to Kindle" msgstr "转换 %(orig)s 到 %(format)s 并发送到Kindle" -#: cps/helper.py:168 cps/helper.py:172 cps/helper.py:176 +#: cps/helper.py:172 cps/helper.py:176 cps/helper.py:180 #, python-format msgid "Send %(format)s to Kindle" msgstr "发送 %(format)s 到Kindle" -#: cps/helper.py:216 cps/tasks/convert.py:90 +#: cps/helper.py:220 cps/tasks/convert.py:92 #, python-format msgid "%(book)s send to Kindle" msgstr "%(book)s发送到Kindle" -#: cps/helper.py:221 +#: cps/helper.py:225 msgid "The requested file could not be read. Maybe wrong permissions?" msgstr "无法读取请求的文件。可能有错误的权限设置?" -#: cps/helper.py:313 +#: cps/helper.py:353 +msgid "Read status could not set: {}" +msgstr "阅读状态无法设置: {}" + +#: cps/helper.py:376 #, python-format msgid "Deleting bookfolder for book %(id)s failed, path has subfolders: %(path)s" msgstr "删除书的文件夹%(id)s失败,路径有子文件夹:%(path)s" -#: cps/helper.py:319 +#: cps/helper.py:382 #, python-format msgid "Deleting book %(id)s failed: %(message)s" msgstr "删除书籍 %(id)s失败:%(message)s" -#: cps/helper.py:330 +#: cps/helper.py:393 #, python-format msgid "Deleting book %(id)s from database only, book path in database not valid: %(path)s" msgstr "仅从数据库中删除书籍 %(id)s,数据库中的书籍路径无效: %(path)s" -#: cps/helper.py:385 +#: cps/helper.py:458 #, python-format -msgid "Rename title from: '%(src)s' to '%(dest)s' failed with error: %(error)s" -msgstr "将标题从“%(src)s”改为“%(dest)s”时失败,出错信息:%(error)s" +msgid "Rename author from: '%(src)s' to '%(dest)s' failed with error: %(error)s" +msgstr "将作者从“%(src)s”改为“%(dest)s”时失败,出错信息:%(error)s" -#: cps/helper.py:400 -#, python-format -msgid "Rename file in path '%(src)s' to '%(dest)s' failed with error: %(error)s" -msgstr "从“%(src)s”重命名为“%(dest)s”失败,出错信息:%(error)s" - -#: cps/helper.py:425 cps/helper.py:435 cps/helper.py:443 +#: cps/helper.py:529 cps/helper.py:538 #, python-format msgid "File %(file)s not found on Google Drive" msgstr "Google Drive上找不到文件 %(file)s" -#: cps/helper.py:464 +#: cps/helper.py:572 +#, python-format +msgid "Rename title from: '%(src)s' to '%(dest)s' failed with error: %(error)s" +msgstr "将标题从“%(src)s”改为“%(dest)s”时失败,出错信息:%(error)s" + +#: cps/helper.py:592 +msgid "Error in rename file in path: {}" +msgstr "重命名此路径: {}文件时出错" + +#: cps/helper.py:610 #, python-format msgid "Book path %(path)s not found on Google Drive" msgstr "Google Drive上找不到书籍路径 %(path)s" -#: cps/helper.py:504 cps/web.py:1659 +#: cps/helper.py:651 cps/web.py:1737 msgid "Found an existing account for this e-mail address" msgstr "使用此邮箱的账号已经存在。" -#: cps/helper.py:512 +#: cps/helper.py:659 msgid "This username is already taken" msgstr "此用户名已被使用" -#: cps/helper.py:522 +#: cps/helper.py:669 msgid "Invalid e-mail address format" msgstr "无效的邮件地址格式" -#: cps/helper.py:595 +#: cps/helper.py:754 +msgid "Python modul 'advocate' is not installed but is needed for cover downloads" +msgstr "下载封面必须的 Python 模块'advocate' 未安装" + +#: cps/helper.py:767 msgid "Error Downloading Cover" msgstr "下载封面时出错" -#: cps/helper.py:598 +#: cps/helper.py:770 msgid "Cover Format Error" msgstr "封面格式出错" -#: cps/helper.py:608 +#: cps/helper.py:773 +msgid "You are not allowed to access localhost or the local network for cover uploads" +msgstr "您没有访问本地主机或本地网络进行封面上传" + +#: cps/helper.py:783 msgid "Failed to create path for cover" msgstr "创建封面路径失败" -#: cps/helper.py:624 +#: cps/helper.py:799 msgid "Cover-file is not a valid image file, or could not be stored" msgstr "封面文件不是有效的图片文件,或者无法存储" -#: cps/helper.py:635 +#: cps/helper.py:810 msgid "Only jpg/jpeg/png/webp/bmp files are supported as coverfile" msgstr "封面文件只支持jpg/jpeg/png/webp/bmp文件" -#: cps/helper.py:648 +#: cps/helper.py:822 msgid "Invalid cover file content" msgstr "封面文件内容无效" -#: cps/helper.py:652 +#: cps/helper.py:826 msgid "Only jpg/jpeg files are supported as coverfile" msgstr "仅将jpg、jpeg文件作为封面文件" -#: cps/helper.py:704 +#: cps/helper.py:878 msgid "Unrar binary file not found" msgstr "找不到Unrar执行文件" -#: cps/helper.py:715 +#: cps/helper.py:889 msgid "Error excecuting UnRar" msgstr "执行UnRar时出错" -#: cps/helper.py:763 +#: cps/helper.py:937 msgid "Waiting" msgstr "等待中" -#: cps/helper.py:765 +#: cps/helper.py:939 msgid "Failed" msgstr "失败" -#: cps/helper.py:767 +#: cps/helper.py:941 msgid "Started" msgstr "已开始" -#: cps/helper.py:769 +#: cps/helper.py:943 msgid "Finished" msgstr "已完成" -#: cps/helper.py:771 +#: cps/helper.py:945 msgid "Unknown Status" msgstr "未知状态" -#: cps/kobo_auth.py:127 -msgid "PLease access calibre-web from non localhost to get valid api_endpoint for kobo device" +#: cps/kobo_auth.py:128 +msgid "Please access Calibre-Web from non localhost to get valid api_endpoint for kobo device" msgstr "请不要使用localhost访问Calibre-Web,以便Kobo设备能获取有效的api_endpoint" -#: cps/kobo_auth.py:130 cps/kobo_auth.py:158 +#: cps/kobo_auth.py:154 msgid "Kobo Setup" msgstr "Kobo 设置" @@ -776,7 +795,7 @@ msgstr "Kobo 设置" msgid "Register with %(provider)s" msgstr "使用 %(provider)s 注册" -#: cps/oauth_bb.py:138 cps/remotelogin.py:133 cps/web.py:1535 +#: cps/oauth_bb.py:138 cps/remotelogin.py:130 cps/web.py:1613 #, python-format msgid "you are now logged in as: '%(nickname)s'" msgstr "您现在已以“%(nickname)s”身份登录" @@ -837,163 +856,163 @@ msgstr "Google Oauth 错误,请重试。" msgid "Google Oauth error: {}" msgstr "Google Oauth 错误: {}" -#: cps/opds.py:384 +#: cps/opds.py:298 msgid "{} Stars" msgstr "{} 星" -#: cps/remotelogin.py:65 cps/templates/layout.html:84 -#: cps/templates/login.html:4 cps/templates/login.html:21 cps/web.py:1584 +#: cps/remotelogin.py:62 cps/templates/layout.html:84 +#: cps/templates/login.html:4 cps/templates/login.html:21 cps/web.py:1662 msgid "Login" msgstr "登录" -#: cps/remotelogin.py:77 cps/remotelogin.py:111 +#: cps/remotelogin.py:74 cps/remotelogin.py:108 msgid "Token not found" msgstr "找不到Token" -#: cps/remotelogin.py:86 cps/remotelogin.py:119 +#: cps/remotelogin.py:83 cps/remotelogin.py:116 msgid "Token has expired" msgstr "Token已过期" -#: cps/remotelogin.py:95 +#: cps/remotelogin.py:92 msgid "Success! Please return to your device" msgstr "成功!请返回您的设备" -#: cps/render_template.py:39 cps/web.py:416 +#: cps/render_template.py:41 cps/web.py:407 msgid "Books" msgstr "书籍" -#: cps/render_template.py:41 +#: cps/render_template.py:43 msgid "Show recent books" msgstr "显示最近书籍" -#: cps/render_template.py:42 cps/templates/index.xml:25 +#: cps/render_template.py:44 cps/templates/index.xml:25 msgid "Hot Books" msgstr "热门书籍" -#: cps/render_template.py:44 +#: cps/render_template.py:46 msgid "Show Hot Books" msgstr "显示热门书籍" -#: cps/render_template.py:46 cps/render_template.py:51 +#: cps/render_template.py:48 cps/render_template.py:53 msgid "Downloaded Books" msgstr "下载历史" -#: cps/render_template.py:48 cps/render_template.py:53 +#: cps/render_template.py:50 cps/render_template.py:55 #: cps/templates/user_table.html:167 msgid "Show Downloaded Books" msgstr "显示下载过的书籍" -#: cps/render_template.py:56 cps/templates/index.xml:32 cps/web.py:430 +#: cps/render_template.py:58 cps/templates/index.xml:32 cps/web.py:422 msgid "Top Rated Books" msgstr "最高评分书籍" -#: cps/render_template.py:58 cps/templates/user_table.html:161 +#: cps/render_template.py:60 cps/templates/user_table.html:161 msgid "Show Top Rated Books" msgstr "显示最高评分书籍" -#: cps/render_template.py:59 cps/templates/index.xml:54 -#: cps/templates/index.xml:58 cps/web.py:676 +#: cps/render_template.py:61 cps/templates/index.xml:54 +#: cps/templates/index.xml:58 cps/web.py:729 msgid "Read Books" msgstr "已读书籍" -#: cps/render_template.py:61 +#: cps/render_template.py:63 msgid "Show read and unread" msgstr "显示阅读状态" -#: cps/render_template.py:63 cps/templates/index.xml:61 -#: cps/templates/index.xml:65 cps/web.py:679 +#: cps/render_template.py:65 cps/templates/index.xml:61 +#: cps/templates/index.xml:65 cps/web.py:732 msgid "Unread Books" msgstr "未读书籍" -#: cps/render_template.py:65 +#: cps/render_template.py:67 msgid "Show unread" msgstr "显示未读" -#: cps/render_template.py:66 +#: cps/render_template.py:68 msgid "Discover" msgstr "发现" -#: cps/render_template.py:68 cps/templates/index.xml:50 +#: cps/render_template.py:70 cps/templates/index.xml:50 #: cps/templates/user_table.html:162 msgid "Show Random Books" msgstr "显示随机书籍" -#: cps/render_template.py:69 cps/templates/book_table.html:67 -#: cps/templates/index.xml:83 cps/web.py:1041 +#: cps/render_template.py:71 cps/templates/book_table.html:67 +#: cps/templates/index.xml:83 cps/web.py:1135 msgid "Categories" msgstr "分类" -#: cps/render_template.py:71 cps/templates/user_table.html:158 +#: cps/render_template.py:73 cps/templates/user_table.html:158 msgid "Show category selection" msgstr "显示分类选择" -#: cps/render_template.py:72 cps/templates/book_edit.html:90 +#: cps/render_template.py:74 cps/templates/book_edit.html:90 #: cps/templates/book_table.html:68 cps/templates/index.xml:90 -#: cps/templates/search_form.html:69 cps/web.py:948 cps/web.py:959 +#: cps/templates/search_form.html:69 cps/web.py:1034 cps/web.py:1041 msgid "Series" msgstr "丛书" -#: cps/render_template.py:74 cps/templates/user_table.html:157 +#: cps/render_template.py:76 cps/templates/user_table.html:157 msgid "Show series selection" msgstr "显示丛书选择" -#: cps/render_template.py:75 cps/templates/book_table.html:66 +#: cps/render_template.py:77 cps/templates/book_table.html:66 #: cps/templates/index.xml:69 msgid "Authors" msgstr "作者" -#: cps/render_template.py:77 cps/templates/user_table.html:160 +#: cps/render_template.py:79 cps/templates/user_table.html:160 msgid "Show author selection" msgstr "显示作者选择" -#: cps/render_template.py:79 cps/templates/book_table.html:72 -#: cps/templates/index.xml:76 cps/web.py:925 +#: cps/render_template.py:81 cps/templates/book_table.html:72 +#: cps/templates/index.xml:76 cps/web.py:1006 msgid "Publishers" msgstr "出版社" -#: cps/render_template.py:81 cps/templates/user_table.html:163 +#: cps/render_template.py:83 cps/templates/user_table.html:163 msgid "Show publisher selection" msgstr "显示出版社选择" -#: cps/render_template.py:82 cps/templates/book_table.html:70 +#: cps/render_template.py:84 cps/templates/book_table.html:70 #: cps/templates/index.xml:97 cps/templates/search_form.html:107 -#: cps/web.py:1018 +#: cps/web.py:1108 msgid "Languages" msgstr "语言" -#: cps/render_template.py:85 cps/templates/user_table.html:155 +#: cps/render_template.py:87 cps/templates/user_table.html:155 msgid "Show language selection" msgstr "显示语言选择" -#: cps/render_template.py:86 cps/templates/index.xml:104 +#: cps/render_template.py:88 cps/templates/index.xml:104 msgid "Ratings" msgstr "评分" -#: cps/render_template.py:88 cps/templates/user_table.html:164 +#: cps/render_template.py:90 cps/templates/user_table.html:164 msgid "Show ratings selection" msgstr "显示评分选择" -#: cps/render_template.py:89 cps/templates/index.xml:112 +#: cps/render_template.py:91 cps/templates/index.xml:112 msgid "File formats" msgstr "文件格式" -#: cps/render_template.py:91 cps/templates/user_table.html:165 +#: cps/render_template.py:93 cps/templates/user_table.html:165 msgid "Show file formats selection" msgstr "显示文件格式选择" -#: cps/render_template.py:93 cps/web.py:703 +#: cps/render_template.py:95 cps/web.py:755 msgid "Archived Books" msgstr "归档书籍" -#: cps/render_template.py:95 cps/templates/user_table.html:166 +#: cps/render_template.py:97 cps/templates/user_table.html:166 msgid "Show archived books" msgstr "显示归档书籍" -#: cps/render_template.py:97 cps/web.py:780 +#: cps/render_template.py:100 cps/web.py:837 msgid "Books List" msgstr "书籍列表" -#: cps/render_template.py:99 cps/templates/user_table.html:168 +#: cps/render_template.py:102 cps/templates/user_table.html:168 msgid "Show Books List" msgstr "显示书籍列表" @@ -1017,7 +1036,7 @@ msgstr "此书籍已被添加到书架:%(sname)s" #: cps/shelf.py:126 msgid "You are not allowed to add a book to the shelf" -msgstr "你没有向书架添加书籍的权限" +msgstr "您没有向书架添加书籍的权限" #: cps/shelf.py:144 #, python-format @@ -1041,267 +1060,270 @@ msgstr "此书已从书架 %(sname)s 中删除" #: cps/shelf.py:218 msgid "Sorry you are not allowed to remove a book from this shelf" -msgstr "抱歉,你没有从这个书架删除书籍的权限" +msgstr "抱歉,您没有从这个书架删除书籍的权限" #: cps/shelf.py:228 cps/templates/layout.html:140 msgid "Create a Shelf" msgstr "创建书架" -#: cps/shelf.py:237 +#: cps/shelf.py:236 msgid "Sorry you are not allowed to edit this shelf" msgstr "对不起,您没有编辑这个书架的权限" -#: cps/shelf.py:239 +#: cps/shelf.py:238 msgid "Edit a shelf" msgstr "编辑书架" -#: cps/shelf.py:249 +#: cps/shelf.py:248 msgid "Sorry you are not allowed to create a public shelf" -msgstr "抱歉,你没有创建公开书架的权限" +msgstr "抱歉,您没有创建公开书架的权限" -#: cps/shelf.py:266 +#: cps/shelf.py:265 #, python-format msgid "Shelf %(title)s created" msgstr "书架 %(title)s 已创建" -#: cps/shelf.py:269 +#: cps/shelf.py:268 #, python-format msgid "Shelf %(title)s changed" msgstr "书架 %(title)s 已修改" -#: cps/shelf.py:283 +#: cps/shelf.py:282 msgid "There was an error" msgstr "发生错误" -#: cps/shelf.py:305 +#: cps/shelf.py:304 #, python-format msgid "A public shelf with the name '%(title)s' already exists." msgstr "公共书架:%(title)s已经存在已经存在。" -#: cps/shelf.py:316 +#: cps/shelf.py:315 #, python-format msgid "A private shelf with the name '%(title)s' already exists." msgstr "私有书架:%(title)s已经存在已经存在。" #: cps/shelf.py:337 -#, fuzzy -msgid "Shelf successfully deleted" -msgstr "书籍已成功删除" +msgid "Error deleting Shelf" +msgstr "删除书架时出错" -#: cps/shelf.py:386 +#: cps/shelf.py:339 +msgid "Shelf successfully deleted" +msgstr "书架已成功删除" + +#: cps/shelf.py:389 #, python-format msgid "Change order of Shelf: '%(name)s'" msgstr "修改书架 %(name)s 顺序" -#: cps/shelf.py:456 +#: cps/shelf.py:461 #, python-format msgid "Shelf: '%(name)s'" msgstr "书架:%(name)s" -#: cps/shelf.py:460 +#: cps/shelf.py:465 msgid "Error opening shelf. Shelf does not exist or is not accessible" msgstr "打开书架出错。书架不存在或不可访问" -#: cps/updater.py:403 cps/updater.py:414 cps/updater.py:514 cps/updater.py:529 +#: cps/updater.py:426 cps/updater.py:437 cps/updater.py:538 cps/updater.py:553 msgid "Unexpected data while reading update information" msgstr "读取更新信息时出现意外数据" -#: cps/updater.py:410 cps/updater.py:521 +#: cps/updater.py:433 cps/updater.py:545 msgid "No update available. You already have the latest version installed" msgstr "无可用更新。您已经安装了最新版本" -#: cps/updater.py:428 +#: cps/updater.py:451 msgid "A new update is available. Click on the button below to update to the latest version." msgstr "有新的更新。单击下面的按钮以更新到最新版本。" -#: cps/updater.py:446 +#: cps/updater.py:469 msgid "Could not fetch update information" msgstr "无法获取更新信息" -#: cps/updater.py:456 +#: cps/updater.py:479 msgid "Click on the button below to update to the latest stable version." msgstr "点击下面按钮更新到最新稳定版本。" -#: cps/updater.py:465 cps/updater.py:479 cps/updater.py:490 +#: cps/updater.py:488 cps/updater.py:502 cps/updater.py:513 #, python-format msgid "A new update is available. Click on the button below to update to version: %(version)s" msgstr "有新的更新。单击下面的按钮以更新到版本: %(version)s" -#: cps/updater.py:507 +#: cps/updater.py:531 msgid "No release information available" msgstr "无可用发布信息" -#: cps/templates/index.html:5 cps/web.py:440 +#: cps/templates/index.html:5 cps/web.py:434 msgid "Discover (Random Books)" msgstr "发现(随机书籍)" -#: cps/web.py:471 +#: cps/web.py:470 msgid "Hot Books (Most Downloaded)" msgstr "热门书籍(最多下载)" -#: cps/web.py:507 +#: cps/web.py:501 #, python-format msgid "Downloaded books by %(user)s" msgstr "%(user)s 下载过的书籍" -#: cps/web.py:539 +#: cps/web.py:534 #, python-format msgid "Author: %(name)s" msgstr "作者:%(name)s" -#: cps/web.py:554 +#: cps/web.py:570 #, python-format msgid "Publisher: %(name)s" msgstr "出版社:%(name)s" -#: cps/web.py:569 +#: cps/web.py:598 #, python-format msgid "Series: %(serie)s" msgstr "丛书:%(serie)s" -#: cps/web.py:582 +#: cps/web.py:610 #, python-format msgid "Rating: %(rating)s stars" msgstr "评分:%(rating)s 星" -#: cps/web.py:597 +#: cps/web.py:626 #, python-format msgid "File format: %(format)s" msgstr "文件格式:%(format)s" -#: cps/web.py:615 +#: cps/web.py:663 #, python-format msgid "Category: %(name)s" msgstr "分类:%(name)s" -#: cps/web.py:631 +#: cps/web.py:690 #, python-format msgid "Language: %(name)s" msgstr "语言:%(name)s" -#: cps/templates/layout.html:56 cps/web.py:737 cps/web.py:1371 +#: cps/templates/layout.html:56 cps/web.py:789 cps/web.py:1444 msgid "Advanced Search" msgstr "高级搜索" #: cps/templates/book_edit.html:235 cps/templates/feed.xml:33 #: cps/templates/index.xml:11 cps/templates/layout.html:45 #: cps/templates/layout.html:48 cps/templates/search_form.html:226 -#: cps/web.py:750 cps/web.py:1077 +#: cps/web.py:807 cps/web.py:1164 msgid "Search" msgstr "搜索" -#: cps/templates/admin.html:16 cps/web.py:903 +#: cps/templates/admin.html:16 cps/web.py:979 msgid "Downloads" msgstr "下载次数" -#: cps/web.py:980 +#: cps/web.py:1068 msgid "Ratings list" msgstr "评分列表" -#: cps/web.py:1001 +#: cps/web.py:1095 msgid "File formats list" msgstr "文件格式列表" -#: cps/templates/layout.html:73 cps/templates/tasks.html:7 cps/web.py:1055 +#: cps/templates/layout.html:73 cps/templates/tasks.html:7 cps/web.py:1149 msgid "Tasks" msgstr "任务列表" -#: cps/web.py:1215 +#: cps/web.py:1286 msgid "Published after " msgstr "出版时间晚于 " -#: cps/web.py:1222 +#: cps/web.py:1293 msgid "Published before " msgstr "出版时间早于 " -#: cps/web.py:1244 +#: cps/web.py:1315 #, python-format msgid "Rating <= %(rating)s" msgstr "评分 <= %(rating)s" -#: cps/web.py:1246 +#: cps/web.py:1317 #, python-format msgid "Rating >= %(rating)s" msgstr "评分 >= %(rating)s" -#: cps/web.py:1248 +#: cps/web.py:1319 #, python-format msgid "Read Status = %(status)s" msgstr "阅读状态 = %(status)s" -#: cps/web.py:1353 +#: cps/web.py:1425 msgid "Error on search for custom columns, please restart Calibre-Web" msgstr "搜索自定义列时出错,请重启 Calibre-Web" -#: cps/web.py:1449 +#: cps/web.py:1527 #, python-format msgid "Book successfully queued for sending to %(kindlemail)s" msgstr "书籍已经成功加入 %(kindlemail)s 的发送队列" -#: cps/web.py:1453 +#: cps/web.py:1531 #, python-format msgid "Oops! There was an error sending this book: %(res)s" msgstr "糟糕!发送这本书籍的时候出现错误:%(res)s" -#: cps/web.py:1455 +#: cps/web.py:1533 msgid "Please update your profile with a valid Send to Kindle E-mail Address." msgstr "请先配置您的kindle邮箱。" -#: cps/web.py:1472 +#: cps/web.py:1550 msgid "E-Mail server is not configured, please contact your administrator!" msgstr "邮件服务未配置,请联系网站管理员!" -#: cps/templates/layout.html:85 cps/templates/register.html:17 cps/web.py:1473 -#: cps/web.py:1480 cps/web.py:1486 cps/web.py:1505 cps/web.py:1509 -#: cps/web.py:1515 +#: cps/templates/layout.html:85 cps/templates/register.html:17 cps/web.py:1551 +#: cps/web.py:1558 cps/web.py:1564 cps/web.py:1583 cps/web.py:1587 +#: cps/web.py:1593 msgid "Register" msgstr "注册" -#: cps/web.py:1507 +#: cps/web.py:1585 msgid "Your e-mail is not allowed to register" msgstr "您的电子邮件不允许注册" -#: cps/web.py:1510 +#: cps/web.py:1588 msgid "Confirmation e-mail was send to your e-mail account." msgstr "确认邮件已经发送到您的邮箱。" -#: cps/web.py:1524 +#: cps/web.py:1602 msgid "Cannot activate LDAP authentication" msgstr "无法激活LDAP认证" -#: cps/web.py:1543 +#: cps/web.py:1621 #, python-format msgid "Fallback Login as: '%(nickname)s', LDAP Server not reachable, or user not known" msgstr "后备登录“%(nickname)s”:无法访问LDAP服务器,或用户未知" -#: cps/web.py:1549 +#: cps/web.py:1627 #, python-format msgid "Could not login: %(message)s" msgstr "无法登录:%(message)s" -#: cps/web.py:1553 cps/web.py:1578 +#: cps/web.py:1631 cps/web.py:1656 msgid "Wrong Username or Password" msgstr "用户名或密码错误" -#: cps/web.py:1560 +#: cps/web.py:1638 msgid "New Password was send to your email address" msgstr "新密码已发送到您的邮箱" -#: cps/web.py:1566 +#: cps/web.py:1644 msgid "Please enter valid username to reset password" msgstr "请输入有效的用户名进行密码重置" -#: cps/web.py:1573 +#: cps/web.py:1651 #, python-format msgid "You are now logged in as: '%(nickname)s'" msgstr "您现在已以“%(nickname)s”登录" -#: cps/web.py:1639 cps/web.py:1688 +#: cps/web.py:1717 cps/web.py:1766 #, python-format msgid "%(name)s's profile" msgstr "%(name)s 的用户配置" -#: cps/web.py:1655 +#: cps/web.py:1733 msgid "Profile updated" msgstr "资料已更新" @@ -1309,36 +1331,36 @@ msgstr "资料已更新" msgid "Found no valid gmail.json file with OAuth information" msgstr "找不到包含 OAuth 信息的有效 gmail.json 文件" -#: cps/tasks/convert.py:137 +#: cps/tasks/convert.py:154 #, python-format msgid "Calibre ebook-convert %(tool)s not found" msgstr "Calibre 电子书转换器%(tool)s没有发现" -#: cps/tasks/convert.py:163 +#: cps/tasks/convert.py:187 #, python-format msgid "%(format)s format not found on disk" msgstr "硬盘上找不到 %(format)s 格式" -#: cps/tasks/convert.py:167 +#: cps/tasks/convert.py:191 msgid "Ebook converter failed with unknown error" msgstr "发生未知错误,书籍转换失败" -#: cps/tasks/convert.py:177 +#: cps/tasks/convert.py:201 #, python-format msgid "Kepubify-converter failed: %(error)s" msgstr "Kepubify 转换失败:%(error)s" -#: cps/tasks/convert.py:199 +#: cps/tasks/convert.py:223 #, python-format msgid "Converted file not found or more than one file in folder %(folder)s" msgstr "找不到转换后的文件或文件夹%(folder)s中有多个文件" -#: cps/tasks/convert.py:222 +#: cps/tasks/convert.py:246 #, python-format msgid "Ebook-converter failed: %(error)s" msgstr "电子书转换器失败: %(error)s" -#: cps/tasks/convert.py:245 +#: cps/tasks/convert.py:269 #, python-format msgid "Calibre failed with error: %(error)s" msgstr "Calibre 运行失败,错误信息:%(error)s" @@ -1393,7 +1415,7 @@ msgid "Edit" msgstr "编辑书籍" #: cps/templates/admin.html:25 cps/templates/book_edit.html:16 -#: cps/templates/book_table.html:97 cps/templates/modal_dialogs.html:63 +#: cps/templates/book_table.html:100 cps/templates/modal_dialogs.html:63 #: cps/templates/modal_dialogs.html:116 cps/templates/user_edit.html:67 #: cps/templates/user_table.html:149 msgid "Delete" @@ -1403,179 +1425,179 @@ msgstr "删除数据" msgid "Public Shelf" msgstr "公共书架" -#: cps/templates/admin.html:51 +#: cps/templates/admin.html:53 msgid "Add New User" msgstr "添加新用户" -#: cps/templates/admin.html:53 +#: cps/templates/admin.html:55 msgid "Import LDAP Users" msgstr "导入LDAP用户" -#: cps/templates/admin.html:60 +#: cps/templates/admin.html:62 msgid "E-mail Server Settings" msgstr "SMTP邮件服务器设置" -#: cps/templates/admin.html:65 cps/templates/email_edit.html:31 +#: cps/templates/admin.html:67 cps/templates/email_edit.html:31 msgid "SMTP Hostname" msgstr "SMTP主机名" -#: cps/templates/admin.html:69 cps/templates/email_edit.html:35 +#: cps/templates/admin.html:71 cps/templates/email_edit.html:35 msgid "SMTP Port" msgstr "SMTP端口" -#: cps/templates/admin.html:73 cps/templates/email_edit.html:39 +#: cps/templates/admin.html:75 cps/templates/email_edit.html:39 msgid "Encryption" msgstr "加密" -#: cps/templates/admin.html:77 cps/templates/email_edit.html:47 +#: cps/templates/admin.html:79 cps/templates/email_edit.html:47 msgid "SMTP Login" msgstr "SMTP用户名" -#: cps/templates/admin.html:81 cps/templates/admin.html:92 +#: cps/templates/admin.html:83 cps/templates/admin.html:94 #: cps/templates/email_edit.html:55 msgid "From E-mail" msgstr "发件人邮箱" -#: cps/templates/admin.html:88 +#: cps/templates/admin.html:90 msgid "E-Mail Service" msgstr "电子邮件服务" -#: cps/templates/admin.html:89 +#: cps/templates/admin.html:91 msgid "Gmail via Oauth2" msgstr "通过Oauth2的Gmail" -#: cps/templates/admin.html:104 +#: cps/templates/admin.html:106 msgid "Configuration" msgstr "配置" -#: cps/templates/admin.html:107 +#: cps/templates/admin.html:109 msgid "Calibre Database Directory" msgstr "Calibre 数据库路径" -#: cps/templates/admin.html:111 cps/templates/config_edit.html:68 +#: cps/templates/admin.html:113 cps/templates/config_edit.html:68 msgid "Log Level" msgstr "日志级别" -#: cps/templates/admin.html:115 +#: cps/templates/admin.html:117 msgid "Port" msgstr "端口" -#: cps/templates/admin.html:120 +#: cps/templates/admin.html:122 msgid "External Port" msgstr "扩展端口" -#: cps/templates/admin.html:127 cps/templates/config_view_edit.html:28 +#: cps/templates/admin.html:129 cps/templates/config_view_edit.html:28 msgid "Books per Page" msgstr "每页书籍数" -#: cps/templates/admin.html:131 +#: cps/templates/admin.html:133 msgid "Uploads" msgstr "上传" -#: cps/templates/admin.html:135 +#: cps/templates/admin.html:137 msgid "Anonymous Browsing" msgstr "匿名浏览" -#: cps/templates/admin.html:139 +#: cps/templates/admin.html:141 msgid "Public Registration" msgstr "开放注册" -#: cps/templates/admin.html:143 +#: cps/templates/admin.html:145 msgid "Magic Link Remote Login" msgstr "魔法链接远程登录" -#: cps/templates/admin.html:147 +#: cps/templates/admin.html:149 msgid "Reverse Proxy Login" msgstr "反向代理登录" -#: cps/templates/admin.html:152 cps/templates/config_edit.html:173 +#: cps/templates/admin.html:154 cps/templates/config_edit.html:173 msgid "Reverse Proxy Header Name" msgstr "反向代理头部名称" -#: cps/templates/admin.html:157 +#: cps/templates/admin.html:159 msgid "Edit Calibre Database Configuration" msgstr "编辑Calibre数据库配置" -#: cps/templates/admin.html:158 +#: cps/templates/admin.html:160 msgid "Edit Basic Configuration" msgstr "编辑基本配置" -#: cps/templates/admin.html:159 +#: cps/templates/admin.html:161 msgid "Edit UI Configuration" msgstr "编辑界面配置" -#: cps/templates/admin.html:164 +#: cps/templates/admin.html:166 msgid "Administration" msgstr "管理" -#: cps/templates/admin.html:165 +#: cps/templates/admin.html:167 msgid "Download Debug Package" msgstr "下载Debug包" -#: cps/templates/admin.html:166 +#: cps/templates/admin.html:168 msgid "View Logs" msgstr "查看日志文件" -#: cps/templates/admin.html:169 +#: cps/templates/admin.html:171 msgid "Reconnect Calibre Database" msgstr "重新连接到Calibre数据库" -#: cps/templates/admin.html:170 +#: cps/templates/admin.html:172 msgid "Restart" msgstr "重启" -#: cps/templates/admin.html:171 +#: cps/templates/admin.html:173 msgid "Shutdown" msgstr "停止" -#: cps/templates/admin.html:176 +#: cps/templates/admin.html:178 msgid "Update" msgstr "更新" -#: cps/templates/admin.html:180 +#: cps/templates/admin.html:182 msgid "Version" msgstr "版本" -#: cps/templates/admin.html:181 +#: cps/templates/admin.html:183 msgid "Details" msgstr "详情" -#: cps/templates/admin.html:187 +#: cps/templates/admin.html:189 msgid "Current version" msgstr "当前版本" -#: cps/templates/admin.html:194 +#: cps/templates/admin.html:196 msgid "Check for Update" msgstr "检查更新" -#: cps/templates/admin.html:195 +#: cps/templates/admin.html:197 msgid "Perform Update" msgstr "执行更新" -#: cps/templates/admin.html:208 +#: cps/templates/admin.html:210 msgid "Are you sure you want to restart?" msgstr "您确定要重启吗?" -#: cps/templates/admin.html:213 cps/templates/admin.html:227 -#: cps/templates/admin.html:247 cps/templates/config_db.html:70 +#: cps/templates/admin.html:215 cps/templates/admin.html:229 +#: cps/templates/admin.html:249 cps/templates/config_db.html:70 msgid "OK" msgstr "确定" -#: cps/templates/admin.html:214 cps/templates/admin.html:228 -#: cps/templates/book_edit.html:213 cps/templates/book_table.html:124 +#: cps/templates/admin.html:216 cps/templates/admin.html:230 +#: cps/templates/book_edit.html:213 cps/templates/book_table.html:127 #: cps/templates/config_db.html:54 cps/templates/config_edit.html:359 -#: cps/templates/config_view_edit.html:173 cps/templates/modal_dialogs.html:64 +#: cps/templates/config_view_edit.html:175 cps/templates/modal_dialogs.html:64 #: cps/templates/modal_dialogs.html:99 cps/templates/modal_dialogs.html:117 #: cps/templates/modal_dialogs.html:135 cps/templates/shelf_edit.html:27 #: cps/templates/user_edit.html:144 msgid "Cancel" msgstr "取消" -#: cps/templates/admin.html:226 +#: cps/templates/admin.html:228 msgid "Are you sure you want to shutdown?" msgstr "您确定要关闭吗?" -#: cps/templates/admin.html:238 +#: cps/templates/admin.html:240 msgid "Updating, please do not reload this page" msgstr "正在更新,请不要刷新页面" @@ -1587,44 +1609,43 @@ msgstr "通过" msgid "In Library" msgstr "在书库" -#: cps/templates/author.html:26 cps/templates/index.html:72 -#: cps/templates/search.html:29 cps/templates/shelf.html:19 +#: cps/templates/author.html:26 cps/templates/index.html:73 +#: cps/templates/search.html:30 cps/templates/shelf.html:19 msgid "Sort according to book date, newest first" msgstr "按图书日期排序,最新优先" -#: cps/templates/author.html:27 cps/templates/index.html:73 -#: cps/templates/search.html:30 cps/templates/shelf.html:20 +#: cps/templates/author.html:27 cps/templates/index.html:74 +#: cps/templates/search.html:31 cps/templates/shelf.html:20 msgid "Sort according to book date, oldest first" msgstr "按图书日期排序,最旧优先" -#: cps/templates/author.html:28 cps/templates/index.html:74 -#: cps/templates/search.html:31 cps/templates/shelf.html:21 +#: cps/templates/author.html:28 cps/templates/index.html:75 +#: cps/templates/search.html:32 cps/templates/shelf.html:21 msgid "Sort title in alphabetical order" msgstr "按标题按字母顺序排序" -#: cps/templates/author.html:29 cps/templates/index.html:75 -#: cps/templates/search.html:32 cps/templates/shelf.html:22 +#: cps/templates/author.html:29 cps/templates/index.html:76 +#: cps/templates/search.html:33 cps/templates/shelf.html:22 msgid "Sort title in reverse alphabetical order" msgstr "按标题逆字母顺序排序" -#: cps/templates/author.html:30 cps/templates/index.html:78 -#: cps/templates/search.html:35 cps/templates/shelf.html:25 +#: cps/templates/author.html:30 cps/templates/index.html:79 +#: cps/templates/search.html:36 cps/templates/shelf.html:25 msgid "Sort according to publishing date, newest first" msgstr "按出版日期排序,最新优先" -#: cps/templates/author.html:31 cps/templates/index.html:79 -#: cps/templates/search.html:36 cps/templates/shelf.html:26 +#: cps/templates/author.html:31 cps/templates/index.html:80 +#: cps/templates/search.html:37 cps/templates/shelf.html:26 msgid "Sort according to publishing date, oldest first" msgstr "按出版日期排序,最旧优先" -#: cps/templates/author.html:57 cps/templates/author.html:117 -#: cps/templates/discover.html:30 cps/templates/index.html:29 -#: cps/templates/index.html:111 cps/templates/search.html:65 -#: cps/templates/shelf.html:54 +#: cps/templates/author.html:56 cps/templates/author.html:115 +#: cps/templates/index.html:29 cps/templates/index.html:112 +#: cps/templates/search.html:66 cps/templates/shelf.html:54 msgid "reduce" msgstr "减少" -#: cps/templates/author.html:101 +#: cps/templates/author.html:99 msgid "More by" msgstr "更多" @@ -1749,7 +1770,7 @@ msgid "Fetch Metadata" msgstr "获取元数据" #: cps/templates/book_edit.html:212 cps/templates/config_db.html:53 -#: cps/templates/config_edit.html:358 cps/templates/config_view_edit.html:172 +#: cps/templates/config_edit.html:358 cps/templates/config_view_edit.html:174 #: cps/templates/email_edit.html:65 cps/templates/shelf_edit.html:25 #: cps/templates/shelf_order.html:41 cps/templates/user_edit.html:142 msgid "Save" @@ -1876,26 +1897,34 @@ msgstr "输入简介" msgid "Comments" msgstr "简介" -#: cps/templates/book_table.html:77 cps/templates/book_table.html:79 -#: cps/templates/book_table.html:81 cps/templates/book_table.html:83 -#: cps/templates/book_table.html:87 cps/templates/book_table.html:89 -#: cps/templates/book_table.html:91 cps/templates/book_table.html:93 +#: cps/templates/book_table.html:75 +msgid "Archiv Status" +msgstr "存档状态" + +#: cps/templates/book_table.html:77 cps/templates/search_form.html:42 +msgid "Read Status" +msgstr "阅读状态" + +#: cps/templates/book_table.html:80 cps/templates/book_table.html:82 +#: cps/templates/book_table.html:84 cps/templates/book_table.html:86 +#: cps/templates/book_table.html:90 cps/templates/book_table.html:92 +#: cps/templates/book_table.html:96 msgid "Enter " msgstr "输入" -#: cps/templates/book_table.html:110 cps/templates/modal_dialogs.html:46 +#: cps/templates/book_table.html:113 cps/templates/modal_dialogs.html:46 msgid "Are you really sure?" msgstr "您真的确认?" -#: cps/templates/book_table.html:114 +#: cps/templates/book_table.html:117 msgid "Books with Title will be merged from:" msgstr "这本书籍将被合并:" -#: cps/templates/book_table.html:118 +#: cps/templates/book_table.html:121 msgid "Into Book with Title:" msgstr "合并到这本书籍:" -#: cps/templates/book_table.html:123 +#: cps/templates/book_table.html:126 msgid "Merge" msgstr "合并" @@ -2071,11 +2100,6 @@ msgstr "LDAP服务器端口" msgid "LDAP Encryption" msgstr "LDAP 加密" -#: cps/templates/config_edit.html:204 cps/templates/config_view_edit.html:62 -#: cps/templates/email_edit.html:41 -msgid "None" -msgstr "无" - #: cps/templates/config_edit.html:205 msgid "TLS" msgstr "TLS协议" @@ -2292,11 +2316,11 @@ msgstr "新用户默认显示权限" msgid "Show Random Books in Detail View" msgstr "在主页显示随机书籍" -#: cps/templates/config_view_edit.html:165 cps/templates/user_edit.html:87 +#: cps/templates/config_view_edit.html:166 cps/templates/user_edit.html:87 msgid "Add Allowed/Denied Tags" msgstr "添加显示或隐藏书籍的标签值" -#: cps/templates/config_view_edit.html:166 +#: cps/templates/config_view_edit.html:167 msgid "Add Allowed/Denied custom column values" msgstr "添加显示或隐藏书籍的自定义栏目值" @@ -2345,13 +2369,13 @@ msgstr "归档" msgid "Description:" msgstr "简介:" -#: cps/templates/detail.html:256 cps/templates/search.html:14 +#: cps/templates/detail.html:256 cps/templates/search.html:15 msgid "Add to shelf" msgstr "添加到书架" #: cps/templates/detail.html:267 cps/templates/detail.html:284 #: cps/templates/feed.xml:79 cps/templates/layout.html:137 -#: cps/templates/search.html:20 +#: cps/templates/search.html:21 msgid "(Public)" msgstr "(公共)" @@ -2429,10 +2453,14 @@ msgstr "禁止注册的域名(黑名单)" msgid "Next" msgstr "下一个" -#: cps/templates/generate_kobo_auth_url.html:5 +#: cps/templates/generate_kobo_auth_url.html:6 msgid "Open the .kobo/Kobo eReader.conf file in a text editor and add (or edit):" msgstr "在文本编辑器中打开.kobo/Kobo eReader.conf,添加(或编辑):" +#: cps/templates/generate_kobo_auth_url.html:11 +msgid "Kobo Token:" +msgstr "Kobo Token:" + #: cps/templates/http_error.html:31 msgid "Calibre-Web Instance is unconfigured, please contact your administrator" msgstr "Calibre-Web 实例未配置,请联系您的管理员!" @@ -2449,29 +2477,29 @@ msgstr "回到首页" msgid "Logout User" msgstr "登出账号" -#: cps/templates/index.html:69 +#: cps/templates/index.html:70 msgid "Sort ascending according to download count" msgstr "按下载数排序" -#: cps/templates/index.html:70 +#: cps/templates/index.html:71 msgid "Sort descending according to download count" msgstr "按下载数逆序排序" -#: cps/templates/index.html:76 cps/templates/search.html:33 +#: cps/templates/index.html:77 cps/templates/search.html:34 #: cps/templates/shelf.html:23 msgid "Sort authors in alphabetical order" msgstr "按作者字母顺序排序" -#: cps/templates/index.html:77 cps/templates/search.html:34 +#: cps/templates/index.html:78 cps/templates/search.html:35 #: cps/templates/shelf.html:24 msgid "Sort authors in reverse alphabetical order" msgstr "按作者逆字母顺序排序" -#: cps/templates/index.html:81 +#: cps/templates/index.html:82 msgid "Sort ascending according to series index" msgstr "按丛书编号排序" -#: cps/templates/index.html:82 +#: cps/templates/index.html:83 msgid "Sort descending according to series index" msgstr "按丛书编号逆排序" @@ -2901,10 +2929,6 @@ msgstr "出版日期从" msgid "Published Date To" msgstr "出版日期到" -#: cps/templates/search_form.html:42 -msgid "Read Status" -msgstr "阅读状态" - #: cps/templates/search_form.html:59 msgid "Exclude Tags" msgstr "排除标签" @@ -3067,7 +3091,7 @@ msgstr "新建或查看" #: cps/templates/user_edit.html:70 msgid "Force full kobo sync" -msgstr "" +msgstr "强制与kobo完全同步" #: cps/templates/user_edit.html:88 msgid "Add allowed/Denied Custom Column Values" diff --git a/cps/translations/zh_Hant_TW/LC_MESSAGES/messages.mo b/cps/translations/zh_Hant_TW/LC_MESSAGES/messages.mo index 6ca6555d..4dce851c 100644 Binary files a/cps/translations/zh_Hant_TW/LC_MESSAGES/messages.mo and b/cps/translations/zh_Hant_TW/LC_MESSAGES/messages.mo differ diff --git a/cps/translations/zh_Hant_TW/LC_MESSAGES/messages.po b/cps/translations/zh_Hant_TW/LC_MESSAGES/messages.po index 8fea62e8..8f592870 100644 --- a/cps/translations/zh_Hant_TW/LC_MESSAGES/messages.po +++ b/cps/translations/zh_Hant_TW/LC_MESSAGES/messages.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Calibre-Web\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2022-01-15 09:19+0100\n" +"POT-Creation-Date: 2022-04-18 20:01+0200\n" "PO-Revision-Date: 2020-09-27 22:18+0800\n" "Last-Translator: xlivevil \n" "Language: zh_TW\n" @@ -16,580 +16,583 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.9.0\n" +"Generated-By: Babel 2.9.1\n" -#: cps/about.py:34 cps/about.py:49 cps/about.py:65 cps/converter.py:31 -msgid "not installed" -msgstr "未安裝" - -#: cps/about.py:47 cps/about.py:63 -msgid "installed" -msgstr "已安裝" - -#: cps/about.py:145 +#: cps/about.py:86 msgid "Statistics" msgstr "統計" -#: cps/admin.py:144 +#: cps/admin.py:141 msgid "Server restarted, please reload page" msgstr "服務器已重啟,請刷新頁面" -#: cps/admin.py:146 +#: cps/admin.py:143 msgid "Performing shutdown of server, please close window" msgstr "正在關閉服務器,請關閉窗口" -#: cps/admin.py:154 +#: cps/admin.py:151 msgid "Reconnect successful" msgstr "重新連接成功" -#: cps/admin.py:157 +#: cps/admin.py:154 msgid "Unknown command" msgstr "未知命令" -#: cps/admin.py:167 cps/editbooks.py:707 cps/editbooks.py:721 -#: cps/editbooks.py:866 cps/editbooks.py:868 cps/editbooks.py:895 -#: cps/editbooks.py:911 cps/updater.py:584 cps/uploader.py:93 -#: cps/uploader.py:103 +#: cps/admin.py:176 cps/editbooks.py:713 cps/editbooks.py:892 +#: cps/editbooks.py:894 cps/editbooks.py:930 cps/editbooks.py:947 +#: cps/updater.py:608 cps/uploader.py:93 cps/uploader.py:103 msgid "Unknown" msgstr "未知" -#: cps/admin.py:188 +#: cps/admin.py:197 msgid "Admin page" msgstr "管理頁" -#: cps/admin.py:207 +#: cps/admin.py:217 msgid "Basic Configuration" msgstr "基本配置" -#: cps/admin.py:244 +#: cps/admin.py:255 msgid "UI Configuration" msgstr "界面配置" -#: cps/admin.py:277 cps/templates/admin.html:50 +#: cps/admin.py:289 cps/templates/admin.html:51 msgid "Edit Users" msgstr "管理用戶" -#: cps/admin.py:318 cps/opds.py:109 cps/opds.py:198 cps/opds.py:275 -#: cps/opds.py:327 cps/templates/grid.html:13 cps/templates/languages.html:9 +#: cps/admin.py:333 cps/opds.py:529 cps/templates/grid.html:13 #: cps/templates/list.html:13 msgid "All" msgstr "全部" -#: cps/admin.py:343 cps/admin.py:1615 +#: cps/admin.py:360 cps/admin.py:1648 msgid "User not found" msgstr "找不到用戶" -#: cps/admin.py:357 +#: cps/admin.py:374 msgid "{} users deleted successfully" msgstr "成功刪除 {} 個用戶" -#: cps/admin.py:379 cps/templates/config_view_edit.html:133 +#: cps/admin.py:397 cps/templates/config_view_edit.html:133 #: cps/templates/user_edit.html:45 cps/templates/user_table.html:81 msgid "Show All" msgstr "顯示全部" -#: cps/admin.py:400 cps/admin.py:406 +#: cps/admin.py:418 cps/admin.py:424 msgid "Malformed request" msgstr "格式錯誤的請求" -#: cps/admin.py:418 cps/admin.py:1493 +#: cps/admin.py:436 cps/admin.py:1526 msgid "Guest Name can't be changed" msgstr "訪客名稱無法更改" -#: cps/admin.py:430 +#: cps/admin.py:448 msgid "Guest can't have this role" msgstr "遊客無法擁有此角色" -#: cps/admin.py:442 cps/admin.py:1451 +#: cps/admin.py:460 cps/admin.py:1484 msgid "No admin user remaining, can't remove admin role" msgstr "管理員賬戶不存在,無法刪除管理員角色" -#: cps/admin.py:446 cps/admin.py:460 +#: cps/admin.py:464 cps/admin.py:478 msgid "Value has to be true or false" msgstr "值必須是 true 或 false" -#: cps/admin.py:448 +#: cps/admin.py:466 msgid "Invalid role" msgstr "無效角色" -#: cps/admin.py:452 +#: cps/admin.py:470 msgid "Guest can't have this view" msgstr "遊客無法擁有此視圖" -#: cps/admin.py:462 +#: cps/admin.py:480 msgid "Invalid view" msgstr "無效視圖" -#: cps/admin.py:465 +#: cps/admin.py:483 msgid "Guest's Locale is determined automatically and can't be set" msgstr "訪客的本地化是自動偵測而無法設置的" -#: cps/admin.py:469 +#: cps/admin.py:487 msgid "No Valid Locale Given" msgstr "無可用本地化" -#: cps/admin.py:480 +#: cps/admin.py:498 msgid "No Valid Book Language Given" msgstr "無有效書籍語言" -#: cps/admin.py:482 +#: cps/admin.py:500 cps/editbooks.py:1267 msgid "Parameter not found" msgstr "參數未找到" -#: cps/admin.py:533 +#: cps/admin.py:553 msgid "Invalid Read Column" msgstr "無效的閱讀列" -#: cps/admin.py:539 +#: cps/admin.py:559 msgid "Invalid Restricted Column" msgstr "無效的限制列" -#: cps/admin.py:560 cps/admin.py:1323 +#: cps/admin.py:579 cps/admin.py:1355 msgid "Calibre-Web configuration updated" msgstr "Calibre-Web配置已更新" -#: cps/admin.py:572 +#: cps/admin.py:591 msgid "Do you really want to delete the Kobo Token?" msgstr "您確定刪除Kobo Token嗎?" -#: cps/admin.py:574 +#: cps/admin.py:593 msgid "Do you really want to delete this domain?" msgstr "您確定要刪除此網域嗎?" -#: cps/admin.py:576 +#: cps/admin.py:595 msgid "Do you really want to delete this user?" msgstr "您確定要刪除此用戶嗎?" -#: cps/admin.py:578 +#: cps/admin.py:597 msgid "Are you sure you want to delete this shelf?" msgstr "您確定要刪除此書架嗎?" -#: cps/admin.py:580 +#: cps/admin.py:599 msgid "Are you sure you want to change locales of selected user(s)?" msgstr "您確定要修改選定用戶的本地化設置嗎?" -#: cps/admin.py:582 +#: cps/admin.py:601 msgid "Are you sure you want to change visible book languages for selected user(s)?" msgstr "您確定要修改選定用戶的可見書籍語言嗎?" -#: cps/admin.py:584 +#: cps/admin.py:603 msgid "Are you sure you want to change the selected role for the selected user(s)?" msgstr "您確定要修改選定用戶的選定角色嗎?" -#: cps/admin.py:586 +#: cps/admin.py:605 msgid "Are you sure you want to change the selected restrictions for the selected user(s)?" msgstr "您確定要修改選定用戶的選定限制嗎?" -#: cps/admin.py:588 +#: cps/admin.py:607 msgid "Are you sure you want to change the selected visibility restrictions for the selected user(s)?" msgstr "您確定要修改選定用戶的選定可視化限制嗎?" -#: cps/admin.py:590 +#: cps/admin.py:610 msgid "Are you sure you want to change shelf sync behavior for the selected user(s)?" msgstr "您確定要更改所選用戶的書架同步行為嗎?" -#: cps/admin.py:592 +#: cps/admin.py:612 msgid "Are you sure you want to change Calibre library location?" msgstr "您確定要更改 Calibre 庫位置嗎?" -#: cps/admin.py:594 +#: cps/admin.py:614 msgid "Are you sure you want delete Calibre-Web's sync database to force a full sync with your Kobo Reader?" msgstr "" -#: cps/admin.py:743 +#: cps/admin.py:764 msgid "Tag not found" msgstr "標籤未找到" -#: cps/admin.py:755 +#: cps/admin.py:776 msgid "Invalid Action" msgstr "無效的動作" -#: cps/admin.py:871 cps/admin.py:877 cps/admin.py:887 cps/admin.py:897 +#: cps/admin.py:893 cps/admin.py:899 cps/admin.py:909 cps/admin.py:919 #: cps/templates/modal_dialogs.html:29 cps/templates/user_table.html:41 #: cps/templates/user_table.html:58 msgid "Deny" msgstr "拒絕" -#: cps/admin.py:873 cps/admin.py:879 cps/admin.py:889 cps/admin.py:899 +#: cps/admin.py:895 cps/admin.py:901 cps/admin.py:911 cps/admin.py:921 #: cps/templates/modal_dialogs.html:28 cps/templates/user_table.html:44 #: cps/templates/user_table.html:61 msgid "Allow" msgstr "允許" -#: cps/admin.py:913 +#: cps/admin.py:936 msgid "{} sync entries deleted" msgstr "" -#: cps/admin.py:1036 +#: cps/admin.py:1059 msgid "client_secrets.json Is Not Configured For Web Application" msgstr "client_secrets.json 未為 Web 應用程序配置" -#: cps/admin.py:1081 +#: cps/admin.py:1104 msgid "Logfile Location is not Valid, Please Enter Correct Path" msgstr "日誌文件路徑無效,請輸入正確的路徑" -#: cps/admin.py:1087 +#: cps/admin.py:1110 msgid "Access Logfile Location is not Valid, Please Enter Correct Path" msgstr "訪問日誌路徑無效,請輸入正確的路徑" -#: cps/admin.py:1117 +#: cps/admin.py:1140 msgid "Please Enter a LDAP Provider, Port, DN and User Object Identifier" msgstr "請輸入LDAP主機、端口、DN和用戶對象標識符" -#: cps/admin.py:1123 +#: cps/admin.py:1146 msgid "Please Enter a LDAP Service Account and Password" msgstr "請輸入一個LDAP服務賬號和密碼 " -#: cps/admin.py:1126 +#: cps/admin.py:1149 msgid "Please Enter a LDAP Service Account" msgstr "請輸入一個LDAP服務賬號" -#: cps/admin.py:1131 +#: cps/admin.py:1154 #, python-format msgid "LDAP Group Object Filter Needs to Have One \"%s\" Format Identifier" msgstr "LDAP群組對象過濾器需要一個具有“%s”格式標識符號" -#: cps/admin.py:1133 +#: cps/admin.py:1156 msgid "LDAP Group Object Filter Has Unmatched Parenthesis" msgstr "LDAP群組對象過濾器的括號不匹配" -#: cps/admin.py:1137 +#: cps/admin.py:1160 #, python-format msgid "LDAP User Object Filter needs to Have One \"%s\" Format Identifier" msgstr "LDAP用戶對象過濾器需要一個具有“%s”格式標識符" -#: cps/admin.py:1139 +#: cps/admin.py:1162 msgid "LDAP User Object Filter Has Unmatched Parenthesis" msgstr "LDAP用戶對象過濾器的括號不匹配" -#: cps/admin.py:1146 +#: cps/admin.py:1169 #, python-format msgid "LDAP Member User Filter needs to Have One \"%s\" Format Identifier" msgstr "LDAP成員用戶過濾器需要有一個“%s”格式標識符號" -#: cps/admin.py:1148 +#: cps/admin.py:1171 msgid "LDAP Member User Filter Has Unmatched Parenthesis" msgstr "LDAP成員用戶過濾器中有不匹配的括號" -#: cps/admin.py:1155 +#: cps/admin.py:1178 msgid "LDAP CACertificate, Certificate or Key Location is not Valid, Please Enter Correct Path" msgstr "LDAP CA證書、證書或密鑰位置無效,請輸入正確的路徑" -#: cps/admin.py:1197 cps/admin.py:1308 cps/admin.py:1405 cps/admin.py:1521 -#: cps/admin.py:1590 cps/shelf.py:100 cps/shelf.py:160 cps/shelf.py:203 -#: cps/shelf.py:279 cps/shelf.py:341 cps/shelf.py:376 cps/shelf.py:451 -msgid "Settings DB is not Writeable" -msgstr "設置數據庫不可寫入" - -#: cps/admin.py:1208 -msgid "DB Location is not Valid, Please Enter Correct Path" -msgstr "數據庫路徑無效,請輸入正確的路徑" - -#: cps/admin.py:1223 -msgid "DB is not Writeable" -msgstr "數據庫不可寫入" - -#: cps/admin.py:1235 -msgid "Keyfile Location is not Valid, Please Enter Correct Path" -msgstr "密鑰文件路徑無效,請輸入正確的路徑" - -#: cps/admin.py:1239 -msgid "Certfile Location is not Valid, Please Enter Correct Path" -msgstr "證書文件路徑無效,請輸入正確的路徑" - -#: cps/admin.py:1346 -#, fuzzy -msgid "Database Settings updated" -msgstr "郵件服務器設置已更新" - -#: cps/admin.py:1354 -msgid "Database Configuration" -msgstr "數據庫配置" - -#: cps/admin.py:1370 cps/web.py:1479 -msgid "Please fill out all fields!" -msgstr "請填寫所有欄位!" - -#: cps/admin.py:1378 -msgid "E-mail is not from valid domain" -msgstr "郵箱不在有效網域中" - -#: cps/admin.py:1384 cps/admin.py:1543 -msgid "Add new user" -msgstr "添加新用戶" - -#: cps/admin.py:1395 -#, python-format -msgid "User '%(user)s' created" -msgstr "用戶“%(user)s”已創建" - -#: cps/admin.py:1401 -msgid "Found an existing account for this e-mail address or name." -msgstr "使用此郵箱或用戶名的賬號已經存在。" - -#: cps/admin.py:1430 -#, python-format -msgid "User '%(nick)s' deleted" -msgstr "用戶“%(nick)s”已刪除" - -#: cps/admin.py:1432 cps/admin.py:1433 -msgid "Can't delete Guest User" -msgstr "無法刪除訪客用戶" - -#: cps/admin.py:1436 -msgid "No admin user remaining, can't delete user" -msgstr "管理員賬戶不存在,無法刪除用戶" - -#: cps/admin.py:1509 cps/admin.py:1634 -#, python-format -msgid "Edit User %(nick)s" -msgstr "編輯用戶 %(nick)s" - -#: cps/admin.py:1513 -#, python-format -msgid "User '%(nick)s' updated" -msgstr "用戶“%(nick)s”已更新" - -#: cps/admin.py:1517 cps/admin.py:1649 cps/web.py:1504 cps/web.py:1564 -msgid "An unknown error occurred. Please try again later." -msgstr "發生一個未知錯誤,請稍後再試。" - -#: cps/admin.py:1552 cps/templates/admin.html:98 -msgid "Edit E-mail Server Settings" -msgstr "編輯郵件服務器設置" - -#: cps/admin.py:1571 -msgid "Gmail Account Verification Successful" -msgstr "G-Mail賬號驗證成功" - -#: cps/admin.py:1597 -#, python-format -msgid "Test e-mail queued for sending to %(email)s, please check Tasks for result" -msgstr "發送給%(email)s的測試郵件已進入隊列。請檢查任務結果" - -#: cps/admin.py:1600 -#, python-format -msgid "There was an error sending the Test e-mail: %(res)s" -msgstr "發送測試郵件時出錯:%(res)s" - -#: cps/admin.py:1602 -msgid "Please configure your e-mail address first..." -msgstr "請先配置您的郵箱地址..." - -#: cps/admin.py:1604 -msgid "E-mail server settings updated" -msgstr "郵件服務器設置已更新" - -#: cps/admin.py:1646 -#, python-format -msgid "Password for user %(user)s reset" -msgstr "用戶 %(user)s 的密碼已重置" - -#: cps/admin.py:1652 cps/web.py:1444 -msgid "Please configure the SMTP mail settings first..." -msgstr "請先配置SMTP郵箱設置..." - -#: cps/admin.py:1663 -msgid "Logfile viewer" -msgstr "日誌文件查看器" - -#: cps/admin.py:1729 -msgid "Requesting update package" -msgstr "正在請求更新包" - -#: cps/admin.py:1730 -msgid "Downloading update package" -msgstr "正在下載更新包" - -#: cps/admin.py:1731 -msgid "Unzipping update package" -msgstr "正在解壓更新包" - -#: cps/admin.py:1732 -msgid "Replacing files" -msgstr "正在替換文件" - -#: cps/admin.py:1733 -msgid "Database connections are closed" -msgstr "數據庫連接已關閉" - -#: cps/admin.py:1734 -msgid "Stopping server" -msgstr "正在停止服務器" - -#: cps/admin.py:1735 -msgid "Update finished, please press okay and reload page" -msgstr "更新完成,請點擊確定並刷新頁面" - -#: cps/admin.py:1736 cps/admin.py:1737 cps/admin.py:1738 cps/admin.py:1739 -#: cps/admin.py:1740 cps/admin.py:1741 -msgid "Update failed:" -msgstr "更新失敗:" - -#: cps/admin.py:1736 cps/updater.py:385 cps/updater.py:595 cps/updater.py:597 -msgid "HTTP Error" -msgstr "HTTP錯誤" - -#: cps/admin.py:1737 cps/updater.py:387 cps/updater.py:599 -msgid "Connection error" -msgstr "連接錯誤" - -#: cps/admin.py:1738 cps/updater.py:389 cps/updater.py:601 -msgid "Timeout while establishing connection" -msgstr "建立連接超時" - -#: cps/admin.py:1739 cps/updater.py:391 cps/updater.py:603 -msgid "General error" -msgstr "一般錯誤" - -#: cps/admin.py:1740 -#, fuzzy -msgid "Update file could not be saved in temp dir" -msgstr "更新文件無法保存在臨時目錄中" - -#: cps/admin.py:1741 -msgid "Files could not be replaced during update" -msgstr "更新時檔案無法替換變更" - -#: cps/admin.py:1765 -msgid "Failed to extract at least One LDAP User" -msgstr "未能提取至少一個LDAP用戶" - -#: cps/admin.py:1810 -msgid "Failed to Create at Least One LDAP User" -msgstr "未能創建至少一個LDAP用戶" - -#: cps/admin.py:1823 -#, python-format -msgid "Error: %(ldaperror)s" -msgstr "錯誤:%(ldaperror)s" - -#: cps/admin.py:1827 -msgid "Error: No user returned in response of LDAP server" -msgstr "錯誤:在LDAP服務器的響應中沒有返回用戶" - -#: cps/admin.py:1860 -msgid "At Least One LDAP User Not Found in Database" -msgstr "數據庫中沒有找到至少一個LDAP用戶" - -#: cps/admin.py:1862 -msgid "{} User Successfully Imported" -msgstr "{} 用戶被成功導入" - -#: cps/converter.py:30 -msgid "not configured" -msgstr "未配置" - -#: cps/converter.py:32 -msgid "Execution permissions missing" -msgstr "缺少執行權限" - -#: cps/db.py:651 cps/web.py:667 cps/web.py:1155 -#, python-format -msgid "Custom Column No.%(column)d is not existing in calibre database" -msgstr "自定義列號:%(column)d在Calibre數據庫中不存在" - -#: cps/editbooks.py:300 cps/editbooks.py:302 -msgid "Book Format Successfully Deleted" -msgstr "書籍格式已成功刪除" - -#: cps/editbooks.py:309 cps/editbooks.py:311 -msgid "Book Successfully Deleted" -msgstr "書籍已成功刪除" - -#: cps/editbooks.py:361 -msgid "You are missing permissions to delete books" -msgstr "" - -#: cps/editbooks.py:376 cps/editbooks.py:763 cps/web.py:523 cps/web.py:1703 -#: cps/web.py:1744 cps/web.py:1811 -msgid "Oops! Selected book title is unavailable. File does not exist or is not accessible" -msgstr "糟糕!選擇書名無法打開。文件不存在或者文件不可訪問" - -#: cps/editbooks.py:410 -msgid "edit metadata" -msgstr "編輯元數據" - -#: cps/editbooks.py:458 -#, python-format -msgid "%(seriesindex)s is not a valid number, skipping" -msgstr "%(seriesindex)s 不是一個有效的數值,忽略" - -#: cps/editbooks.py:494 cps/editbooks.py:958 -#, fuzzy, python-format -msgid "'%(langname)s' is not a valid language" -msgstr "%(langname)s 不是一種有效語言" - -#: cps/editbooks.py:634 cps/editbooks.py:985 -#, python-format -msgid "File extension '%(ext)s' is not allowed to be uploaded to this server" -msgstr "不能上傳文件附檔名為“%(ext)s”的文件到此服務器" - -#: cps/editbooks.py:638 cps/editbooks.py:989 -msgid "File to be uploaded must have an extension" -msgstr "要上傳的文件必須具有附檔名" - -#: cps/editbooks.py:650 -#, python-format -msgid "Failed to create path %(path)s (Permission denied)." -msgstr "創建路徑 %(path)s 失敗(權限拒絕)。" - -#: cps/editbooks.py:655 -#, python-format -msgid "Failed to store file %(file)s." -msgstr "保存文件 %(file)s 失敗。" - -#: cps/editbooks.py:673 cps/editbooks.py:1076 cps/web.py:1664 +#: cps/admin.py:1223 cps/admin.py:1339 cps/admin.py:1437 cps/admin.py:1554 +#: cps/admin.py:1623 cps/editbooks.py:678 cps/editbooks.py:882 +#: cps/editbooks.py:1130 cps/shelf.py:100 cps/shelf.py:160 cps/shelf.py:203 +#: cps/shelf.py:278 cps/shelf.py:343 cps/shelf.py:380 cps/shelf.py:456 +#: cps/web.py:1742 #, python-format msgid "Database error: %(error)s." msgstr "數據庫錯誤:%(error)s。" -#: cps/editbooks.py:678 +#: cps/admin.py:1235 +msgid "DB Location is not Valid, Please Enter Correct Path" +msgstr "數據庫路徑無效,請輸入正確的路徑" + +#: cps/admin.py:1253 +msgid "DB is not Writeable" +msgstr "數據庫不可寫入" + +#: cps/admin.py:1266 +msgid "Keyfile Location is not Valid, Please Enter Correct Path" +msgstr "密鑰文件路徑無效,請輸入正確的路徑" + +#: cps/admin.py:1270 +msgid "Certfile Location is not Valid, Please Enter Correct Path" +msgstr "證書文件路徑無效,請輸入正確的路徑" + +#: cps/admin.py:1378 +#, fuzzy +msgid "Database Settings updated" +msgstr "郵件服務器設置已更新" + +#: cps/admin.py:1386 +msgid "Database Configuration" +msgstr "數據庫配置" + +#: cps/admin.py:1402 cps/web.py:1557 +msgid "Please fill out all fields!" +msgstr "請填寫所有欄位!" + +#: cps/admin.py:1410 +msgid "E-mail is not from valid domain" +msgstr "郵箱不在有效網域中" + +#: cps/admin.py:1416 cps/admin.py:1576 +msgid "Add new user" +msgstr "添加新用戶" + +#: cps/admin.py:1427 +#, python-format +msgid "User '%(user)s' created" +msgstr "用戶“%(user)s”已創建" + +#: cps/admin.py:1433 +msgid "Found an existing account for this e-mail address or name." +msgstr "使用此郵箱或用戶名的賬號已經存在。" + +#: cps/admin.py:1463 +#, python-format +msgid "User '%(nick)s' deleted" +msgstr "用戶“%(nick)s”已刪除" + +#: cps/admin.py:1465 cps/admin.py:1466 +msgid "Can't delete Guest User" +msgstr "無法刪除訪客用戶" + +#: cps/admin.py:1469 +msgid "No admin user remaining, can't delete user" +msgstr "管理員賬戶不存在,無法刪除用戶" + +#: cps/admin.py:1542 cps/admin.py:1667 +#, python-format +msgid "Edit User %(nick)s" +msgstr "編輯用戶 %(nick)s" + +#: cps/admin.py:1546 +#, python-format +msgid "User '%(nick)s' updated" +msgstr "用戶“%(nick)s”已更新" + +#: cps/admin.py:1550 cps/admin.py:1682 cps/web.py:1582 cps/web.py:1642 +msgid "An unknown error occurred. Please try again later." +msgstr "發生一個未知錯誤,請稍後再試。" + +#: cps/admin.py:1585 cps/templates/admin.html:100 +msgid "Edit E-mail Server Settings" +msgstr "編輯郵件服務器設置" + +#: cps/admin.py:1604 +msgid "Gmail Account Verification Successful" +msgstr "G-Mail賬號驗證成功" + +#: cps/admin.py:1630 +#, python-format +msgid "Test e-mail queued for sending to %(email)s, please check Tasks for result" +msgstr "發送給%(email)s的測試郵件已進入隊列。請檢查任務結果" + +#: cps/admin.py:1633 +#, python-format +msgid "There was an error sending the Test e-mail: %(res)s" +msgstr "發送測試郵件時出錯:%(res)s" + +#: cps/admin.py:1635 +msgid "Please configure your e-mail address first..." +msgstr "請先配置您的郵箱地址..." + +#: cps/admin.py:1637 +msgid "E-mail server settings updated" +msgstr "郵件服務器設置已更新" + +#: cps/admin.py:1679 +#, python-format +msgid "Password for user %(user)s reset" +msgstr "用戶 %(user)s 的密碼已重置" + +#: cps/admin.py:1685 cps/web.py:1522 +msgid "Please configure the SMTP mail settings first..." +msgstr "請先配置SMTP郵箱設置..." + +#: cps/admin.py:1696 +msgid "Logfile viewer" +msgstr "日誌文件查看器" + +#: cps/admin.py:1762 +msgid "Requesting update package" +msgstr "正在請求更新包" + +#: cps/admin.py:1763 +msgid "Downloading update package" +msgstr "正在下載更新包" + +#: cps/admin.py:1764 +msgid "Unzipping update package" +msgstr "正在解壓更新包" + +#: cps/admin.py:1765 +msgid "Replacing files" +msgstr "正在替換文件" + +#: cps/admin.py:1766 +msgid "Database connections are closed" +msgstr "數據庫連接已關閉" + +#: cps/admin.py:1767 +msgid "Stopping server" +msgstr "正在停止服務器" + +#: cps/admin.py:1768 +msgid "Update finished, please press okay and reload page" +msgstr "更新完成,請點擊確定並刷新頁面" + +#: cps/admin.py:1769 cps/admin.py:1770 cps/admin.py:1771 cps/admin.py:1772 +#: cps/admin.py:1773 cps/admin.py:1774 +msgid "Update failed:" +msgstr "更新失敗:" + +#: cps/admin.py:1769 cps/updater.py:384 cps/updater.py:619 cps/updater.py:621 +msgid "HTTP Error" +msgstr "HTTP錯誤" + +#: cps/admin.py:1770 cps/updater.py:386 cps/updater.py:623 +msgid "Connection error" +msgstr "連接錯誤" + +#: cps/admin.py:1771 cps/updater.py:388 cps/updater.py:625 +msgid "Timeout while establishing connection" +msgstr "建立連接超時" + +#: cps/admin.py:1772 cps/updater.py:390 cps/updater.py:627 +msgid "General error" +msgstr "一般錯誤" + +#: cps/admin.py:1773 +#, fuzzy +msgid "Update file could not be saved in temp dir" +msgstr "更新文件無法保存在臨時目錄中" + +#: cps/admin.py:1774 +msgid "Files could not be replaced during update" +msgstr "更新時檔案無法替換變更" + +#: cps/admin.py:1798 +msgid "Failed to extract at least One LDAP User" +msgstr "未能提取至少一個LDAP用戶" + +#: cps/admin.py:1843 +msgid "Failed to Create at Least One LDAP User" +msgstr "未能創建至少一個LDAP用戶" + +#: cps/admin.py:1856 +#, python-format +msgid "Error: %(ldaperror)s" +msgstr "錯誤:%(ldaperror)s" + +#: cps/admin.py:1860 +msgid "Error: No user returned in response of LDAP server" +msgstr "錯誤:在LDAP服務器的響應中沒有返回用戶" + +#: cps/admin.py:1893 +msgid "At Least One LDAP User Not Found in Database" +msgstr "數據庫中沒有找到至少一個LDAP用戶" + +#: cps/admin.py:1895 +msgid "{} User Successfully Imported" +msgstr "{} 用戶被成功導入" + +#: cps/converter.py:30 +msgid "not installed" +msgstr "未安裝" + +#: cps/converter.py:31 +msgid "Execution permissions missing" +msgstr "缺少執行權限" + +#: cps/db.py:674 cps/web.py:710 cps/web.py:1222 +#, python-format +msgid "Custom Column No.%(column)d is not existing in calibre database" +msgstr "自定義列號:%(column)d在Calibre數據庫中不存在" + +#: cps/db.py:917 cps/templates/config_edit.html:204 +#: cps/templates/config_view_edit.html:62 cps/templates/email_edit.html:41 +#: cps/web.py:551 cps/web.py:585 cps/web.py:646 cps/web.py:671 cps/web.py:1003 +#: cps/web.py:1032 cps/web.py:1066 cps/web.py:1093 cps/web.py:1132 +msgid "None" +msgstr "無" + +#: cps/editbooks.py:295 cps/editbooks.py:297 +msgid "Book Format Successfully Deleted" +msgstr "書籍格式已成功刪除" + +#: cps/editbooks.py:304 cps/editbooks.py:306 +msgid "Book Successfully Deleted" +msgstr "書籍已成功刪除" + +#: cps/editbooks.py:358 +msgid "You are missing permissions to delete books" +msgstr "" + +#: cps/editbooks.py:373 cps/editbooks.py:765 cps/web.py:518 cps/web.py:1783 +#: cps/web.py:1825 cps/web.py:1870 +msgid "Oops! Selected book title is unavailable. File does not exist or is not accessible" +msgstr "糟糕!選擇書名無法打開。文件不存在或者文件不可訪問" + +#: cps/editbooks.py:408 +msgid "edit metadata" +msgstr "編輯元數據" + +#: cps/editbooks.py:457 +#, python-format +msgid "%(seriesindex)s is not a valid number, skipping" +msgstr "%(seriesindex)s 不是一個有效的數值,忽略" + +#: cps/editbooks.py:493 cps/editbooks.py:1001 +#, fuzzy, python-format +msgid "'%(langname)s' is not a valid language" +msgstr "%(langname)s 不是一種有效語言" + +#: cps/editbooks.py:634 +msgid "User has no rights to upload additional file formats" +msgstr "" + +#: cps/editbooks.py:639 cps/editbooks.py:1029 +#, python-format +msgid "File extension '%(ext)s' is not allowed to be uploaded to this server" +msgstr "不能上傳文件附檔名為“%(ext)s”的文件到此服務器" + +#: cps/editbooks.py:643 cps/editbooks.py:1033 +msgid "File to be uploaded must have an extension" +msgstr "要上傳的文件必須具有附檔名" + +#: cps/editbooks.py:655 +#, python-format +msgid "Failed to create path %(path)s (Permission denied)." +msgstr "創建路徑 %(path)s 失敗(權限拒絕)。" + +#: cps/editbooks.py:660 +#, python-format +msgid "Failed to store file %(file)s." +msgstr "保存文件 %(file)s 失敗。" + +#: cps/editbooks.py:683 #, python-format msgid "File format %(ext)s added to %(book)s" msgstr "已添加 %(ext)s 格式到 %(book)s" -#: cps/editbooks.py:814 +#: cps/editbooks.py:697 cps/editbooks.py:809 +msgid "User has no rights to upload cover" +msgstr "" + +#: cps/editbooks.py:828 msgid "Identifiers are not Case Sensitive, Overwriting Old Identifier" msgstr "標識符不區分大小寫,覆蓋舊標識符" -#: cps/editbooks.py:848 +#: cps/editbooks.py:869 msgid "Metadata successfully updated" msgstr "已成功更新元數據" -#: cps/editbooks.py:861 -msgid "Error editing book, please check logfile for details" -msgstr "編輯書籍出錯,請檢查日誌文件以獲取詳細信息" +#: cps/editbooks.py:887 +msgid "Error editing book: {}" +msgstr "" -#: cps/editbooks.py:899 +#: cps/editbooks.py:951 msgid "Uploaded book probably exists in the library, consider to change before upload new: " msgstr "上傳的書籍可能已經存在,建議修改後重新上傳: " -#: cps/editbooks.py:997 +#: cps/editbooks.py:1041 #, python-format msgid "File %(filename)s could not saved to temp dir" msgstr "文件 %(filename)s 無法保存到臨時目錄" -#: cps/editbooks.py:1016 +#: cps/editbooks.py:1061 #, python-format msgid "Failed to Move Cover File %(file)s: %(error)s" msgstr "移動封面文件失敗 %(file)s:%(error)s" -#: cps/editbooks.py:1063 +#: cps/editbooks.py:1117 #, python-format msgid "File %(file)s uploaded" msgstr "文件 %(file)s 已上傳" -#: cps/editbooks.py:1088 +#: cps/editbooks.py:1143 msgid "Source or destination format for conversion missing" msgstr "轉換的來源或目的格式不存在" -#: cps/editbooks.py:1096 +#: cps/editbooks.py:1151 #, python-format msgid "Book successfully queued for converting to %(book_format)s" msgstr "書籍已經被成功加入到 %(book_format)s 格式轉換隊列" -#: cps/editbooks.py:1100 +#: cps/editbooks.py:1155 #, python-format msgid "There was an error converting this book: %(res)s" msgstr "轉換此書籍時出現錯誤: %(res)s" @@ -602,174 +605,191 @@ msgstr "Google Drive 設置未完成,請嘗試停用並再次激活Google雲 msgid "Callback domain is not verified, please follow steps to verify domain in google developer console" msgstr "回調網域名稱尚未被驗證,請在google開發者控制台按步驟驗證網域名稱" -#: cps/helper.py:77 +#: cps/helper.py:81 #, python-format msgid "%(format)s format not found for book id: %(book)d" msgstr "找不到id為 %(book)d 的書籍的 %(format)s 格式" -#: cps/helper.py:83 cps/tasks/convert.py:73 +#: cps/helper.py:87 cps/tasks/convert.py:75 #, python-format msgid "%(format)s not found on Google Drive: %(fn)s" msgstr "Google Drive %(fn)s 上找不到 %(format)s" -#: cps/helper.py:88 +#: cps/helper.py:92 #, python-format msgid "%(format)s not found: %(fn)s" msgstr "找不到 %(format)s:%(fn)s" -#: cps/helper.py:93 cps/helper.py:217 cps/templates/detail.html:41 +#: cps/helper.py:97 cps/helper.py:221 cps/templates/detail.html:41 #: cps/templates/detail.html:45 msgid "Send to Kindle" msgstr "發送到Kindle" -#: cps/helper.py:94 cps/helper.py:111 cps/helper.py:219 +#: cps/helper.py:98 cps/helper.py:115 cps/helper.py:223 msgid "This e-mail has been sent via Calibre-Web." msgstr "此郵件已經通過Calibre-Web發送。" -#: cps/helper.py:109 +#: cps/helper.py:113 msgid "Calibre-Web test e-mail" msgstr "Calibre-Web測試郵件" -#: cps/helper.py:110 +#: cps/helper.py:114 msgid "Test e-mail" msgstr "測試郵件" -#: cps/helper.py:127 +#: cps/helper.py:131 msgid "Get Started with Calibre-Web" msgstr "開啟Calibre-Web之旅" -#: cps/helper.py:132 +#: cps/helper.py:136 #, python-format msgid "Registration e-mail for user: %(name)s" msgstr "用戶註冊電子郵件:%(name)s" -#: cps/helper.py:143 cps/helper.py:149 +#: cps/helper.py:147 cps/helper.py:153 #, python-format msgid "Convert %(orig)s to %(format)s and send to Kindle" msgstr "轉換 %(orig)s 到 %(format)s 並發送到Kindle" -#: cps/helper.py:168 cps/helper.py:172 cps/helper.py:176 +#: cps/helper.py:172 cps/helper.py:176 cps/helper.py:180 #, python-format msgid "Send %(format)s to Kindle" msgstr "發送 %(format)s 到Kindle" -#: cps/helper.py:216 cps/tasks/convert.py:90 +#: cps/helper.py:220 cps/tasks/convert.py:92 #, python-format msgid "%(book)s send to Kindle" msgstr "%(book)s發送到Kindle" -#: cps/helper.py:221 +#: cps/helper.py:225 msgid "The requested file could not be read. Maybe wrong permissions?" msgstr "無法讀取請求的文件。可能有錯誤的權限設置?" -#: cps/helper.py:313 +#: cps/helper.py:353 +msgid "Read status could not set: {}" +msgstr "" + +#: cps/helper.py:376 #, python-format msgid "Deleting bookfolder for book %(id)s failed, path has subfolders: %(path)s" msgstr "刪除書的文件夾%(id)s失敗,路徑有子文件夾:%(path)s" -#: cps/helper.py:319 +#: cps/helper.py:382 #, python-format msgid "Deleting book %(id)s failed: %(message)s" msgstr "刪除書籍 %(id)s失敗:%(message)s" -#: cps/helper.py:330 +#: cps/helper.py:393 #, python-format msgid "Deleting book %(id)s from database only, book path in database not valid: %(path)s" msgstr "僅從數據庫中刪除書籍 %(id)s,數據庫中的書籍路徑無效: %(path)s" -#: cps/helper.py:385 -#, python-format -msgid "Rename title from: '%(src)s' to '%(dest)s' failed with error: %(error)s" +#: cps/helper.py:458 +#, fuzzy, python-format +msgid "Rename author from: '%(src)s' to '%(dest)s' failed with error: %(error)s" msgstr "將標題從“%(src)s”改為“%(dest)s”時失敗,錯誤錯信息:%(error)s" -#: cps/helper.py:400 -#, python-format -msgid "Rename file in path '%(src)s' to '%(dest)s' failed with error: %(error)s" -msgstr "從“%(src)s”重命名為“%(dest)s”失敗,錯誤信息:%(error)s" - -#: cps/helper.py:425 cps/helper.py:435 cps/helper.py:443 +#: cps/helper.py:529 cps/helper.py:538 #, python-format msgid "File %(file)s not found on Google Drive" msgstr "Google Drive上找不到文件 %(file)s" -#: cps/helper.py:464 +#: cps/helper.py:572 +#, python-format +msgid "Rename title from: '%(src)s' to '%(dest)s' failed with error: %(error)s" +msgstr "將標題從“%(src)s”改為“%(dest)s”時失敗,錯誤錯信息:%(error)s" + +#: cps/helper.py:592 +msgid "Error in rename file in path: {}" +msgstr "" + +#: cps/helper.py:610 #, python-format msgid "Book path %(path)s not found on Google Drive" msgstr "Google Drive上找不到書籍路徑 %(path)s" -#: cps/helper.py:504 cps/web.py:1659 +#: cps/helper.py:651 cps/web.py:1737 msgid "Found an existing account for this e-mail address" msgstr "使用此郵箱的賬號已經存在。" -#: cps/helper.py:512 +#: cps/helper.py:659 msgid "This username is already taken" msgstr "此用戶名已被使用" -#: cps/helper.py:522 +#: cps/helper.py:669 msgid "Invalid e-mail address format" msgstr "無效的郵件地址格式" -#: cps/helper.py:595 +#: cps/helper.py:754 +msgid "Python modul 'advocate' is not installed but is needed for cover downloads" +msgstr "" + +#: cps/helper.py:767 msgid "Error Downloading Cover" msgstr "下載封面時出錯" -#: cps/helper.py:598 +#: cps/helper.py:770 msgid "Cover Format Error" msgstr "封面格式出錯" -#: cps/helper.py:608 +#: cps/helper.py:773 +msgid "You are not allowed to access localhost or the local network for cover uploads" +msgstr "" + +#: cps/helper.py:783 msgid "Failed to create path for cover" msgstr "創建封面路徑失敗" -#: cps/helper.py:624 +#: cps/helper.py:799 msgid "Cover-file is not a valid image file, or could not be stored" msgstr "封面文件不是有效的圖片文件,或者無法儲存" -#: cps/helper.py:635 +#: cps/helper.py:810 msgid "Only jpg/jpeg/png/webp/bmp files are supported as coverfile" msgstr "封面文件只支持jpg/jpeg/png/webp/bmp格式文件" -#: cps/helper.py:648 +#: cps/helper.py:822 msgid "Invalid cover file content" msgstr "" -#: cps/helper.py:652 +#: cps/helper.py:826 msgid "Only jpg/jpeg files are supported as coverfile" msgstr "僅將jpg、jpeg文件作為封面文件" -#: cps/helper.py:704 +#: cps/helper.py:878 msgid "Unrar binary file not found" msgstr "找不到Unrar執行文件" -#: cps/helper.py:715 +#: cps/helper.py:889 msgid "Error excecuting UnRar" msgstr "執行UnRar時出錯" -#: cps/helper.py:763 +#: cps/helper.py:937 msgid "Waiting" msgstr "等待中" -#: cps/helper.py:765 +#: cps/helper.py:939 msgid "Failed" msgstr "失敗" -#: cps/helper.py:767 +#: cps/helper.py:941 msgid "Started" msgstr "已開始" -#: cps/helper.py:769 +#: cps/helper.py:943 msgid "Finished" msgstr "已完成" -#: cps/helper.py:771 +#: cps/helper.py:945 msgid "Unknown Status" msgstr "未知狀態" -#: cps/kobo_auth.py:127 -msgid "PLease access calibre-web from non localhost to get valid api_endpoint for kobo device" +#: cps/kobo_auth.py:128 +#, fuzzy +msgid "Please access Calibre-Web from non localhost to get valid api_endpoint for kobo device" msgstr "請不要使用localhost訪問Calibre-Web,以便Kobo設備能獲取有效的api_endpoint" -#: cps/kobo_auth.py:130 cps/kobo_auth.py:158 +#: cps/kobo_auth.py:154 msgid "Kobo Setup" msgstr "Kobo 設置" @@ -778,7 +798,7 @@ msgstr "Kobo 設置" msgid "Register with %(provider)s" msgstr "使用 %(provider)s 註冊" -#: cps/oauth_bb.py:138 cps/remotelogin.py:133 cps/web.py:1535 +#: cps/oauth_bb.py:138 cps/remotelogin.py:130 cps/web.py:1613 #, python-format msgid "you are now logged in as: '%(nickname)s'" msgstr "您現在已以“%(nickname)s”身份登入" @@ -839,163 +859,163 @@ msgstr "Google Oauth 錯誤,請重試。" msgid "Google Oauth error: {}" msgstr "Google Oauth 錯誤: {}" -#: cps/opds.py:384 +#: cps/opds.py:298 msgid "{} Stars" msgstr "{} 星" -#: cps/remotelogin.py:65 cps/templates/layout.html:84 -#: cps/templates/login.html:4 cps/templates/login.html:21 cps/web.py:1584 +#: cps/remotelogin.py:62 cps/templates/layout.html:84 +#: cps/templates/login.html:4 cps/templates/login.html:21 cps/web.py:1662 msgid "Login" msgstr "登入" -#: cps/remotelogin.py:77 cps/remotelogin.py:111 +#: cps/remotelogin.py:74 cps/remotelogin.py:108 msgid "Token not found" msgstr "找不到Token" -#: cps/remotelogin.py:86 cps/remotelogin.py:119 +#: cps/remotelogin.py:83 cps/remotelogin.py:116 msgid "Token has expired" msgstr "Token已過期" -#: cps/remotelogin.py:95 +#: cps/remotelogin.py:92 msgid "Success! Please return to your device" msgstr "成功!請返回您的設備" -#: cps/render_template.py:39 cps/web.py:416 +#: cps/render_template.py:41 cps/web.py:407 msgid "Books" msgstr "書籍" -#: cps/render_template.py:41 +#: cps/render_template.py:43 msgid "Show recent books" msgstr "顯示最近書籍" -#: cps/render_template.py:42 cps/templates/index.xml:25 +#: cps/render_template.py:44 cps/templates/index.xml:25 msgid "Hot Books" msgstr "熱門書籍" -#: cps/render_template.py:44 +#: cps/render_template.py:46 msgid "Show Hot Books" msgstr "顯示熱門書籍" -#: cps/render_template.py:46 cps/render_template.py:51 +#: cps/render_template.py:48 cps/render_template.py:53 msgid "Downloaded Books" msgstr "已下載書籍" -#: cps/render_template.py:48 cps/render_template.py:53 +#: cps/render_template.py:50 cps/render_template.py:55 #: cps/templates/user_table.html:167 msgid "Show Downloaded Books" msgstr "顯示下載過的書籍" -#: cps/render_template.py:56 cps/templates/index.xml:32 cps/web.py:430 +#: cps/render_template.py:58 cps/templates/index.xml:32 cps/web.py:422 msgid "Top Rated Books" msgstr "最高評分書籍" -#: cps/render_template.py:58 cps/templates/user_table.html:161 +#: cps/render_template.py:60 cps/templates/user_table.html:161 msgid "Show Top Rated Books" msgstr "顯示最高評分書籍" -#: cps/render_template.py:59 cps/templates/index.xml:54 -#: cps/templates/index.xml:58 cps/web.py:676 +#: cps/render_template.py:61 cps/templates/index.xml:54 +#: cps/templates/index.xml:58 cps/web.py:729 msgid "Read Books" msgstr "已讀書籍" -#: cps/render_template.py:61 +#: cps/render_template.py:63 msgid "Show read and unread" msgstr "顯示閱讀狀態" -#: cps/render_template.py:63 cps/templates/index.xml:61 -#: cps/templates/index.xml:65 cps/web.py:679 +#: cps/render_template.py:65 cps/templates/index.xml:61 +#: cps/templates/index.xml:65 cps/web.py:732 msgid "Unread Books" msgstr "未讀書籍" -#: cps/render_template.py:65 +#: cps/render_template.py:67 msgid "Show unread" msgstr "顯示未讀" -#: cps/render_template.py:66 +#: cps/render_template.py:68 msgid "Discover" msgstr "發現" -#: cps/render_template.py:68 cps/templates/index.xml:50 +#: cps/render_template.py:70 cps/templates/index.xml:50 #: cps/templates/user_table.html:162 msgid "Show Random Books" msgstr "隨機顯示書籍" -#: cps/render_template.py:69 cps/templates/book_table.html:67 -#: cps/templates/index.xml:83 cps/web.py:1041 +#: cps/render_template.py:71 cps/templates/book_table.html:67 +#: cps/templates/index.xml:83 cps/web.py:1135 msgid "Categories" msgstr "分類" -#: cps/render_template.py:71 cps/templates/user_table.html:158 +#: cps/render_template.py:73 cps/templates/user_table.html:158 msgid "Show category selection" msgstr "顯示分類選擇" -#: cps/render_template.py:72 cps/templates/book_edit.html:90 +#: cps/render_template.py:74 cps/templates/book_edit.html:90 #: cps/templates/book_table.html:68 cps/templates/index.xml:90 -#: cps/templates/search_form.html:69 cps/web.py:948 cps/web.py:959 +#: cps/templates/search_form.html:69 cps/web.py:1034 cps/web.py:1041 msgid "Series" msgstr "叢書" -#: cps/render_template.py:74 cps/templates/user_table.html:157 +#: cps/render_template.py:76 cps/templates/user_table.html:157 msgid "Show series selection" msgstr "顯示叢書選擇" -#: cps/render_template.py:75 cps/templates/book_table.html:66 +#: cps/render_template.py:77 cps/templates/book_table.html:66 #: cps/templates/index.xml:69 msgid "Authors" msgstr "作者" -#: cps/render_template.py:77 cps/templates/user_table.html:160 +#: cps/render_template.py:79 cps/templates/user_table.html:160 msgid "Show author selection" msgstr "顯示作者選擇" -#: cps/render_template.py:79 cps/templates/book_table.html:72 -#: cps/templates/index.xml:76 cps/web.py:925 +#: cps/render_template.py:81 cps/templates/book_table.html:72 +#: cps/templates/index.xml:76 cps/web.py:1006 msgid "Publishers" msgstr "出版社" -#: cps/render_template.py:81 cps/templates/user_table.html:163 +#: cps/render_template.py:83 cps/templates/user_table.html:163 msgid "Show publisher selection" msgstr "顯示出版社選擇" -#: cps/render_template.py:82 cps/templates/book_table.html:70 +#: cps/render_template.py:84 cps/templates/book_table.html:70 #: cps/templates/index.xml:97 cps/templates/search_form.html:107 -#: cps/web.py:1018 +#: cps/web.py:1108 msgid "Languages" msgstr "語言" -#: cps/render_template.py:85 cps/templates/user_table.html:155 +#: cps/render_template.py:87 cps/templates/user_table.html:155 msgid "Show language selection" msgstr "顯示語言選擇" -#: cps/render_template.py:86 cps/templates/index.xml:104 +#: cps/render_template.py:88 cps/templates/index.xml:104 msgid "Ratings" msgstr "評分" -#: cps/render_template.py:88 cps/templates/user_table.html:164 +#: cps/render_template.py:90 cps/templates/user_table.html:164 msgid "Show ratings selection" msgstr "顯示評分選擇" -#: cps/render_template.py:89 cps/templates/index.xml:112 +#: cps/render_template.py:91 cps/templates/index.xml:112 msgid "File formats" msgstr "文件格式" -#: cps/render_template.py:91 cps/templates/user_table.html:165 +#: cps/render_template.py:93 cps/templates/user_table.html:165 msgid "Show file formats selection" msgstr "顯示文件格式選擇" -#: cps/render_template.py:93 cps/web.py:703 +#: cps/render_template.py:95 cps/web.py:755 msgid "Archived Books" msgstr "歸檔書籍" -#: cps/render_template.py:95 cps/templates/user_table.html:166 +#: cps/render_template.py:97 cps/templates/user_table.html:166 msgid "Show archived books" msgstr "顯示歸檔書籍" -#: cps/render_template.py:97 cps/web.py:780 +#: cps/render_template.py:100 cps/web.py:837 msgid "Books List" msgstr "書籍列表" -#: cps/render_template.py:99 cps/templates/user_table.html:168 +#: cps/render_template.py:102 cps/templates/user_table.html:168 msgid "Show Books List" msgstr "顯示書籍列表" @@ -1049,261 +1069,265 @@ msgstr "" msgid "Create a Shelf" msgstr "創建書架" -#: cps/shelf.py:237 +#: cps/shelf.py:236 msgid "Sorry you are not allowed to edit this shelf" msgstr "對不起,您沒有編輯這個書架的權限" -#: cps/shelf.py:239 +#: cps/shelf.py:238 msgid "Edit a shelf" msgstr "編輯書架" -#: cps/shelf.py:249 +#: cps/shelf.py:248 msgid "Sorry you are not allowed to create a public shelf" msgstr "" -#: cps/shelf.py:266 +#: cps/shelf.py:265 #, python-format msgid "Shelf %(title)s created" msgstr "書架 %(title)s 已創建" -#: cps/shelf.py:269 +#: cps/shelf.py:268 #, python-format msgid "Shelf %(title)s changed" msgstr "書架 %(title)s 已修改" -#: cps/shelf.py:283 +#: cps/shelf.py:282 msgid "There was an error" msgstr "發生錯誤" -#: cps/shelf.py:305 +#: cps/shelf.py:304 #, python-format msgid "A public shelf with the name '%(title)s' already exists." msgstr "公共書架:%(title)s已經存在已經存在。" -#: cps/shelf.py:316 +#: cps/shelf.py:315 #, python-format msgid "A private shelf with the name '%(title)s' already exists." msgstr "私有書架:%(title)s已經存在。" #: cps/shelf.py:337 +msgid "Error deleting Shelf" +msgstr "" + +#: cps/shelf.py:339 #, fuzzy msgid "Shelf successfully deleted" msgstr "書籍已成功刪除" -#: cps/shelf.py:386 +#: cps/shelf.py:389 #, python-format msgid "Change order of Shelf: '%(name)s'" msgstr "修改書架 %(name)s 順序" -#: cps/shelf.py:456 +#: cps/shelf.py:461 #, python-format msgid "Shelf: '%(name)s'" msgstr "書架:%(name)s" -#: cps/shelf.py:460 +#: cps/shelf.py:465 msgid "Error opening shelf. Shelf does not exist or is not accessible" msgstr "打開書架出錯。書架不存在或不可訪問" -#: cps/updater.py:403 cps/updater.py:414 cps/updater.py:514 cps/updater.py:529 +#: cps/updater.py:426 cps/updater.py:437 cps/updater.py:538 cps/updater.py:553 msgid "Unexpected data while reading update information" msgstr "讀取更新信息時出現未預期數據" -#: cps/updater.py:410 cps/updater.py:521 +#: cps/updater.py:433 cps/updater.py:545 msgid "No update available. You already have the latest version installed" msgstr "無可用更新。您已經安裝了最新版本" -#: cps/updater.py:428 +#: cps/updater.py:451 msgid "A new update is available. Click on the button below to update to the latest version." msgstr "有新的更新。單擊下面的按鈕以更新到最新版本。" -#: cps/updater.py:446 +#: cps/updater.py:469 msgid "Could not fetch update information" msgstr "無法獲取更新信息" -#: cps/updater.py:456 +#: cps/updater.py:479 msgid "Click on the button below to update to the latest stable version." msgstr "點擊下面按鈕更新到最新穩定版本。" -#: cps/updater.py:465 cps/updater.py:479 cps/updater.py:490 +#: cps/updater.py:488 cps/updater.py:502 cps/updater.py:513 #, python-format msgid "A new update is available. Click on the button below to update to version: %(version)s" msgstr "有新的更新。單擊下面的按鈕以更新到版本: %(version)s" -#: cps/updater.py:507 +#: cps/updater.py:531 msgid "No release information available" msgstr "無可用發佈信息" -#: cps/templates/index.html:5 cps/web.py:440 +#: cps/templates/index.html:5 cps/web.py:434 msgid "Discover (Random Books)" msgstr "發現(隨機書籍)" -#: cps/web.py:471 +#: cps/web.py:470 msgid "Hot Books (Most Downloaded)" msgstr "熱門書籍(最多下載)" -#: cps/web.py:507 +#: cps/web.py:501 #, python-format msgid "Downloaded books by %(user)s" msgstr "%(user)s 下載過的書籍" -#: cps/web.py:539 +#: cps/web.py:534 #, python-format msgid "Author: %(name)s" msgstr "作者:%(name)s" -#: cps/web.py:554 +#: cps/web.py:570 #, python-format msgid "Publisher: %(name)s" msgstr "出版社:%(name)s" -#: cps/web.py:569 +#: cps/web.py:598 #, python-format msgid "Series: %(serie)s" msgstr "叢書:%(serie)s" -#: cps/web.py:582 +#: cps/web.py:610 #, python-format msgid "Rating: %(rating)s stars" msgstr "評分:%(rating)s 星" -#: cps/web.py:597 +#: cps/web.py:626 #, python-format msgid "File format: %(format)s" msgstr "文件格式:%(format)s" -#: cps/web.py:615 +#: cps/web.py:663 #, python-format msgid "Category: %(name)s" msgstr "分類:%(name)s" -#: cps/web.py:631 +#: cps/web.py:690 #, python-format msgid "Language: %(name)s" msgstr "語言:%(name)s" -#: cps/templates/layout.html:56 cps/web.py:737 cps/web.py:1371 +#: cps/templates/layout.html:56 cps/web.py:789 cps/web.py:1444 msgid "Advanced Search" msgstr "進階搜尋" #: cps/templates/book_edit.html:235 cps/templates/feed.xml:33 #: cps/templates/index.xml:11 cps/templates/layout.html:45 #: cps/templates/layout.html:48 cps/templates/search_form.html:226 -#: cps/web.py:750 cps/web.py:1077 +#: cps/web.py:807 cps/web.py:1164 msgid "Search" msgstr "搜尋" -#: cps/templates/admin.html:16 cps/web.py:903 +#: cps/templates/admin.html:16 cps/web.py:979 msgid "Downloads" msgstr "下載次數" -#: cps/web.py:980 +#: cps/web.py:1068 msgid "Ratings list" msgstr "評分列表" -#: cps/web.py:1001 +#: cps/web.py:1095 msgid "File formats list" msgstr "文件格式列表" -#: cps/templates/layout.html:73 cps/templates/tasks.html:7 cps/web.py:1055 +#: cps/templates/layout.html:73 cps/templates/tasks.html:7 cps/web.py:1149 msgid "Tasks" msgstr "任務列表" -#: cps/web.py:1215 +#: cps/web.py:1286 msgid "Published after " msgstr "出版時間晚於 " -#: cps/web.py:1222 +#: cps/web.py:1293 msgid "Published before " msgstr "出版時間早於 " -#: cps/web.py:1244 +#: cps/web.py:1315 #, python-format msgid "Rating <= %(rating)s" msgstr "評分 <= %(rating)s" -#: cps/web.py:1246 +#: cps/web.py:1317 #, python-format msgid "Rating >= %(rating)s" msgstr "評分 >= %(rating)s" -#: cps/web.py:1248 +#: cps/web.py:1319 #, python-format msgid "Read Status = %(status)s" msgstr "閱讀狀態 = %(status)s" -#: cps/web.py:1353 +#: cps/web.py:1425 msgid "Error on search for custom columns, please restart Calibre-Web" msgstr "搜詢自定義欄位時出錯,請重啟 Calibre-Web" -#: cps/web.py:1449 +#: cps/web.py:1527 #, python-format msgid "Book successfully queued for sending to %(kindlemail)s" msgstr "書籍已經成功加入 %(kindlemail)s 的發送隊列" -#: cps/web.py:1453 +#: cps/web.py:1531 #, python-format msgid "Oops! There was an error sending this book: %(res)s" msgstr "糟糕!發送這本書籍的時候出現錯誤:%(res)s" -#: cps/web.py:1455 +#: cps/web.py:1533 msgid "Please update your profile with a valid Send to Kindle E-mail Address." msgstr "請先設置您的kindle郵箱。" -#: cps/web.py:1472 +#: cps/web.py:1550 msgid "E-Mail server is not configured, please contact your administrator!" msgstr "郵件服務未配置,請聯繫網站管理員!" -#: cps/templates/layout.html:85 cps/templates/register.html:17 cps/web.py:1473 -#: cps/web.py:1480 cps/web.py:1486 cps/web.py:1505 cps/web.py:1509 -#: cps/web.py:1515 +#: cps/templates/layout.html:85 cps/templates/register.html:17 cps/web.py:1551 +#: cps/web.py:1558 cps/web.py:1564 cps/web.py:1583 cps/web.py:1587 +#: cps/web.py:1593 msgid "Register" msgstr "註冊" -#: cps/web.py:1507 +#: cps/web.py:1585 msgid "Your e-mail is not allowed to register" msgstr "您的電子郵件不允許註冊" -#: cps/web.py:1510 +#: cps/web.py:1588 msgid "Confirmation e-mail was send to your e-mail account." msgstr "確認郵件已經發送到您的郵箱。" -#: cps/web.py:1524 +#: cps/web.py:1602 msgid "Cannot activate LDAP authentication" msgstr "無法激活LDAP認證" -#: cps/web.py:1543 +#: cps/web.py:1621 #, python-format msgid "Fallback Login as: '%(nickname)s', LDAP Server not reachable, or user not known" msgstr "備援登入“%(nickname)s”:無法訪問LDAP伺服器,或用戶未知" -#: cps/web.py:1549 +#: cps/web.py:1627 #, python-format msgid "Could not login: %(message)s" msgstr "無法登入:%(message)s" -#: cps/web.py:1553 cps/web.py:1578 +#: cps/web.py:1631 cps/web.py:1656 msgid "Wrong Username or Password" msgstr "用戶名或密碼錯誤" -#: cps/web.py:1560 +#: cps/web.py:1638 msgid "New Password was send to your email address" msgstr "新密碼已發送到您的郵箱" -#: cps/web.py:1566 +#: cps/web.py:1644 msgid "Please enter valid username to reset password" msgstr "請輸入有效的用戶名進行密碼重置" -#: cps/web.py:1573 +#: cps/web.py:1651 #, python-format msgid "You are now logged in as: '%(nickname)s'" msgstr "您現在已以“%(nickname)s”登入" -#: cps/web.py:1639 cps/web.py:1688 +#: cps/web.py:1717 cps/web.py:1766 #, python-format msgid "%(name)s's profile" msgstr "%(name)s 的用戶配置" -#: cps/web.py:1655 +#: cps/web.py:1733 msgid "Profile updated" msgstr "資料已更新" @@ -1311,36 +1335,36 @@ msgstr "資料已更新" msgid "Found no valid gmail.json file with OAuth information" msgstr "找不到包含 OAuth 信息的有效 gmail.json 文件" -#: cps/tasks/convert.py:137 +#: cps/tasks/convert.py:154 #, python-format msgid "Calibre ebook-convert %(tool)s not found" msgstr "沒有發現Calibre 電子書轉換器%(tool)s" -#: cps/tasks/convert.py:163 +#: cps/tasks/convert.py:187 #, python-format msgid "%(format)s format not found on disk" msgstr "硬碟上找不到 %(format)s 格式" -#: cps/tasks/convert.py:167 +#: cps/tasks/convert.py:191 msgid "Ebook converter failed with unknown error" msgstr "發生未知錯誤,書籍轉換失敗" -#: cps/tasks/convert.py:177 +#: cps/tasks/convert.py:201 #, python-format msgid "Kepubify-converter failed: %(error)s" msgstr "Kepubify 轉換失敗:%(error)s" -#: cps/tasks/convert.py:199 +#: cps/tasks/convert.py:223 #, python-format msgid "Converted file not found or more than one file in folder %(folder)s" msgstr "找不到轉換後的文件或文件夾%(folder)s中有多個文件" -#: cps/tasks/convert.py:222 +#: cps/tasks/convert.py:246 #, python-format msgid "Ebook-converter failed: %(error)s" msgstr "電子書轉換器失敗: %(error)s" -#: cps/tasks/convert.py:245 +#: cps/tasks/convert.py:269 #, python-format msgid "Calibre failed with error: %(error)s" msgstr "Calibre 運行失敗,錯誤信息:%(error)s" @@ -1395,7 +1419,7 @@ msgid "Edit" msgstr "編輯書籍" #: cps/templates/admin.html:25 cps/templates/book_edit.html:16 -#: cps/templates/book_table.html:97 cps/templates/modal_dialogs.html:63 +#: cps/templates/book_table.html:100 cps/templates/modal_dialogs.html:63 #: cps/templates/modal_dialogs.html:116 cps/templates/user_edit.html:67 #: cps/templates/user_table.html:149 msgid "Delete" @@ -1405,179 +1429,179 @@ msgstr "刪除數據" msgid "Public Shelf" msgstr "公共書架" -#: cps/templates/admin.html:51 +#: cps/templates/admin.html:53 msgid "Add New User" msgstr "添加新用戶" -#: cps/templates/admin.html:53 +#: cps/templates/admin.html:55 msgid "Import LDAP Users" msgstr "導入LDAP用戶" -#: cps/templates/admin.html:60 +#: cps/templates/admin.html:62 msgid "E-mail Server Settings" msgstr "SMTP郵件服務器設置" -#: cps/templates/admin.html:65 cps/templates/email_edit.html:31 +#: cps/templates/admin.html:67 cps/templates/email_edit.html:31 msgid "SMTP Hostname" msgstr "SMTP主機名" -#: cps/templates/admin.html:69 cps/templates/email_edit.html:35 +#: cps/templates/admin.html:71 cps/templates/email_edit.html:35 msgid "SMTP Port" msgstr "SMTP端口" -#: cps/templates/admin.html:73 cps/templates/email_edit.html:39 +#: cps/templates/admin.html:75 cps/templates/email_edit.html:39 msgid "Encryption" msgstr "加密" -#: cps/templates/admin.html:77 cps/templates/email_edit.html:47 +#: cps/templates/admin.html:79 cps/templates/email_edit.html:47 msgid "SMTP Login" msgstr "SMTP用戶名" -#: cps/templates/admin.html:81 cps/templates/admin.html:92 +#: cps/templates/admin.html:83 cps/templates/admin.html:94 #: cps/templates/email_edit.html:55 msgid "From E-mail" msgstr "發信人郵箱" -#: cps/templates/admin.html:88 +#: cps/templates/admin.html:90 msgid "E-Mail Service" msgstr "電子郵件服務" -#: cps/templates/admin.html:89 +#: cps/templates/admin.html:91 msgid "Gmail via Oauth2" msgstr "通過Oauth2的Gmail" -#: cps/templates/admin.html:104 +#: cps/templates/admin.html:106 msgid "Configuration" msgstr "配置" -#: cps/templates/admin.html:107 +#: cps/templates/admin.html:109 msgid "Calibre Database Directory" msgstr "Calibre 數據庫路徑" -#: cps/templates/admin.html:111 cps/templates/config_edit.html:68 +#: cps/templates/admin.html:113 cps/templates/config_edit.html:68 msgid "Log Level" msgstr "日誌級別" -#: cps/templates/admin.html:115 +#: cps/templates/admin.html:117 msgid "Port" msgstr "端口" -#: cps/templates/admin.html:120 +#: cps/templates/admin.html:122 msgid "External Port" msgstr "擴展端口" -#: cps/templates/admin.html:127 cps/templates/config_view_edit.html:28 +#: cps/templates/admin.html:129 cps/templates/config_view_edit.html:28 msgid "Books per Page" msgstr "每頁書籍數" -#: cps/templates/admin.html:131 +#: cps/templates/admin.html:133 msgid "Uploads" msgstr "上傳" -#: cps/templates/admin.html:135 +#: cps/templates/admin.html:137 msgid "Anonymous Browsing" msgstr "匿名瀏覽" -#: cps/templates/admin.html:139 +#: cps/templates/admin.html:141 msgid "Public Registration" msgstr "開放註冊" -#: cps/templates/admin.html:143 +#: cps/templates/admin.html:145 msgid "Magic Link Remote Login" msgstr "魔法連接遠程登錄" -#: cps/templates/admin.html:147 +#: cps/templates/admin.html:149 msgid "Reverse Proxy Login" msgstr "反向代理登入" -#: cps/templates/admin.html:152 cps/templates/config_edit.html:173 +#: cps/templates/admin.html:154 cps/templates/config_edit.html:173 msgid "Reverse Proxy Header Name" msgstr "反向代理標頭名稱" -#: cps/templates/admin.html:157 +#: cps/templates/admin.html:159 msgid "Edit Calibre Database Configuration" msgstr "編輯Calibre數據庫配置" -#: cps/templates/admin.html:158 +#: cps/templates/admin.html:160 msgid "Edit Basic Configuration" msgstr "編輯基本配置" -#: cps/templates/admin.html:159 +#: cps/templates/admin.html:161 msgid "Edit UI Configuration" msgstr "編輯界面配置" -#: cps/templates/admin.html:164 +#: cps/templates/admin.html:166 msgid "Administration" msgstr "管理" -#: cps/templates/admin.html:165 +#: cps/templates/admin.html:167 msgid "Download Debug Package" msgstr "下載除錯包" -#: cps/templates/admin.html:166 +#: cps/templates/admin.html:168 msgid "View Logs" msgstr "查看日誌文件" -#: cps/templates/admin.html:169 +#: cps/templates/admin.html:171 msgid "Reconnect Calibre Database" msgstr "重新連接到Calibre數據庫" -#: cps/templates/admin.html:170 +#: cps/templates/admin.html:172 msgid "Restart" msgstr "重啟" -#: cps/templates/admin.html:171 +#: cps/templates/admin.html:173 msgid "Shutdown" msgstr "停止" -#: cps/templates/admin.html:176 +#: cps/templates/admin.html:178 msgid "Update" msgstr "更新" -#: cps/templates/admin.html:180 +#: cps/templates/admin.html:182 msgid "Version" msgstr "版本" -#: cps/templates/admin.html:181 +#: cps/templates/admin.html:183 msgid "Details" msgstr "詳情" -#: cps/templates/admin.html:187 +#: cps/templates/admin.html:189 msgid "Current version" msgstr "當前版本" -#: cps/templates/admin.html:194 +#: cps/templates/admin.html:196 msgid "Check for Update" msgstr "檢查更新" -#: cps/templates/admin.html:195 +#: cps/templates/admin.html:197 msgid "Perform Update" msgstr "執行更新" -#: cps/templates/admin.html:208 +#: cps/templates/admin.html:210 msgid "Are you sure you want to restart?" msgstr "您確定要重啟嗎?" -#: cps/templates/admin.html:213 cps/templates/admin.html:227 -#: cps/templates/admin.html:247 cps/templates/config_db.html:70 +#: cps/templates/admin.html:215 cps/templates/admin.html:229 +#: cps/templates/admin.html:249 cps/templates/config_db.html:70 msgid "OK" msgstr "確定" -#: cps/templates/admin.html:214 cps/templates/admin.html:228 -#: cps/templates/book_edit.html:213 cps/templates/book_table.html:124 +#: cps/templates/admin.html:216 cps/templates/admin.html:230 +#: cps/templates/book_edit.html:213 cps/templates/book_table.html:127 #: cps/templates/config_db.html:54 cps/templates/config_edit.html:359 -#: cps/templates/config_view_edit.html:173 cps/templates/modal_dialogs.html:64 +#: cps/templates/config_view_edit.html:175 cps/templates/modal_dialogs.html:64 #: cps/templates/modal_dialogs.html:99 cps/templates/modal_dialogs.html:117 #: cps/templates/modal_dialogs.html:135 cps/templates/shelf_edit.html:27 #: cps/templates/user_edit.html:144 msgid "Cancel" msgstr "取消" -#: cps/templates/admin.html:226 +#: cps/templates/admin.html:228 msgid "Are you sure you want to shutdown?" msgstr "您確定要關閉嗎?" -#: cps/templates/admin.html:238 +#: cps/templates/admin.html:240 msgid "Updating, please do not reload this page" msgstr "正在更新,請不要刷新頁面" @@ -1589,44 +1613,43 @@ msgstr "通過" msgid "In Library" msgstr "在書庫" -#: cps/templates/author.html:26 cps/templates/index.html:72 -#: cps/templates/search.html:29 cps/templates/shelf.html:19 +#: cps/templates/author.html:26 cps/templates/index.html:73 +#: cps/templates/search.html:30 cps/templates/shelf.html:19 msgid "Sort according to book date, newest first" msgstr "按圖書日期排序,最新優先" -#: cps/templates/author.html:27 cps/templates/index.html:73 -#: cps/templates/search.html:30 cps/templates/shelf.html:20 +#: cps/templates/author.html:27 cps/templates/index.html:74 +#: cps/templates/search.html:31 cps/templates/shelf.html:20 msgid "Sort according to book date, oldest first" msgstr "按圖書日期排序,最舊優先" -#: cps/templates/author.html:28 cps/templates/index.html:74 -#: cps/templates/search.html:31 cps/templates/shelf.html:21 +#: cps/templates/author.html:28 cps/templates/index.html:75 +#: cps/templates/search.html:32 cps/templates/shelf.html:21 msgid "Sort title in alphabetical order" msgstr "按標題按字母順序排序" -#: cps/templates/author.html:29 cps/templates/index.html:75 -#: cps/templates/search.html:32 cps/templates/shelf.html:22 +#: cps/templates/author.html:29 cps/templates/index.html:76 +#: cps/templates/search.html:33 cps/templates/shelf.html:22 msgid "Sort title in reverse alphabetical order" msgstr "按標題逆字母順序排序" -#: cps/templates/author.html:30 cps/templates/index.html:78 -#: cps/templates/search.html:35 cps/templates/shelf.html:25 +#: cps/templates/author.html:30 cps/templates/index.html:79 +#: cps/templates/search.html:36 cps/templates/shelf.html:25 msgid "Sort according to publishing date, newest first" msgstr "按出版日期排序,最新優先" -#: cps/templates/author.html:31 cps/templates/index.html:79 -#: cps/templates/search.html:36 cps/templates/shelf.html:26 +#: cps/templates/author.html:31 cps/templates/index.html:80 +#: cps/templates/search.html:37 cps/templates/shelf.html:26 msgid "Sort according to publishing date, oldest first" msgstr "按出版日期排序,最舊優先" -#: cps/templates/author.html:57 cps/templates/author.html:117 -#: cps/templates/discover.html:30 cps/templates/index.html:29 -#: cps/templates/index.html:111 cps/templates/search.html:65 -#: cps/templates/shelf.html:54 +#: cps/templates/author.html:56 cps/templates/author.html:115 +#: cps/templates/index.html:29 cps/templates/index.html:112 +#: cps/templates/search.html:66 cps/templates/shelf.html:54 msgid "reduce" msgstr "減少" -#: cps/templates/author.html:101 +#: cps/templates/author.html:99 msgid "More by" msgstr "更多" @@ -1751,7 +1774,7 @@ msgid "Fetch Metadata" msgstr "獲取元數據" #: cps/templates/book_edit.html:212 cps/templates/config_db.html:53 -#: cps/templates/config_edit.html:358 cps/templates/config_view_edit.html:172 +#: cps/templates/config_edit.html:358 cps/templates/config_view_edit.html:174 #: cps/templates/email_edit.html:65 cps/templates/shelf_edit.html:25 #: cps/templates/shelf_order.html:41 cps/templates/user_edit.html:142 msgid "Save" @@ -1880,27 +1903,35 @@ msgstr "輸入網域名" msgid "Comments" msgstr "" -#: cps/templates/book_table.html:77 cps/templates/book_table.html:79 -#: cps/templates/book_table.html:81 cps/templates/book_table.html:83 -#: cps/templates/book_table.html:87 cps/templates/book_table.html:89 -#: cps/templates/book_table.html:91 cps/templates/book_table.html:93 +#: cps/templates/book_table.html:75 +msgid "Archiv Status" +msgstr "" + +#: cps/templates/book_table.html:77 cps/templates/search_form.html:42 +msgid "Read Status" +msgstr "閱讀狀態" + +#: cps/templates/book_table.html:80 cps/templates/book_table.html:82 +#: cps/templates/book_table.html:84 cps/templates/book_table.html:86 +#: cps/templates/book_table.html:90 cps/templates/book_table.html:92 +#: cps/templates/book_table.html:96 #, fuzzy msgid "Enter " msgstr "書號" -#: cps/templates/book_table.html:110 cps/templates/modal_dialogs.html:46 +#: cps/templates/book_table.html:113 cps/templates/modal_dialogs.html:46 msgid "Are you really sure?" msgstr "您真的確認?" -#: cps/templates/book_table.html:114 +#: cps/templates/book_table.html:117 msgid "Books with Title will be merged from:" msgstr "這本書籍將被合併:" -#: cps/templates/book_table.html:118 +#: cps/templates/book_table.html:121 msgid "Into Book with Title:" msgstr "合併到這本書籍:" -#: cps/templates/book_table.html:123 +#: cps/templates/book_table.html:126 msgid "Merge" msgstr "合併" @@ -2076,11 +2107,6 @@ msgstr "LDAP伺服器端口" msgid "LDAP Encryption" msgstr "LDAP 加密" -#: cps/templates/config_edit.html:204 cps/templates/config_view_edit.html:62 -#: cps/templates/email_edit.html:41 -msgid "None" -msgstr "無" - #: cps/templates/config_edit.html:205 msgid "TLS" msgstr "TLS協議" @@ -2299,11 +2325,11 @@ msgstr "新用戶默認顯示權限" msgid "Show Random Books in Detail View" msgstr "在主頁顯示隨機書籍" -#: cps/templates/config_view_edit.html:165 cps/templates/user_edit.html:87 +#: cps/templates/config_view_edit.html:166 cps/templates/user_edit.html:87 msgid "Add Allowed/Denied Tags" msgstr "添加顯示或隱藏書籍的標籤值" -#: cps/templates/config_view_edit.html:166 +#: cps/templates/config_view_edit.html:167 msgid "Add Allowed/Denied custom column values" msgstr "添加顯示或隱藏書籍的自定義欄位值" @@ -2352,13 +2378,13 @@ msgstr "歸檔" msgid "Description:" msgstr "簡介:" -#: cps/templates/detail.html:256 cps/templates/search.html:14 +#: cps/templates/detail.html:256 cps/templates/search.html:15 msgid "Add to shelf" msgstr "添加到書架" #: cps/templates/detail.html:267 cps/templates/detail.html:284 #: cps/templates/feed.xml:79 cps/templates/layout.html:137 -#: cps/templates/search.html:20 +#: cps/templates/search.html:21 msgid "(Public)" msgstr "(公共)" @@ -2436,10 +2462,15 @@ msgstr "禁止註冊的網域名(黑名單)" msgid "Next" msgstr "下一個" -#: cps/templates/generate_kobo_auth_url.html:5 +#: cps/templates/generate_kobo_auth_url.html:6 msgid "Open the .kobo/Kobo eReader.conf file in a text editor and add (or edit):" msgstr "在文本編輯器中打開.kobo/Kobo eReader.conf,添加(或編輯):" +#: cps/templates/generate_kobo_auth_url.html:11 +#, fuzzy +msgid "Kobo Token:" +msgstr "Kobo 同步 Token" + #: cps/templates/http_error.html:31 msgid "Calibre-Web Instance is unconfigured, please contact your administrator" msgstr "Calibre-Web 實例未配置,請聯繫您的系統管理員!" @@ -2456,29 +2487,29 @@ msgstr "回到首頁" msgid "Logout User" msgstr "登出賬號" -#: cps/templates/index.html:69 +#: cps/templates/index.html:70 msgid "Sort ascending according to download count" msgstr "" -#: cps/templates/index.html:70 +#: cps/templates/index.html:71 msgid "Sort descending according to download count" msgstr "" -#: cps/templates/index.html:76 cps/templates/search.html:33 +#: cps/templates/index.html:77 cps/templates/search.html:34 #: cps/templates/shelf.html:23 msgid "Sort authors in alphabetical order" msgstr "按作者字母順序排序" -#: cps/templates/index.html:77 cps/templates/search.html:34 +#: cps/templates/index.html:78 cps/templates/search.html:35 #: cps/templates/shelf.html:24 msgid "Sort authors in reverse alphabetical order" msgstr "按作者逆字母順序排序" -#: cps/templates/index.html:81 +#: cps/templates/index.html:82 msgid "Sort ascending according to series index" msgstr "按叢書編號排序" -#: cps/templates/index.html:82 +#: cps/templates/index.html:83 msgid "Sort descending according to series index" msgstr "按叢書編號逆排序" @@ -2908,10 +2939,6 @@ msgstr "出版日期從" msgid "Published Date To" msgstr "出版日期到" -#: cps/templates/search_form.html:42 -msgid "Read Status" -msgstr "閱讀狀態" - #: cps/templates/search_form.html:59 msgid "Exclude Tags" msgstr "排除標籤" diff --git a/cps/ub.py b/cps/ub.py index 786dc909..0360b572 100644 --- a/cps/ub.py +++ b/cps/ub.py @@ -17,6 +17,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +import atexit import os import sys import datetime @@ -67,6 +68,7 @@ logged_in = dict() def signal_store_user_session(object, user): store_user_session() + def store_user_session(): if flask_session.get('user_id', ""): flask_session['_user_id'] = flask_session.get('user_id', "") @@ -85,15 +87,16 @@ def store_user_session(): else: log.error("No user id in session") + def delete_user_session(user_id, session_key): try: log.debug("Deleted session_key: " + session_key) - session.query(User_Sessions).filter(User_Sessions.user_id==user_id, - User_Sessions.session_key==session_key).delete() + session.query(User_Sessions).filter(User_Sessions.user_id == user_id, + User_Sessions.session_key == session_key).delete() session.commit() - except (exc.OperationalError, exc.InvalidRequestError) as e: + except (exc.OperationalError, exc.InvalidRequestError) as ex: session.rollback() - log.exception(e) + log.exception(ex) def check_user_session(user_id, session_key): @@ -209,9 +212,9 @@ class UserBase: pass try: session.commit() - except (exc.OperationalError, exc.InvalidRequestError): + except (exc.OperationalError, exc.InvalidRequestError) as e: session.rollback() - # ToDo: Error message + log.error_or_exception(e) def __repr__(self): return '' % self.name @@ -510,6 +513,28 @@ class RemoteAuthToken(Base): return '' % self.id +def filename(context): + file_format = context.get_current_parameters()['format'] + if file_format == 'jpeg': + return context.get_current_parameters()['uuid'] + '.jpg' + else: + return context.get_current_parameters()['uuid'] + '.' + file_format + + +class Thumbnail(Base): + __tablename__ = 'thumbnail' + + id = Column(Integer, primary_key=True) + entity_id = Column(Integer) + uuid = Column(String, default=lambda: str(uuid.uuid4()), unique=True) + format = Column(String, default='jpeg') + type = Column(SmallInteger, default=constants.THUMBNAIL_TYPE_COVER) + resolution = Column(SmallInteger, default=constants.COVER_THUMBNAIL_SMALL) + filename = Column(String, default=filename) + generated_at = Column(DateTime, default=lambda: datetime.datetime.utcnow()) + expiration = Column(DateTime, nullable=True) + + # Add missing tables during migration of database def add_missing_tables(engine, _session): if not engine.dialect.has_table(engine.connect(), "book_read_link"): @@ -524,6 +549,8 @@ def add_missing_tables(engine, _session): KoboStatistics.__table__.create(bind=engine) if not engine.dialect.has_table(engine.connect(), "archived_book"): ArchivedBook.__table__.create(bind=engine) + if not engine.dialect.has_table(engine.connect(), "thumbnail"): + Thumbnail.__table__.create(bind=engine) if not engine.dialect.has_table(engine.connect(), "registration"): Registration.__table__.create(bind=engine) with engine.connect() as conn: @@ -829,6 +856,16 @@ def init_db(app_db_path): sys.exit(3) +def get_new_session_instance(): + new_engine = create_engine(u'sqlite:///{0}'.format(cli.settings_path), echo=False) + new_session = scoped_session(sessionmaker()) + new_session.configure(bind=new_engine) + + atexit.register(lambda: new_session.remove() if new_session else True) + + return new_session + + def dispose(): global session @@ -853,5 +890,5 @@ def session_commit(success=None, _session=None): log.info(success) except (exc.OperationalError, exc.InvalidRequestError) as e: s.rollback() - log.debug_or_exception(e) + log.error_or_exception(e) return "" diff --git a/cps/updater.py b/cps/updater.py index 2166b334..021df005 100644 --- a/cps/updater.py +++ b/cps/updater.py @@ -117,7 +117,7 @@ class Updater(threading.Thread): except (IOError, OSError) as ex: self.status = 12 log.error(u'Possible Reason for error: update file could not be saved in temp dir') - log.debug_or_exception(ex) + log.error_or_exception(ex) self.pause() return False @@ -214,7 +214,7 @@ class Updater(threading.Thread): if not os.path.exists(dst_dir): try: os.makedirs(dst_dir) - log.debug('Create directory: {}', dst_dir) + log.debug('Create directory: {}'.format(dst_dir)) except OSError as e: log.error('Failed creating folder: {} with error {}'.format(dst_dir, e)) if change_permissions: @@ -233,7 +233,7 @@ class Updater(threading.Thread): permission = os.stat(dst_file) try: os.remove(dst_file) - log.debug('Remove file before copy: %s', dst_file) + log.debug('Remove file before copy: {}'.format(dst_file)) except OSError as e: log.error('Failed removing file: {} with error {}'.format(dst_file, e)) else: @@ -398,7 +398,7 @@ class Updater(threading.Thread): os.sep + 'gdrive_credentials', os.sep + 'settings.yaml', os.sep + 'venv', os.sep + 'virtualenv', os.sep + 'access.log', os.sep + 'access.log1', os.sep + 'access.log2', os.sep + '.calibre-web.log.swp', os.sep + '_sqlite3.so', os.sep + 'cps' + os.sep + '.HOMEDIR', - os.sep + 'gmail.json', os.sep + 'exclude.txt' + os.sep + 'gmail.json', os.sep + 'exclude.txt', os.sep + 'cps' + os.sep + 'cache' ] try: with open(os.path.join(constants.BASE_DIR, "exclude.txt"), "r") as f: diff --git a/cps/uploader.py b/cps/uploader.py index 992d188c..276db326 100644 --- a/cps/uploader.py +++ b/cps/uploader.py @@ -107,52 +107,10 @@ def default_meta(tmp_file_path, original_file_name, original_file_extension): series="", series_id="", languages="", - publisher="") - - -def parse_xmp(pdf_file): - """ - Parse XMP Metadata and prepare for BookMeta object - """ - try: - xmp_info = pdf_file.getXmpMetadata() - except Exception as ex: - log.debug('Can not read XMP metadata {}'.format(ex)) - return None - - if xmp_info: - try: - xmp_author = xmp_info.dc_creator # list - except AttributeError: - xmp_author = [''] - - if xmp_info.dc_title: - xmp_title = xmp_info.dc_title['x-default'] - else: - xmp_title = '' - - if xmp_info.dc_description: - xmp_description = xmp_info.dc_description['x-default'] - else: - xmp_description = '' - - languages = [] - try: - for i in xmp_info.dc_language: - #calibre-web currently only takes one language. - languages.append(isoLanguages.get_lang3(i)) - except AttributeError: - languages.append('') - - xmp_tags = ', '.join(xmp_info.dc_subject) - xmp_publisher = ', '.join(xmp_info.dc_publisher) - - return {'author': xmp_author, - 'title': xmp_title, - 'subject': xmp_description, - 'tags': xmp_tags, 'languages': languages, - 'publisher': xmp_publisher - } + publisher="", + pubdate="", + identifiers=[] + ) def parse_xmp(pdf_file): @@ -231,7 +189,7 @@ def pdf_meta(tmp_file_path, original_file_name, original_file_extension): if title == '': title = doc_info.title if doc_info.title else original_file_name if subject == '': - subject = doc_info.subject + subject = doc_info.subject or "" if tags == '' and '/Keywords' in doc_info: if isinstance(doc_info['/Keywords'], bytes): tags = doc_info['/Keywords'].decode('utf-8') @@ -251,7 +209,9 @@ def pdf_meta(tmp_file_path, original_file_name, original_file_extension): series="", series_id="", languages=','.join(languages), - publisher=publisher) + publisher=publisher, + pubdate="", + identifiers=[]) def pdf_preview(tmp_file_path, tmp_dir): diff --git a/cps/usermanagement.py b/cps/usermanagement.py index 71da7701..62fe6f77 100644 --- a/cps/usermanagement.py +++ b/cps/usermanagement.py @@ -18,6 +18,7 @@ import base64 import binascii +from functools import wraps from sqlalchemy.sql.expression import func from werkzeug.security import check_password_hash @@ -25,10 +26,6 @@ from flask_login import login_required, login_user from . import lm, ub, config, constants, services -try: - from functools import wraps -except ImportError: - pass # We're not using Python 3 def login_required_if_no_ano(func): @wraps(func) diff --git a/cps/web.py b/cps/web.py index 6d33f809..f3c97700 100644 --- a/cps/web.py +++ b/cps/web.py @@ -26,9 +26,10 @@ import json import mimetypes import chardet # dependency of requests import copy +from functools import wraps from babel.dates import format_date -from babel import Locale as LC +from babel import Locale from flask import Blueprint, jsonify from flask import request, redirect, send_from_directory, make_response, flash, abort, url_for from flask import session as flask_session @@ -49,7 +50,7 @@ from . import babel, db, ub, config, get_locale, app from . import calibre_db, kobo_sync_status from .gdriveutils import getFileFromEbooksFolder, do_gdrive_download from .helper import check_valid_domain, render_task_status, check_email, check_username, \ - get_cc_columns, get_book_cover, get_download_link, send_mail, generate_random_password, \ + get_book_cover, get_series_cover_thumbnail, get_download_link, send_mail, generate_random_password, \ send_registration_mail, check_send_to_kindle, check_read_formats, tags_filters, reset_password, valid_email, \ edit_book_read_status from .pagination import Pagination @@ -67,15 +68,12 @@ feature_support = { try: from .oauth_bb import oauth_check, register_user_with_oauth, logout_oauth_user, get_oauth_status + feature_support['oauth'] = True except ImportError: feature_support['oauth'] = False oauth_check = {} - -try: - from functools import wraps -except ImportError: - pass # We're not using Python 3 + register_user_with_oauth = logout_oauth_user = get_oauth_status = None try: from natsort import natsorted as sort @@ -85,8 +83,14 @@ except ImportError: @app.after_request def add_security_headers(resp): - resp.headers['Content-Security-Policy'] = "default-src 'self'" + ''.join([' '+host for host in config.config_trustedhosts.strip().split(',')]) + " 'unsafe-inline' 'unsafe-eval'; font-src 'self' data:; img-src 'self' data:" - if request.endpoint == "editbook.edit_book" or config.config_use_google_drive: + csp = "default-src 'self'" + csp += ''.join([' ' + host for host in config.config_trustedhosts.strip().split(',')]) + csp += " 'unsafe-inline' 'unsafe-eval'; font-src 'self' data:; img-src 'self' " + if request.path.startswith("/author/") and config.config_use_goodreads: + csp += "images.gr-assets.com i.gr-assets.com s.gr-assets.com" + csp += " data:" + resp.headers['Content-Security-Policy'] = csp + if request.endpoint == "edit-book.show_edit_book" or config.config_use_google_drive: resp.headers['Content-Security-Policy'] += " *" elif request.endpoint == "web.read_book": resp.headers['Content-Security-Policy'] += " blob:;style-src-elem 'self' blob: 'unsafe-inline';" @@ -96,6 +100,7 @@ def add_security_headers(resp): resp.headers['Strict-Transport-Security'] = 'max-age=31536000;' return resp + web = Blueprint('web', __name__) log = logger.create() @@ -122,19 +127,20 @@ def viewer_required(f): return inner + # ################################### data provider functions ######################################################### @web.route("/ajax/emailstat") @login_required def get_email_status_json(): - tasks = WorkerThread.getInstance().tasks + tasks = WorkerThread.get_instance().tasks return jsonify(render_task_status(tasks)) @web.route("/ajax/bookmark//", methods=['POST']) @login_required -def bookmark(book_id, book_format): +def set_bookmark(book_id, book_format): bookmark_key = request.form["bookmark"] ub.session.query(ub.Bookmark).filter(and_(ub.Bookmark.user_id == int(current_user.id), ub.Bookmark.book_id == book_id, @@ -143,11 +149,11 @@ def bookmark(book_id, book_format): ub.session_commit() return "", 204 - lbookmark = ub.Bookmark(user_id=current_user.id, - book_id=book_id, - format=book_format, - bookmark_key=bookmark_key) - ub.session.merge(lbookmark) + l_bookmark = ub.Bookmark(user_id=current_user.id, + book_id=book_id, + format=book_format, + bookmark_key=bookmark_key) + ub.session.merge(l_bookmark) ub.session_commit("Bookmark for user {} in book {} created".format(current_user.id, book_id)) return "", 201 @@ -165,7 +171,7 @@ def toggle_read(book_id): @web.route("/ajax/togglearchived/", methods=['POST']) @login_required def toggle_archived(book_id): - is_archived = change_archived_books(book_id, message="Book {} archivebit toggled".format(book_id)) + is_archived = change_archived_books(book_id, message="Book {} archive bit toggled".format(book_id)) if is_archived: remove_synced_book(book_id) return "" @@ -233,6 +239,7 @@ def get_comic_book(book_id, book_format, page): return "", 204 ''' + # ################################### Typeahead ################################################################## @@ -300,47 +307,63 @@ def get_matching_tags(): return json_dumps -def get_sort_function(sort, data): +def generate_char_list(entries): # data_colum, db_link): + char_list = list() + for entry in entries: + upper_char = entry[0].name[0].upper() + if upper_char not in char_list: + char_list.append(upper_char) + return char_list + + +def query_char_list(data_colum, db_link): + results = (calibre_db.session.query(func.upper(func.substr(data_colum, 1, 1)).label('char')) + .join(db_link).join(db.Books).filter(calibre_db.common_filters()) + .group_by(func.upper(func.substr(data_colum, 1, 1))).all()) + return results + + +def get_sort_function(sort_param, data): order = [db.Books.timestamp.desc()] - if sort == 'stored': - sort = current_user.get_view_property(data, 'stored') + if sort_param == 'stored': + sort_param = current_user.get_view_property(data, 'stored') else: - current_user.set_view_property(data, 'stored', sort) - if sort == 'pubnew': + current_user.set_view_property(data, 'stored', sort_param) + if sort_param == 'pubnew': order = [db.Books.pubdate.desc()] - if sort == 'pubold': + if sort_param == 'pubold': order = [db.Books.pubdate] - if sort == 'abc': + if sort_param == 'abc': order = [db.Books.sort] - if sort == 'zyx': + if sort_param == 'zyx': order = [db.Books.sort.desc()] - if sort == 'new': + if sort_param == 'new': order = [db.Books.timestamp.desc()] - if sort == 'old': + if sort_param == 'old': order = [db.Books.timestamp] - if sort == 'authaz': + if sort_param == 'authaz': order = [db.Books.author_sort.asc(), db.Series.name, db.Books.series_index] - if sort == 'authza': + if sort_param == 'authza': order = [db.Books.author_sort.desc(), db.Series.name.desc(), db.Books.series_index.desc()] - if sort == 'seriesasc': + if sort_param == 'seriesasc': order = [db.Books.series_index.asc()] - if sort == 'seriesdesc': + if sort_param == 'seriesdesc': order = [db.Books.series_index.desc()] - if sort == 'hotdesc': + if sort_param == 'hotdesc': order = [func.count(ub.Downloads.book_id).desc()] - if sort == 'hotasc': + if sort_param == 'hotasc': order = [func.count(ub.Downloads.book_id).asc()] - if sort is None: - sort = "new" - return order, sort + if sort_param is None: + sort_param = "new" + return order, sort_param -def render_books_list(data, sort, book_id, page): - order = get_sort_function(sort, data) +def render_books_list(data, sort_param, book_id, page): + order = get_sort_function(sort_param, data) if data == "rated": return render_rated_books(page, book_id, order=order) elif data == "discover": - return render_discover_books(page, book_id) + return render_discover_books(book_id) elif data == "unread": return render_read_books(page, False, order=order) elif data == "read": @@ -370,13 +393,13 @@ def render_books_list(data, sort, book_id, page): offset = int(int(config.config_books_per_page) * (page - 1)) return render_search_results(term, offset, order, config.config_books_per_page) elif data == "advsearch": - term = json.loads(flask_session['query']) + term = json.loads(flask_session.get('query', '{}')) offset = int(int(config.config_books_per_page) * (page - 1)) return render_adv_search_results(term, offset, order, config.config_books_per_page) else: website = data or "newest" entries, random, pagination = calibre_db.fill_indexpage(page, 0, db.Books, True, order[0], - False, 0, + True, config.config_read_column, db.books_series_link, db.Books.id == db.books_series_link.c.book, db.Series) @@ -390,7 +413,7 @@ def render_rated_books(page, book_id, order): db.Books, db.Books.ratings.any(db.Ratings.rating > 9), order[0], - False, 0, + True, config.config_read_column, db.books_series_link, db.Books.id == db.books_series_link.c.book, db.Series) @@ -401,41 +424,48 @@ def render_rated_books(page, book_id, order): abort(404) -def render_discover_books(page, book_id): +def render_discover_books(book_id): if current_user.check_visibility(constants.SIDEBAR_RANDOM): - entries, __, pagination = calibre_db.fill_indexpage(page, 0, db.Books, True, [func.randomblob(2)]) + entries, __, ___ = calibre_db.fill_indexpage(1, 0, db.Books, True, [func.randomblob(2)], + join_archive_read=True, + config_read_column=config.config_read_column) pagination = Pagination(1, config.config_books_per_page, config.config_books_per_page) - return render_title_template('discover.html', entries=entries, pagination=pagination, id=book_id, + return render_title_template('index.html', random=false(), entries=entries, pagination=pagination, id=book_id, title=_(u"Discover (Random Books)"), page="discover") else: abort(404) + def render_hot_books(page, order): if current_user.check_visibility(constants.SIDEBAR_HOT): if order[1] not in ['hotasc', 'hotdesc']: - # Unary expression comparsion only working (for this expression) in sqlalchemy 1.4+ - #if not (order[0][0].compare(func.count(ub.Downloads.book_id).desc()) or - # order[0][0].compare(func.count(ub.Downloads.book_id).asc())): + # Unary expression comparsion only working (for this expression) in sqlalchemy 1.4+ + # if not (order[0][0].compare(func.count(ub.Downloads.book_id).desc()) or + # order[0][0].compare(func.count(ub.Downloads.book_id).asc())): order = [func.count(ub.Downloads.book_id).desc()], 'hotdesc' if current_user.show_detail_random(): - random = calibre_db.session.query(db.Books).filter(calibre_db.common_filters()) \ - .order_by(func.random()).limit(config.config_random_books) + random_query = calibre_db.generate_linked_query(config.config_read_column, db.Books) + random = (random_query.filter(calibre_db.common_filters()) + .order_by(func.random()) + .limit(config.config_random_books).all()) else: random = false() + off = int(int(config.config_books_per_page) * (page - 1)) - all_books = ub.session.query(ub.Downloads, func.count(ub.Downloads.book_id))\ + all_books = ub.session.query(ub.Downloads, func.count(ub.Downloads.book_id)) \ .order_by(*order[0]).group_by(ub.Downloads.book_id) hot_books = all_books.offset(off).limit(config.config_books_per_page) entries = list() for book in hot_books: - downloadBook = calibre_db.session.query(db.Books).filter(calibre_db.common_filters()).filter( - db.Books.id == book.Downloads.book_id).first() - if downloadBook: - entries.append(downloadBook) + query = calibre_db.generate_linked_query(config.config_read_column, db.Books) + download_book = query.filter(calibre_db.common_filters()).filter( + book.Downloads.book_id == db.Books.id).first() + if download_book: + entries.append(download_book) else: ub.delete_download(book.Downloads.book_id) - numBooks = entries.__len__() - pagination = Pagination(page, config.config_books_per_page, numBooks) + num_books = entries.__len__() + pagination = Pagination(page, config.config_books_per_page, num_books) return render_title_template('index.html', random=random, entries=entries, pagination=pagination, title=_(u"Hot Books (Most Downloaded)"), page="hot", order=order[1]) else: @@ -448,33 +478,27 @@ def render_downloaded_books(page, order, user_id): else: user_id = current_user.id if current_user.check_visibility(constants.SIDEBAR_DOWNLOAD): - if current_user.show_detail_random(): - random = calibre_db.session.query(db.Books).filter(calibre_db.common_filters()) \ - .order_by(func.random()).limit(config.config_random_books) - else: - random = false() - - entries, __, pagination = calibre_db.fill_indexpage(page, + entries, random, pagination = calibre_db.fill_indexpage(page, 0, db.Books, ub.Downloads.user_id == user_id, order[0], - False, 0, + True, config.config_read_column, db.books_series_link, db.Books.id == db.books_series_link.c.book, db.Series, ub.Downloads, db.Books.id == ub.Downloads.book_id) for book in entries: - if not calibre_db.session.query(db.Books).filter(calibre_db.common_filters()) \ - .filter(db.Books.id == book.id).first(): - ub.delete_download(book.id) + if not (calibre_db.session.query(db.Books).filter(calibre_db.common_filters()) + .filter(db.Books.id == book.Books.id).first()): + ub.delete_download(book.Books.id) user = ub.session.query(ub.User).filter(ub.User.id == user_id).first() return render_title_template('index.html', random=random, entries=entries, pagination=pagination, id=user_id, - title=_(u"Downloaded books by %(user)s",user=user.name), + title=_(u"Downloaded books by %(user)s", user=user.name), page="download", order=order[1]) else: @@ -486,9 +510,9 @@ def render_author_books(page, author_id, order): db.Books, db.Books.authors.any(db.Authors.id == author_id), [order[0][0], db.Series.name, db.Books.series_index], - False, 0, + True, config.config_read_column, db.books_series_link, - db.Books.id == db.books_series_link.c.book, + db.books_series_link.c.book == db.Books.id, db.Series) if entries is None or not len(entries): flash(_(u"Oops! Selected book title is unavailable. File does not exist or is not accessible"), @@ -504,55 +528,100 @@ def render_author_books(page, author_id, order): other_books = [] if services.goodreads_support and config.config_use_goodreads: author_info = services.goodreads_support.get_author_info(author_name) - other_books = services.goodreads_support.get_other_books(author_info, entries) + book_entries = [entry.Books for entry in entries] + other_books = services.goodreads_support.get_other_books(author_info, book_entries) return render_title_template('author.html', entries=entries, pagination=pagination, id=author_id, title=_(u"Author: %(name)s", name=author_name), author=author_info, other_books=other_books, page="author", order=order[1]) def render_publisher_books(page, book_id, order): - publisher = calibre_db.session.query(db.Publishers).filter(db.Publishers.id == book_id).first() - if publisher: + if book_id == '-1': entries, random, pagination = calibre_db.fill_indexpage(page, 0, db.Books, - db.Books.publishers.any(db.Publishers.id == book_id), + db.Publishers.name == None, [db.Series.name, order[0][0], db.Books.series_index], - False, 0, + True, config.config_read_column, + db.books_publishers_link, + db.Books.id == db.books_publishers_link.c.book, + db.Publishers, db.books_series_link, db.Books.id == db.books_series_link.c.book, db.Series) - return render_title_template('index.html', random=random, entries=entries, pagination=pagination, id=book_id, - title=_(u"Publisher: %(name)s", name=publisher.name), - page="publisher", - order=order[1]) + publisher = _("None") else: - abort(404) + publisher = calibre_db.session.query(db.Publishers).filter(db.Publishers.id == book_id).first() + if publisher: + entries, random, pagination = calibre_db.fill_indexpage(page, 0, + db.Books, + db.Books.publishers.any( + db.Publishers.id == book_id), + [db.Series.name, order[0][0], + db.Books.series_index], + True, config.config_read_column, + db.books_series_link, + db.Books.id == db.books_series_link.c.book, + db.Series) + publisher = publisher.name + else: + abort(404) + + return render_title_template('index.html', random=random, entries=entries, pagination=pagination, id=book_id, + title=_(u"Publisher: %(name)s", name=publisher), + page="publisher", + order=order[1]) def render_series_books(page, book_id, order): - name = calibre_db.session.query(db.Series).filter(db.Series.id == book_id).first() - if name: + if book_id == '-1': entries, random, pagination = calibre_db.fill_indexpage(page, 0, db.Books, - db.Books.series.any(db.Series.id == book_id), - [order[0][0]]) - return render_title_template('index.html', random=random, pagination=pagination, entries=entries, id=book_id, - title=_(u"Series: %(serie)s", serie=name.name), page="series", order=order[1]) + db.Series.name == None, + [order[0][0]], + True, config.config_read_column, + db.books_series_link, + db.Books.id == db.books_series_link.c.book, + db.Series) + series_name = _("None") else: - abort(404) + series_name = calibre_db.session.query(db.Series).filter(db.Series.id == book_id).first() + if series_name: + entries, random, pagination = calibre_db.fill_indexpage(page, 0, + db.Books, + db.Books.series.any(db.Series.id == book_id), + [order[0][0]], + True, config.config_read_column) + series_name = series_name.name + else: + abort(404) + return render_title_template('index.html', random=random, pagination=pagination, entries=entries, id=book_id, + title=_(u"Series: %(serie)s", serie=series_name), page="series", order=order[1]) def render_ratings_books(page, book_id, order): - name = calibre_db.session.query(db.Ratings).filter(db.Ratings.id == book_id).first() - entries, random, pagination = calibre_db.fill_indexpage(page, 0, - db.Books, - db.Books.ratings.any(db.Ratings.id == book_id), - [order[0][0]]) - if name and name.rating <= 10: + if book_id == '-1': + entries, random, pagination = calibre_db.fill_indexpage(page, 0, + db.Books, + db.Books.ratings == None, + [order[0][0]], + True, config.config_read_column, + db.books_series_link, + db.Books.id == db.books_series_link.c.book, + db.Series) + title = _(u"Rating: None") + rating = -1 + else: + name = calibre_db.session.query(db.Ratings).filter(db.Ratings.id == book_id).first() + entries, random, pagination = calibre_db.fill_indexpage(page, 0, + db.Books, + db.Books.ratings.any(db.Ratings.id == book_id), + [order[0][0]], + True, config.config_read_column) + title = _(u"Rating: %(rating)s stars", rating=int(name.rating / 2)) + rating = name.rating + if title and rating <= 10: return render_title_template('index.html', random=random, pagination=pagination, entries=entries, id=book_id, - title=_(u"Rating: %(rating)s stars", rating=int(name.rating / 2)), - page="ratings", - order=order[1]) + title=title, page="ratings", order=order[1]) else: abort(404) @@ -563,7 +632,8 @@ def render_formats_books(page, book_id, order): entries, random, pagination = calibre_db.fill_indexpage(page, 0, db.Books, db.Books.data.any(db.Data.format == book_id.upper()), - [order[0][0]]) + [order[0][0]], + True, config.config_read_column) return render_title_template('index.html', random=random, pagination=pagination, entries=entries, id=book_id, title=_(u"File format: %(format)s", format=name.format), page="formats", @@ -573,97 +643,116 @@ def render_formats_books(page, book_id, order): def render_category_books(page, book_id, order): - name = calibre_db.session.query(db.Tags).filter(db.Tags.id == book_id).first() - if name: + if book_id == '-1': entries, random, pagination = calibre_db.fill_indexpage(page, 0, db.Books, - db.Books.tags.any(db.Tags.id == book_id), + db.Tags.name == None, [order[0][0], db.Series.name, db.Books.series_index], - False, 0, + True, config.config_read_column, + db.books_tags_link, + db.Books.id == db.books_tags_link.c.book, + db.Tags, db.books_series_link, db.Books.id == db.books_series_link.c.book, db.Series) - return render_title_template('index.html', random=random, entries=entries, pagination=pagination, id=book_id, - title=_(u"Category: %(name)s", name=name.name), page="category", order=order[1]) + tagsname = _("None") else: - abort(404) + tagsname = calibre_db.session.query(db.Tags).filter(db.Tags.id == book_id).first() + if tagsname: + entries, random, pagination = calibre_db.fill_indexpage(page, 0, + db.Books, + db.Books.tags.any(db.Tags.id == book_id), + [order[0][0], db.Series.name, + db.Books.series_index], + True, config.config_read_column, + db.books_series_link, + db.Books.id == db.books_series_link.c.book, + db.Series) + tagsname = tagsname.name + else: + abort(404) + return render_title_template('index.html', random=random, entries=entries, pagination=pagination, id=book_id, + title=_(u"Category: %(name)s", name=tagsname), page="category", order=order[1]) def render_language_books(page, name, order): try: - lang_name = isoLanguages.get_language_name(get_locale(), name) + if name.lower() != "none": + lang_name = isoLanguages.get_language_name(get_locale(), name) + else: + lang_name = _("None") except KeyError: abort(404) - - entries, random, pagination = calibre_db.fill_indexpage(page, 0, - db.Books, - db.Books.languages.any(db.Languages.lang_code == name), - [order[0][0]]) + if name == "none": + entries, random, pagination = calibre_db.fill_indexpage(page, 0, + db.Books, + db.Languages.lang_code == None, + [order[0][0]], + True, config.config_read_column, + db.books_languages_link, + db.Books.id == db.books_languages_link.c.book, + db.Languages) + else: + entries, random, pagination = calibre_db.fill_indexpage(page, 0, + db.Books, + db.Books.languages.any(db.Languages.lang_code == name), + [order[0][0]], + True, config.config_read_column) return render_title_template('index.html', random=random, entries=entries, pagination=pagination, id=name, title=_(u"Language: %(name)s", name=lang_name), page="language", order=order[1]) def render_read_books(page, are_read, as_xml=False, order=None): - sort = order[0] if order else [] + sort_param = order[0] if order else [] if not config.config_read_column: if are_read: db_filter = and_(ub.ReadBook.user_id == int(current_user.id), ub.ReadBook.read_status == ub.ReadBook.STATUS_FINISHED) else: db_filter = coalesce(ub.ReadBook.read_status, 0) != ub.ReadBook.STATUS_FINISHED - entries, random, pagination = calibre_db.fill_indexpage(page, 0, - db.Books, - db_filter, - sort, - False, 0, - db.books_series_link, - db.Books.id == db.books_series_link.c.book, - db.Series, - ub.ReadBook, db.Books.id == ub.ReadBook.book_id) else: try: if are_read: db_filter = db.cc_classes[config.config_read_column].value == True else: db_filter = coalesce(db.cc_classes[config.config_read_column].value, False) != True - entries, random, pagination = calibre_db.fill_indexpage(page, 0, - db.Books, - db_filter, - sort, - False, 0, - db.books_series_link, - db.Books.id == db.books_series_link.c.book, - db.Series, - db.cc_classes[config.config_read_column]) - except (KeyError, AttributeError): - log.error("Custom Column No.%d is not existing in calibre database", config.config_read_column) + except (KeyError, AttributeError, IndexError): + log.error("Custom Column No.{} is not existing in calibre database".format(config.config_read_column)) if not as_xml: flash(_("Custom Column No.%(column)d is not existing in calibre database", column=config.config_read_column), category="error") return redirect(url_for("web.index")) - # ToDo: Handle error Case for opds + return [] # ToDo: Handle error Case for opds + + entries, random, pagination = calibre_db.fill_indexpage(page, 0, + db.Books, + db_filter, + sort_param, + True, config.config_read_column, + db.books_series_link, + db.Books.id == db.books_series_link.c.book, + db.Series) + if as_xml: return entries, pagination else: if are_read: name = _(u'Read Books') + ' (' + str(pagination.total_count) + ')' - pagename = "read" + page_name = "read" else: name = _(u'Unread Books') + ' (' + str(pagination.total_count) + ')' - pagename = "unread" + page_name = "unread" return render_title_template('index.html', random=random, entries=entries, pagination=pagination, - title=name, page=pagename, order=order[1]) + title=name, page=page_name, order=order[1]) -def render_archived_books(page, sort): - order = sort[0] or [] - archived_books = ( - ub.session.query(ub.ArchivedBook) - .filter(ub.ArchivedBook.user_id == int(current_user.id)) - .filter(ub.ArchivedBook.is_archived == True) - .all() - ) +def render_archived_books(page, sort_param): + order = sort_param[0] or [] + archived_books = (ub.session.query(ub.ArchivedBook) + .filter(ub.ArchivedBook.user_id == int(current_user.id)) + .filter(ub.ArchivedBook.is_archived == True) + .all()) archived_book_ids = [archived_book.book_id for archived_book in archived_books] archived_filter = db.Books.id.in_(archived_book_ids) @@ -673,53 +762,52 @@ def render_archived_books(page, sort): archived_filter, order, True, - False, 0) + True, config.config_read_column) name = _(u'Archived Books') + ' (' + str(len(archived_book_ids)) + ')' - pagename = "archived" + page_name = "archived" return render_title_template('index.html', random=random, entries=entries, pagination=pagination, - title=name, page=pagename, order=sort[1]) + title=name, page=page_name, order=sort_param[1]) def render_prepare_search_form(cc): # prepare data for search-form - tags = calibre_db.session.query(db.Tags)\ - .join(db.books_tags_link)\ - .join(db.Books)\ + tags = calibre_db.session.query(db.Tags) \ + .join(db.books_tags_link) \ + .join(db.Books) \ .filter(calibre_db.common_filters()) \ - .group_by(text('books_tags_link.tag'))\ + .group_by(text('books_tags_link.tag')) \ .order_by(db.Tags.name).all() - series = calibre_db.session.query(db.Series)\ - .join(db.books_series_link)\ - .join(db.Books)\ + series = calibre_db.session.query(db.Series) \ + .join(db.books_series_link) \ + .join(db.Books) \ .filter(calibre_db.common_filters()) \ - .group_by(text('books_series_link.series'))\ - .order_by(db.Series.name)\ + .group_by(text('books_series_link.series')) \ + .order_by(db.Series.name) \ .filter(calibre_db.common_filters()).all() - shelves = ub.session.query(ub.Shelf)\ - .filter(or_(ub.Shelf.is_public == 1, ub.Shelf.user_id == int(current_user.id)))\ + shelves = ub.session.query(ub.Shelf) \ + .filter(or_(ub.Shelf.is_public == 1, ub.Shelf.user_id == int(current_user.id))) \ .order_by(ub.Shelf.name).all() - extensions = calibre_db.session.query(db.Data)\ - .join(db.Books)\ + extensions = calibre_db.session.query(db.Data) \ + .join(db.Books) \ .filter(calibre_db.common_filters()) \ - .group_by(db.Data.format)\ + .group_by(db.Data.format) \ .order_by(db.Data.format).all() if current_user.filter_language() == u"all": languages = calibre_db.speaking_language() else: languages = None return render_title_template('search_form.html', tags=tags, languages=languages, extensions=extensions, - series=series,shelves=shelves, title=_(u"Advanced Search"), cc=cc, page="advsearch") + series=series, shelves=shelves, title=_(u"Advanced Search"), cc=cc, page="advsearch") def render_search_results(term, offset=None, order=None, limit=None): - join = db.books_series_link, db.Books.id == db.books_series_link.c.book, db.Series + join = db.books_series_link, db.books_series_link.c.book == db.Books.id, db.Series entries, result_count, pagination = calibre_db.get_search_results(term, + config, offset, order, limit, - False, - config.config_read_column, *join) return render_title_template('search.html', searchterm=term, @@ -757,78 +845,62 @@ def books_list(data, sort_param, book_id, page): @login_required def books_table(): visibility = current_user.view_settings.get('table', {}) - cc = get_cc_columns(filter_config_custom_read=True) + cc = calibre_db.get_cc_columns(config, filter_config_custom_read=True) return render_title_template('book_table.html', title=_(u"Books List"), cc=cc, page="book_table", visiblility=visibility) + @web.route("/ajax/listbooks") @login_required def list_books(): off = int(request.args.get("offset") or 0) limit = int(request.args.get("limit") or config.config_books_per_page) - search = request.args.get("search") - sort = request.args.get("sort", "id") + search_param = request.args.get("search") + sort_param = request.args.get("sort", "id") order = request.args.get("order", "").lower() state = None join = tuple() - if sort == "state": + if sort_param == "state": state = json.loads(request.args.get("state", "[]")) - elif sort == "tags": + elif sort_param == "tags": order = [db.Tags.name.asc()] if order == "asc" else [db.Tags.name.desc()] join = db.books_tags_link, db.Books.id == db.books_tags_link.c.book, db.Tags - elif sort == "series": + elif sort_param == "series": order = [db.Series.name.asc()] if order == "asc" else [db.Series.name.desc()] join = db.books_series_link, db.Books.id == db.books_series_link.c.book, db.Series - elif sort == "publishers": + elif sort_param == "publishers": order = [db.Publishers.name.asc()] if order == "asc" else [db.Publishers.name.desc()] join = db.books_publishers_link, db.Books.id == db.books_publishers_link.c.book, db.Publishers - elif sort == "authors": + elif sort_param == "authors": order = [db.Authors.name.asc(), db.Series.name, db.Books.series_index] if order == "asc" \ else [db.Authors.name.desc(), db.Series.name.desc(), db.Books.series_index.desc()] - join = db.books_authors_link, db.Books.id == db.books_authors_link.c.book, db.Authors, \ - db.books_series_link, db.Books.id == db.books_series_link.c.book, db.Series - elif sort == "languages": + join = db.books_authors_link, db.Books.id == db.books_authors_link.c.book, db.Authors, db.books_series_link, \ + db.Books.id == db.books_series_link.c.book, db.Series + elif sort_param == "languages": order = [db.Languages.lang_code.asc()] if order == "asc" else [db.Languages.lang_code.desc()] join = db.books_languages_link, db.Books.id == db.books_languages_link.c.book, db.Languages - elif order and sort in ["sort", "title", "authors_sort", "series_index"]: - order = [text(sort + " " + order)] + elif order and sort_param in ["sort", "title", "authors_sort", "series_index"]: + order = [text(sort_param + " " + order)] elif not state: order = [db.Books.timestamp.desc()] - total_count = filtered_count = calibre_db.session.query(db.Books).filter(calibre_db.common_filters(allow_show_archived=True)).count() + total_count = filtered_count = calibre_db.session.query(db.Books).filter( + calibre_db.common_filters(allow_show_archived=True)).count() if state is not None: - if search: - books = calibre_db.search_query(search, config.config_read_column).all() + if search_param: + books = calibre_db.search_query(search_param, config).all() filtered_count = len(books) else: - if not config.config_read_column: - books = (calibre_db.session.query(db.Books, ub.ReadBook.read_status, ub.ArchivedBook.is_archived) - .select_from(db.Books) - .outerjoin(ub.ReadBook, - and_(ub.ReadBook.user_id == int(current_user.id), - ub.ReadBook.book_id == db.Books.id))) - else: - try: - read_column = db.cc_classes[config.config_read_column] - books = (calibre_db.session.query(db.Books, read_column.value, ub.ArchivedBook.is_archived) - .select_from(db.Books) - .outerjoin(read_column, read_column.book == db.Books.id)) - except (KeyError, AttributeError): - log.error("Custom Column No.%d is not existing in calibre database", read_column) - # Skip linking read column and return None instead of read status - books =calibre_db.session.query(db.Books, None, ub.ArchivedBook.is_archived) - books = (books.outerjoin(ub.ArchivedBook, and_(db.Books.id == ub.ArchivedBook.book_id, - int(current_user.id) == ub.ArchivedBook.user_id)) - .filter(calibre_db.common_filters(allow_show_archived=True)).all()) + query = calibre_db.generate_linked_query(config.config_read_column, db.Books) + books = query.filter(calibre_db.common_filters(allow_show_archived=True)).all() entries = calibre_db.get_checkbox_sorted(books, state, off, limit, order, True) - elif search: - entries, filtered_count, __ = calibre_db.get_search_results(search, + elif search_param: + entries, filtered_count, __ = calibre_db.get_search_results(search_param, + config, off, - [order,''], + [order, ''], limit, - True, - config.config_read_column, *join) else: entries, __, __ = calibre_db.fill_indexpage_with_archived_books((int(off) / (int(limit)) + 1), @@ -844,11 +916,11 @@ def list_books(): result = list() for entry in entries: val = entry[0] - val.read_status = entry[1] == ub.ReadBook.STATUS_FINISHED - val.is_archived = entry[2] is True - for index in range(0, len(val.languages)): - val.languages[index].language_name = isoLanguages.get_language_name(get_locale(), val.languages[ - index].lang_code) + val.is_archived = entry[1] is True + val.read_status = entry[2] == ub.ReadBook.STATUS_FINISHED + for lang_index in range(0, len(val.languages)): + val.languages[lang_index].language_name = isoLanguages.get_language_name(get_locale(), val.languages[ + lang_index].lang_code) result.append(val) table_entries = {'totalNotFiltered': total_count, 'total': filtered_count, "rows": result} @@ -858,6 +930,7 @@ def list_books(): response.headers["Content-Type"] = "application/json; charset=utf-8" return response + @web.route("/ajax/table_settings", methods=['POST']) @login_required def update_table_settings(): @@ -887,19 +960,18 @@ def author_list(): entries = calibre_db.session.query(db.Authors, func.count('books_authors_link.book').label('count')) \ .join(db.books_authors_link).join(db.Books).filter(calibre_db.common_filters()) \ .group_by(text('books_authors_link.author')).order_by(order).all() - charlist = calibre_db.session.query(func.upper(func.substr(db.Authors.sort, 1, 1)).label('char')) \ - .join(db.books_authors_link).join(db.Books).filter(calibre_db.common_filters()) \ - .group_by(func.upper(func.substr(db.Authors.sort, 1, 1))).all() + char_list = query_char_list(db.Authors.sort, db.books_authors_link) # If not creating a copy, readonly databases can not display authornames with "|" in it as changing the name # starts a change session - autor_copy = copy.deepcopy(entries) - for entry in autor_copy: + author_copy = copy.deepcopy(entries) + for entry in author_copy: entry.Authors.name = entry.Authors.name.replace('|', ',') - return render_title_template('list.html', entries=autor_copy, folder='web.books_list', charlist=charlist, + return render_title_template('list.html', entries=author_copy, folder='web.books_list', charlist=char_list, title=u"Authors", page="authorlist", data='author', order=order_no) else: abort(404) + @web.route("/downloadlist") @login_required_if_no_ano def download_list(): @@ -910,12 +982,12 @@ def download_list(): order = ub.User.name.asc() order_no = 1 if current_user.check_visibility(constants.SIDEBAR_DOWNLOAD) and current_user.role_admin(): - entries = ub.session.query(ub.User, func.count(ub.Downloads.book_id).label('count'))\ + entries = ub.session.query(ub.User, func.count(ub.Downloads.book_id).label('count')) \ .join(ub.Downloads).group_by(ub.Downloads.user_id).order_by(order).all() - charlist = ub.session.query(func.upper(func.substr(ub.User.name, 1, 1)).label('char')) \ + char_list = ub.session.query(func.upper(func.substr(ub.User.name, 1, 1)).label('char')) \ .filter(ub.User.role.op('&')(constants.ROLE_ANONYMOUS) != constants.ROLE_ANONYMOUS) \ .group_by(func.upper(func.substr(ub.User.name, 1, 1))).all() - return render_title_template('list.html', entries=entries, folder='web.books_list', charlist=charlist, + return render_title_template('list.html', entries=entries, folder='web.books_list', charlist=char_list, title=_(u"Downloads"), page="downloadlist", data="download", order=order_no) else: abort(404) @@ -934,10 +1006,16 @@ def publisher_list(): entries = calibre_db.session.query(db.Publishers, func.count('books_publishers_link.book').label('count')) \ .join(db.books_publishers_link).join(db.Books).filter(calibre_db.common_filters()) \ .group_by(text('books_publishers_link.publisher')).order_by(order).all() - charlist = calibre_db.session.query(func.upper(func.substr(db.Publishers.name, 1, 1)).label('char')) \ - .join(db.books_publishers_link).join(db.Books).filter(calibre_db.common_filters()) \ - .group_by(func.upper(func.substr(db.Publishers.name, 1, 1))).all() - return render_title_template('list.html', entries=entries, folder='web.books_list', charlist=charlist, + no_publisher_count = (calibre_db.session.query(db.Books) + .outerjoin(db.books_publishers_link).outerjoin(db.Publishers) + .filter(db.Publishers.name == None) + .filter(calibre_db.common_filters()) + .count()) + if no_publisher_count: + entries.append([db.Category(_("None"), "-1"), no_publisher_count]) + entries = sorted(entries, key=lambda x: x[0].name, reverse=not order_no) + char_list = generate_char_list(entries) + return render_title_template('list.html', entries=entries, folder='web.books_list', charlist=char_list, title=_(u"Publishers"), page="publisherlist", data="publisher", order=order_no) else: abort(404) @@ -953,25 +1031,27 @@ def series_list(): else: order = db.Series.sort.asc() order_no = 1 + char_list = query_char_list(db.Series.sort, db.books_series_link) if current_user.get_view_property('series', 'series_view') == 'list': entries = calibre_db.session.query(db.Series, func.count('books_series_link.book').label('count')) \ .join(db.books_series_link).join(db.Books).filter(calibre_db.common_filters()) \ .group_by(text('books_series_link.series')).order_by(order).all() - charlist = calibre_db.session.query(func.upper(func.substr(db.Series.sort, 1, 1)).label('char')) \ - .join(db.books_series_link).join(db.Books).filter(calibre_db.common_filters()) \ - .group_by(func.upper(func.substr(db.Series.sort, 1, 1))).all() - return render_title_template('list.html', entries=entries, folder='web.books_list', charlist=charlist, + no_series_count = (calibre_db.session.query(db.Books) + .outerjoin(db.books_series_link).outerjoin(db.Series) + .filter(db.Series.name == None) + .filter(calibre_db.common_filters()) + .count()) + if no_series_count: + entries.append([db.Category(_("None"), "-1"), no_series_count]) + entries = sorted(entries, key=lambda x: x[0].name, reverse=not order_no) + return render_title_template('list.html', entries=entries, folder='web.books_list', charlist=char_list, title=_(u"Series"), page="serieslist", data="series", order=order_no) else: entries = calibre_db.session.query(db.Books, func.count('books_series_link').label('count'), func.max(db.Books.series_index), db.Books.id) \ - .join(db.books_series_link).join(db.Series).filter(calibre_db.common_filters())\ + .join(db.books_series_link).join(db.Series).filter(calibre_db.common_filters()) \ .group_by(text('books_series_link.series')).order_by(order).all() - charlist = calibre_db.session.query(func.upper(func.substr(db.Series.sort, 1, 1)).label('char')) \ - .join(db.books_series_link).join(db.Books).filter(calibre_db.common_filters()) \ - .group_by(func.upper(func.substr(db.Series.sort, 1, 1))).all() - - return render_title_template('grid.html', entries=entries, folder='web.books_list', charlist=charlist, + return render_title_template('grid.html', entries=entries, folder='web.books_list', charlist=char_list, title=_(u"Series"), page="serieslist", data="series", bodyClass="grid-view", order=order_no) else: @@ -989,9 +1069,16 @@ def ratings_list(): order = db.Ratings.rating.asc() order_no = 1 entries = calibre_db.session.query(db.Ratings, func.count('books_ratings_link.book').label('count'), - (db.Ratings.rating / 2).label('name')) \ + (db.Ratings.rating / 2).label('name')) \ .join(db.books_ratings_link).join(db.Books).filter(calibre_db.common_filters()) \ .group_by(text('books_ratings_link.rating')).order_by(order).all() + no_rating_count = (calibre_db.session.query(db.Books) + .outerjoin(db.books_ratings_link).outerjoin(db.Ratings) + .filter(db.Ratings.rating == None) + .filter(calibre_db.common_filters()) + .count()) + entries.append([db.Category(_("None"), "-1", -1), no_rating_count]) + entries = sorted(entries, key=lambda x: x[0].rating, reverse=not order_no) return render_title_template('list.html', entries=entries, folder='web.books_list', charlist=list(), title=_(u"Ratings list"), page="ratingslist", data="ratings", order=order_no) else: @@ -1013,6 +1100,12 @@ def formats_list(): db.Data.format.label('format')) \ .join(db.Books).filter(calibre_db.common_filters()) \ .group_by(db.Data.format).order_by(order).all() + no_format_count = (calibre_db.session.query(db.Books).outerjoin(db.Data) + .filter(db.Data.format == None) + .filter(calibre_db.common_filters()) + .count()) + if no_format_count: + entries.append([db.Category(_("None"), "-1"), no_format_count]) return render_title_template('list.html', entries=entries, folder='web.books_list', charlist=list(), title=_(u"File formats list"), page="formatslist", data="formats", order=order_no) else: @@ -1024,15 +1117,10 @@ def formats_list(): def language_overview(): if current_user.check_visibility(constants.SIDEBAR_LANGUAGE) and current_user.filter_language() == u"all": order_no = 0 if current_user.get_view_property('language', 'dir') == 'desc' else 1 - charlist = list() languages = calibre_db.speaking_language(reverse_order=not order_no, with_count=True) - for lang in languages: - upper_lang = lang[0].name[0].upper() - if upper_lang not in charlist: - charlist.append(upper_lang) - return render_title_template('languages.html', languages=languages, - charlist=charlist, title=_(u"Languages"), page="langlist", - data="language", order=order_no) + char_list = generate_char_list(languages) + return render_title_template('list.html', entries=languages, folder='web.books_list', charlist=char_list, + title=_(u"Languages"), page="langlist", data="language", order=order_no) else: abort(404) @@ -1050,10 +1138,16 @@ def category_list(): entries = calibre_db.session.query(db.Tags, func.count('books_tags_link.book').label('count')) \ .join(db.books_tags_link).join(db.Books).order_by(order).filter(calibre_db.common_filters()) \ .group_by(text('books_tags_link.tag')).all() - charlist = calibre_db.session.query(func.upper(func.substr(db.Tags.name, 1, 1)).label('char')) \ - .join(db.books_tags_link).join(db.Books).filter(calibre_db.common_filters()) \ - .group_by(func.upper(func.substr(db.Tags.name, 1, 1))).all() - return render_title_template('list.html', entries=entries, folder='web.books_list', charlist=charlist, + no_tag_count = (calibre_db.session.query(db.Books) + .outerjoin(db.books_tags_link).outerjoin(db.Tags) + .filter(db.Tags.name == None) + .filter(calibre_db.common_filters()) + .count()) + if no_tag_count: + entries.append([db.Category(_("None"), "-1"), no_tag_count]) + entries = sorted(entries, key=lambda x: x[0].name, reverse=not order_no) + char_list = generate_char_list(entries) + return render_title_template('list.html', entries=entries, folder='web.books_list', charlist=char_list, title=_(u"Categories"), page="catlist", data="category", order=order_no) else: abort(404) @@ -1066,7 +1160,7 @@ def category_list(): @login_required def get_tasks_status(): # if current user admin, show all email, otherwise only own emails - tasks = WorkerThread.getInstance().tasks + tasks = WorkerThread.get_instance().tasks answer = render_task_status(tasks) return render_title_template('tasks.html', entries=answer, title=_(u"Tasks"), page="tasks") @@ -1128,27 +1222,6 @@ def adv_search_custom_columns(cc, term, q): return q -def adv_search_language(q, include_languages_inputs, exclude_languages_inputs): - if current_user.filter_language() != "all": - q = q.filter(db.Books.languages.any(db.Languages.lang_code == current_user.filter_language())) - else: - for language in include_languages_inputs: - q = q.filter(db.Books.languages.any(db.Languages.id == language)) - for language in exclude_languages_inputs: - q = q.filter(not_(db.Books.series.any(db.Languages.id == language))) - return q - - -def adv_search_ratings(q, rating_high, rating_low): - if rating_high: - rating_high = int(rating_high) * 2 - q = q.filter(db.Books.ratings.any(db.Ratings.rating <= rating_high)) - if rating_low: - rating_low = int(rating_low) * 2 - q = q.filter(db.Books.ratings.any(db.Ratings.rating >= rating_low)) - return q - - def adv_search_read_status(q, read_status): if read_status: if config.config_read_column: @@ -1159,8 +1232,9 @@ def adv_search_read_status(q, read_status): else: q = q.join(db.cc_classes[config.config_read_column], isouter=True) \ .filter(coalesce(db.cc_classes[config.config_read_column].value, False) != True) - except (KeyError, AttributeError): - log.error(u"Custom Column No.%d is not existing in calibre database", config.config_read_column) + except (KeyError, AttributeError, IndexError): + log.error( + "Custom Column No.{} is not existing in calibre database".format(config.config_read_column)) flash(_("Custom Column No.%(column)d is not existing in calibre database", column=config.config_read_column), category="error") @@ -1177,36 +1251,40 @@ def adv_search_read_status(q, read_status): return q -def adv_search_extension(q, include_extension_inputs, exclude_extension_inputs): - for extension in include_extension_inputs: - q = q.filter(db.Books.data.any(db.Data.format == extension)) - for extension in exclude_extension_inputs: - q = q.filter(not_(db.Books.data.any(db.Data.format == extension))) +def adv_search_language(q, include_languages_inputs, exclude_languages_inputs): + if current_user.filter_language() != "all": + q = q.filter(db.Books.languages.any(db.Languages.lang_code == current_user.filter_language())) + else: + return adv_search_text(q, include_languages_inputs, exclude_languages_inputs, db.Languages.id) return q -def adv_search_tag(q, include_tag_inputs, exclude_tag_inputs): - for tag in include_tag_inputs: - q = q.filter(db.Books.tags.any(db.Tags.id == tag)) - for tag in exclude_tag_inputs: - q = q.filter(not_(db.Books.tags.any(db.Tags.id == tag))) +def adv_search_ratings(q, rating_high, rating_low): + if rating_high: + rating_high = int(rating_high) * 2 + q = q.filter(db.Books.ratings.any(db.Ratings.rating <= rating_high)) + if rating_low: + rating_low = int(rating_low) * 2 + q = q.filter(db.Books.ratings.any(db.Ratings.rating >= rating_low)) return q -def adv_search_serie(q, include_series_inputs, exclude_series_inputs): - for serie in include_series_inputs: - q = q.filter(db.Books.series.any(db.Series.id == serie)) - for serie in exclude_series_inputs: - q = q.filter(not_(db.Books.series.any(db.Series.id == serie))) +def adv_search_text(q, include_inputs, exclude_inputs, data_table): + for inp in include_inputs: + q = q.filter(getattr(db.Books, data_table.class_.__tablename__).any(data_table == inp)) + for excl in exclude_inputs: + q = q.filter(not_(getattr(db.Books, data_table.class_.__tablename__).any(data_table == excl))) return q + def adv_search_shelf(q, include_shelf_inputs, exclude_shelf_inputs): - q = q.outerjoin(ub.BookShelf, db.Books.id == ub.BookShelf.book_id)\ + q = q.outerjoin(ub.BookShelf, db.Books.id == ub.BookShelf.book_id) \ .filter(or_(ub.BookShelf.shelf == None, ub.BookShelf.shelf.notin_(exclude_shelf_inputs))) if len(include_shelf_inputs) > 0: q = q.filter(ub.BookShelf.shelf.in_(include_shelf_inputs)) return q + def extend_search_term(searchterm, author_name, book_title, @@ -1233,7 +1311,7 @@ def extend_search_term(searchterm, format='medium', locale=get_locale())]) except ValueError: pub_end = u"" - elements = {'tag': db.Tags, 'serie':db.Series, 'shelf':ub.Shelf} + elements = {'tag': db.Tags, 'serie': db.Series, 'shelf': ub.Shelf} for key, db_element in elements.items(): tag_names = calibre_db.session.query(db_element).filter(db_element.id.in_(tags['include_' + key])).all() searchterm.extend(tag.name for tag in tag_names) @@ -1263,30 +1341,14 @@ def extend_search_term(searchterm, def render_adv_search_results(term, offset=None, order=None, limit=None): - sort = order[0] if order else [db.Books.sort] + sort_param = order[0] if order else [db.Books.sort] pagination = None - cc = get_cc_columns(filter_config_custom_read=True) + cc = calibre_db.get_cc_columns(config, filter_config_custom_read=True) calibre_db.session.connection().connection.connection.create_function("lower", 1, db.lcase) - if not config.config_read_column: - query = (calibre_db.session.query(db.Books, ub.ArchivedBook.is_archived, ub.ReadBook).select_from(db.Books) - .outerjoin(ub.ReadBook, and_(db.Books.id == ub.ReadBook.book_id, - int(current_user.id) == ub.ReadBook.user_id))) - else: - try: - read_column = cc[config.config_read_column] - query = (calibre_db.session.query(db.Books, ub.ArchivedBook.is_archived, read_column.value) - .select_from(db.Books) - .outerjoin(read_column, read_column.book == db.Books.id)) - except (KeyError, AttributeError): - log.error("Custom Column No.%d is not existing in calibre database", config.config_read_column) - # Skip linking read column - query = calibre_db.session.query(db.Books, ub.ArchivedBook.is_archived, None) - query = query.outerjoin(ub.ArchivedBook, and_(db.Books.id == ub.ArchivedBook.book_id, - int(current_user.id) == ub.ArchivedBook.user_id)) - - q = query.outerjoin(db.books_series_link, db.Books.id == db.books_series_link.c.book)\ - .outerjoin(db.Series)\ + query = calibre_db.generate_linked_query(config.config_read_column, db.Books) + q = query.outerjoin(db.books_series_link, db.books_series_link.c.book == db.Books.id) \ + .outerjoin(db.Series) \ .filter(calibre_db.common_filters(True)) # parse multiselects to a complete dict @@ -1312,43 +1374,43 @@ def render_adv_search_results(term, offset=None, order=None, limit=None): if publisher: publisher = publisher.strip().lower() - searchterm = [] + search_term = [] cc_present = False for c in cc: if c.datatype == "datetime": column_start = term.get('custom_column_' + str(c.id) + '_start') column_end = term.get('custom_column_' + str(c.id) + '_end') if column_start: - searchterm.extend([u"{} >= {}".format(c.name, - format_date(datetime.strptime(column_start, "%Y-%m-%d").date(), - format='medium', - locale=get_locale()) - )]) + search_term.extend([u"{} >= {}".format(c.name, + format_date(datetime.strptime(column_start, "%Y-%m-%d").date(), + format='medium', + locale=get_locale()) + )]) cc_present = True if column_end: - searchterm.extend([u"{} <= {}".format(c.name, - format_date(datetime.strptime(column_end, "%Y-%m-%d").date(), - format='medium', - locale=get_locale()) - )]) + search_term.extend([u"{} <= {}".format(c.name, + format_date(datetime.strptime(column_end, "%Y-%m-%d").date(), + format='medium', + locale=get_locale()) + )]) cc_present = True elif term.get('custom_column_' + str(c.id)): - searchterm.extend([(u"{}: {}".format(c.name, term.get('custom_column_' + str(c.id))))]) + search_term.extend([(u"{}: {}".format(c.name, term.get('custom_column_' + str(c.id))))]) cc_present = True - - if any(tags.values()) or author_name or book_title or publisher or pub_start or pub_end or rating_low \ - or rating_high or description or cc_present or read_status: - searchterm, pub_start, pub_end = extend_search_term(searchterm, - author_name, - book_title, - publisher, - pub_start, - pub_end, - tags, - rating_high, - rating_low, - read_status) + if any(tags.values()) or author_name or book_title or \ + publisher or pub_start or pub_end or rating_low or rating_high \ + or description or cc_present or read_status: + search_term, pub_start, pub_end = extend_search_term(search_term, + author_name, + book_title, + publisher, + pub_start, + pub_end, + tags, + rating_high, + rating_low, + read_status) # q = q.filter() if author_name: q = q.filter(db.Books.authors.any(func.lower(db.Authors.name).ilike("%" + author_name + "%"))) @@ -1361,24 +1423,24 @@ def render_adv_search_results(term, offset=None, order=None, limit=None): q = adv_search_read_status(q, read_status) if publisher: q = q.filter(db.Books.publishers.any(func.lower(db.Publishers.name).ilike("%" + publisher + "%"))) - q = adv_search_tag(q, tags['include_tag'], tags['exclude_tag']) - q = adv_search_serie(q, tags['include_serie'], tags['exclude_serie']) + q = adv_search_text(q, tags['include_tag'], tags['exclude_tag'], db.Tags.id) + q = adv_search_text(q, tags['include_serie'], tags['exclude_serie'], db.Series.id) + q = adv_search_text(q, tags['include_extension'], tags['exclude_extension'], db.Data.format) q = adv_search_shelf(q, tags['include_shelf'], tags['exclude_shelf']) - q = adv_search_extension(q, tags['include_extension'], tags['exclude_extension']) q = adv_search_language(q, tags['include_language'], tags['exclude_language']) - q = adv_search_ratings(q, rating_high, rating_low) + q = adv_search_ratings(q, rating_high, rating_low, ) if description: q = q.filter(db.Books.comments.any(func.lower(db.Comments.text).ilike("%" + description + "%"))) - # search custom culumns + # search custom columns try: q = adv_search_custom_columns(cc, term, q) except AttributeError as ex: - log.debug_or_exception(ex) + log.error_or_exception(ex) flash(_("Error on search for custom columns, please restart Calibre-Web"), category="error") - q = q.order_by(*sort).all() + q = q.order_by(*sort_param).all() flask_session['query'] = json.dumps(term) ub.store_combo_ids(q) result_count = len(q) @@ -1391,11 +1453,12 @@ def render_adv_search_results(term, offset=None, order=None, limit=None): limit_all = result_count entries = calibre_db.order_authors(q[offset:limit_all], list_return=True, combined=True) return render_title_template('search.html', - adv_searchterm=searchterm, + adv_searchterm=search_term, pagination=pagination, entries=entries, result_count=result_count, - title=_(u"Advanced Search"), page="advsearch", + title=_(u"Advanced Search"), + page="advsearch", order=order[1]) @@ -1403,7 +1466,7 @@ def render_adv_search_results(term, offset=None, order=None, limit=None): @login_required_if_no_ano def advanced_search_form(): # Build custom columns names - cc = get_cc_columns(filter_config_custom_read=True) + cc = calibre_db.get_cc_columns(config, filter_config_custom_read=True) return render_prepare_search_form(cc) @@ -1411,13 +1474,42 @@ def advanced_search_form(): @web.route("/cover/") +@web.route("/cover//") @login_required_if_no_ano -def get_cover(book_id): - return get_book_cover(book_id) +def get_cover(book_id, resolution=None): + resolutions = { + 'og': constants.COVER_THUMBNAIL_ORIGINAL, + 'sm': constants.COVER_THUMBNAIL_SMALL, + 'md': constants.COVER_THUMBNAIL_MEDIUM, + 'lg': constants.COVER_THUMBNAIL_LARGE, + } + cover_resolution = resolutions.get(resolution, None) + return get_book_cover(book_id, cover_resolution) + + +@web.route("/series_cover/") +@web.route("/series_cover//") +@login_required_if_no_ano +def get_series_cover(series_id, resolution=None): + resolutions = { + 'og': constants.COVER_THUMBNAIL_ORIGINAL, + 'sm': constants.COVER_THUMBNAIL_SMALL, + 'md': constants.COVER_THUMBNAIL_MEDIUM, + 'lg': constants.COVER_THUMBNAIL_LARGE, + } + cover_resolution = resolutions.get(resolution, None) + return get_series_cover_thumbnail(series_id, cover_resolution) + + @web.route("/robots.txt") def get_robots(): - return send_from_directory(constants.STATIC_DIR, "robots.txt") + try: + return send_from_directory(constants.STATIC_DIR, "robots.txt") + except PermissionError: + log.error("No permission to access robots.txt file.") + abort(403) + @web.route("/show//", defaults={'anyname': 'None'}) @web.route("/show///") @@ -1437,7 +1529,7 @@ def serve_book(book_id, book_format, anyname): df = getFileFromEbooksFolder(book.path, data.name + "." + book_format) return do_gdrive_download(df, headers, (book_format.upper() == 'TXT')) except AttributeError as ex: - log.debug_or_exception(ex) + log.error_or_exception(ex) return "File Not Found" else: if book_format.upper() == 'TXT': @@ -1562,7 +1654,7 @@ def login(): category="success") return redirect_back(url_for("web.index")) elif login_result is None and user and check_password_hash(str(user.password), form['password']) \ - and user.name != "Guest": + and user.name != "Guest": login_user(user, remember=bool(form.get('remember_me'))) ub.store_user_session() log.info("Local Fallback Login as: '%s'", user.name) @@ -1574,23 +1666,23 @@ def login(): log.info(error) flash(_(u"Could not login: %(message)s", message=error), category="error") else: - ip_Address = request.headers.get('X-Forwarded-For', request.remote_addr) - log.warning('LDAP Login failed for user "%s" IP-address: %s', form['username'], ip_Address) + ip_address = request.headers.get('X-Forwarded-For', request.remote_addr) + log.warning('LDAP Login failed for user "%s" IP-address: %s', form['username'], ip_address) flash(_(u"Wrong Username or Password"), category="error") else: - ip_Address = request.headers.get('X-Forwarded-For', request.remote_addr) + ip_address = request.headers.get('X-Forwarded-For', request.remote_addr) if 'forgot' in form and form['forgot'] == 'forgot': if user is not None and user.name != "Guest": ret, __ = reset_password(user.id) if ret == 1: flash(_(u"New Password was send to your email address"), category="info") - log.info('Password reset for user "%s" IP-address: %s', form['username'], ip_Address) + log.info('Password reset for user "%s" IP-address: %s', form['username'], ip_address) else: log.error(u"An unknown error occurred. Please try again later") flash(_(u"An unknown error occurred. Please try again later."), category="error") else: flash(_(u"Please enter valid username to reset password"), category="error") - log.warning('Username missing for password reset IP-address: %s', ip_Address) + log.warning('Username missing for password reset IP-address: %s', ip_address) else: if user and check_password_hash(str(user.password), form['password']) and user.name != "Guest": login_user(user, remember=bool(form.get('remember_me'))) @@ -1600,7 +1692,7 @@ def login(): config.config_is_initial = False return redirect_back(url_for("web.index")) else: - log.warning('Login failed for user "%s" IP-address: %s', form['username'], ip_Address) + log.warning('Login failed for user "{}" IP-address: {}'.format(form['username'], ip_address)) flash(_(u"Wrong Username or Password"), category="error") next_url = request.args.get('next', default=url_for("web.index"), type=str) @@ -1618,7 +1710,7 @@ def login(): @login_required def logout(): if current_user is not None and current_user.is_authenticated: - ub.delete_user_session(current_user.id, flask_session.get('_id',"")) + ub.delete_user_session(current_user.id, flask_session.get('_id', "")) logout_user() if feature_support['oauth'] and (config.config_login_type == 2 or config.config_login_type == 3): logout_oauth_user() @@ -1640,7 +1732,7 @@ def change_profile(kobo_support, local_oauth_check, oauth_status, translations, current_user.email = check_email(to_save["email"]) if current_user.role_admin(): if to_save.get("name", current_user.name) != current_user.name: - # Query User name, if not existing, change + # Query username, if not existing, change current_user.name = check_username(to_save["name"]) current_user.random_books = 1 if to_save.get("show_random") == "on" else 0 if to_save.get("default_language"): @@ -1694,7 +1786,7 @@ def change_profile(kobo_support, local_oauth_check, oauth_status, translations, @login_required def profile(): languages = calibre_db.speaking_language() - translations = babel.list_translations() + [LC('en')] + translations = babel.list_translations() + [Locale('en')] kobo_support = feature_support['kobo'] and config.config_kobo_sync if feature_support['oauth'] and config.config_login_type == 2: oauth_status = get_oauth_status() @@ -1725,12 +1817,15 @@ def profile(): @viewer_required def read_book(book_id, book_format): book = calibre_db.get_filtered_book(book_id) + book.ordered_authors = calibre_db.order_authors([book], False) + if not book: - flash(_(u"Oops! Selected book title is unavailable. File does not exist or is not accessible"), category="error") + flash(_(u"Oops! Selected book title is unavailable. File does not exist or is not accessible"), + category="error") log.debug(u"Oops! Selected book title is unavailable. File does not exist or is not accessible") return redirect(url_for("web.index")) - # check if book has bookmark + # check if book has a bookmark bookmark = None if current_user.is_authenticated: bookmark = ub.session.query(ub.Bookmark).filter(and_(ub.Bookmark.user_id == int(current_user.id), @@ -1767,7 +1862,8 @@ def read_book(book_id, book_format): return render_title_template('readcbr.html', comicfile=all_name, title=title, extension=fileExt) log.debug(u"Oops! Selected book title is unavailable. File does not exist or is not accessible") - flash(_(u"Oops! Selected book title is unavailable. File does not exist or is not accessible"), category="error") + flash(_(u"Oops! Selected book title is unavailable. File does not exist or is not accessible"), + category="error") return redirect(url_for("web.index")) @@ -1781,18 +1877,18 @@ def show_book(book_id): entry = entries[0] entry.read_status = read_book == ub.ReadBook.STATUS_FINISHED entry.is_archived = archived_book - for index in range(0, len(entry.languages)): - entry.languages[index].language_name = isoLanguages.get_language_name(get_locale(), entry.languages[ - index].lang_code) - cc = get_cc_columns(filter_config_custom_read=True) - book_in_shelfs = [] - shelfs = ub.session.query(ub.BookShelf).filter(ub.BookShelf.book_id == book_id).all() - for sh in shelfs: - book_in_shelfs.append(sh.shelf) + 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) + cc = calibre_db.get_cc_columns(config, filter_config_custom_read=True) + book_in_shelves = [] + shelves = ub.session.query(ub.BookShelf).filter(ub.BookShelf.book_id == book_id).all() + for sh in shelves: + book_in_shelves.append(sh.shelf) entry.tags = sort(entry.tags, key=lambda tag: tag.name) - entry.authors = calibre_db.order_authors([entry]) + entry.ordered_authors = calibre_db.order_authors([entry]) entry.kindle_list = check_send_to_kindle(entry) entry.reader_list = check_read_formats(entry) @@ -1805,9 +1901,9 @@ def show_book(book_id): return render_title_template('detail.html', entry=entry, cc=cc, - is_xhr=request.headers.get('X-Requested-With')=='XMLHttpRequest', + is_xhr=request.headers.get('X-Requested-With') == 'XMLHttpRequest', title=entry.title, - books_shelfs=book_in_shelfs, + books_shelfs=book_in_shelves, page="book") else: log.debug(u"Oops! Selected book title is unavailable. File does not exist or is not accessible") diff --git a/messages.pot b/messages.pot index 7fc39068..4477a138 100644 --- a/messages.pot +++ b/messages.pot @@ -8,585 +8,588 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2022-01-15 09:19+0100\n" +"POT-Creation-Date: 2022-04-18 20:01+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.9.0\n" +"Generated-By: Babel 2.9.1\n" -#: cps/about.py:34 cps/about.py:49 cps/about.py:65 cps/converter.py:31 -msgid "not installed" -msgstr "" - -#: cps/about.py:47 cps/about.py:63 -msgid "installed" -msgstr "" - -#: cps/about.py:145 +#: cps/about.py:86 msgid "Statistics" msgstr "" -#: cps/admin.py:144 +#: cps/admin.py:141 msgid "Server restarted, please reload page" msgstr "" -#: cps/admin.py:146 +#: cps/admin.py:143 msgid "Performing shutdown of server, please close window" msgstr "" -#: cps/admin.py:154 +#: cps/admin.py:151 msgid "Reconnect successful" msgstr "" -#: cps/admin.py:157 +#: cps/admin.py:154 msgid "Unknown command" msgstr "" -#: cps/admin.py:167 cps/editbooks.py:707 cps/editbooks.py:721 -#: cps/editbooks.py:866 cps/editbooks.py:868 cps/editbooks.py:895 -#: cps/editbooks.py:911 cps/updater.py:584 cps/uploader.py:93 -#: cps/uploader.py:103 +#: cps/admin.py:176 cps/editbooks.py:713 cps/editbooks.py:892 +#: cps/editbooks.py:894 cps/editbooks.py:930 cps/editbooks.py:947 +#: cps/updater.py:608 cps/uploader.py:93 cps/uploader.py:103 msgid "Unknown" msgstr "" -#: cps/admin.py:188 +#: cps/admin.py:197 msgid "Admin page" msgstr "" -#: cps/admin.py:207 +#: cps/admin.py:217 msgid "Basic Configuration" msgstr "" -#: cps/admin.py:244 +#: cps/admin.py:255 msgid "UI Configuration" msgstr "" -#: cps/admin.py:277 cps/templates/admin.html:50 +#: cps/admin.py:289 cps/templates/admin.html:51 msgid "Edit Users" msgstr "" -#: cps/admin.py:318 cps/opds.py:109 cps/opds.py:198 cps/opds.py:275 -#: cps/opds.py:327 cps/templates/grid.html:13 cps/templates/languages.html:9 +#: cps/admin.py:333 cps/opds.py:529 cps/templates/grid.html:13 #: cps/templates/list.html:13 msgid "All" msgstr "" -#: cps/admin.py:343 cps/admin.py:1615 +#: cps/admin.py:360 cps/admin.py:1648 msgid "User not found" msgstr "" -#: cps/admin.py:357 +#: cps/admin.py:374 msgid "{} users deleted successfully" msgstr "" -#: cps/admin.py:379 cps/templates/config_view_edit.html:133 +#: cps/admin.py:397 cps/templates/config_view_edit.html:133 #: cps/templates/user_edit.html:45 cps/templates/user_table.html:81 msgid "Show All" msgstr "" -#: cps/admin.py:400 cps/admin.py:406 +#: cps/admin.py:418 cps/admin.py:424 msgid "Malformed request" msgstr "" -#: cps/admin.py:418 cps/admin.py:1493 +#: cps/admin.py:436 cps/admin.py:1526 msgid "Guest Name can't be changed" msgstr "" -#: cps/admin.py:430 +#: cps/admin.py:448 msgid "Guest can't have this role" msgstr "" -#: cps/admin.py:442 cps/admin.py:1451 +#: cps/admin.py:460 cps/admin.py:1484 msgid "No admin user remaining, can't remove admin role" msgstr "" -#: cps/admin.py:446 cps/admin.py:460 +#: cps/admin.py:464 cps/admin.py:478 msgid "Value has to be true or false" msgstr "" -#: cps/admin.py:448 +#: cps/admin.py:466 msgid "Invalid role" msgstr "" -#: cps/admin.py:452 +#: cps/admin.py:470 msgid "Guest can't have this view" msgstr "" -#: cps/admin.py:462 +#: cps/admin.py:480 msgid "Invalid view" msgstr "" -#: cps/admin.py:465 +#: cps/admin.py:483 msgid "Guest's Locale is determined automatically and can't be set" msgstr "" -#: cps/admin.py:469 +#: cps/admin.py:487 msgid "No Valid Locale Given" msgstr "" -#: cps/admin.py:480 +#: cps/admin.py:498 msgid "No Valid Book Language Given" msgstr "" -#: cps/admin.py:482 +#: cps/admin.py:500 cps/editbooks.py:1267 msgid "Parameter not found" msgstr "" -#: cps/admin.py:533 +#: cps/admin.py:553 msgid "Invalid Read Column" msgstr "" -#: cps/admin.py:539 +#: cps/admin.py:559 msgid "Invalid Restricted Column" msgstr "" -#: cps/admin.py:560 cps/admin.py:1323 +#: cps/admin.py:579 cps/admin.py:1355 msgid "Calibre-Web configuration updated" msgstr "" -#: cps/admin.py:572 +#: cps/admin.py:591 msgid "Do you really want to delete the Kobo Token?" msgstr "" -#: cps/admin.py:574 +#: cps/admin.py:593 msgid "Do you really want to delete this domain?" msgstr "" -#: cps/admin.py:576 +#: cps/admin.py:595 msgid "Do you really want to delete this user?" msgstr "" -#: cps/admin.py:578 +#: cps/admin.py:597 msgid "Are you sure you want to delete this shelf?" msgstr "" -#: cps/admin.py:580 +#: cps/admin.py:599 msgid "Are you sure you want to change locales of selected user(s)?" msgstr "" -#: cps/admin.py:582 +#: cps/admin.py:601 msgid "Are you sure you want to change visible book languages for selected user(s)?" msgstr "" -#: cps/admin.py:584 +#: cps/admin.py:603 msgid "Are you sure you want to change the selected role for the selected user(s)?" msgstr "" -#: cps/admin.py:586 +#: cps/admin.py:605 msgid "Are you sure you want to change the selected restrictions for the selected user(s)?" msgstr "" -#: cps/admin.py:588 +#: cps/admin.py:607 msgid "Are you sure you want to change the selected visibility restrictions for the selected user(s)?" msgstr "" -#: cps/admin.py:590 +#: cps/admin.py:610 msgid "Are you sure you want to change shelf sync behavior for the selected user(s)?" msgstr "" -#: cps/admin.py:592 +#: cps/admin.py:612 msgid "Are you sure you want to change Calibre library location?" msgstr "" -#: cps/admin.py:594 +#: cps/admin.py:614 msgid "Are you sure you want delete Calibre-Web's sync database to force a full sync with your Kobo Reader?" msgstr "" -#: cps/admin.py:743 +#: cps/admin.py:764 msgid "Tag not found" msgstr "" -#: cps/admin.py:755 +#: cps/admin.py:776 msgid "Invalid Action" msgstr "" -#: cps/admin.py:871 cps/admin.py:877 cps/admin.py:887 cps/admin.py:897 +#: cps/admin.py:893 cps/admin.py:899 cps/admin.py:909 cps/admin.py:919 #: cps/templates/modal_dialogs.html:29 cps/templates/user_table.html:41 #: cps/templates/user_table.html:58 msgid "Deny" msgstr "" -#: cps/admin.py:873 cps/admin.py:879 cps/admin.py:889 cps/admin.py:899 +#: cps/admin.py:895 cps/admin.py:901 cps/admin.py:911 cps/admin.py:921 #: cps/templates/modal_dialogs.html:28 cps/templates/user_table.html:44 #: cps/templates/user_table.html:61 msgid "Allow" msgstr "" -#: cps/admin.py:913 +#: cps/admin.py:936 msgid "{} sync entries deleted" msgstr "" -#: cps/admin.py:1036 +#: cps/admin.py:1059 msgid "client_secrets.json Is Not Configured For Web Application" msgstr "" -#: cps/admin.py:1081 +#: cps/admin.py:1104 msgid "Logfile Location is not Valid, Please Enter Correct Path" msgstr "" -#: cps/admin.py:1087 +#: cps/admin.py:1110 msgid "Access Logfile Location is not Valid, Please Enter Correct Path" msgstr "" -#: cps/admin.py:1117 +#: cps/admin.py:1140 msgid "Please Enter a LDAP Provider, Port, DN and User Object Identifier" msgstr "" -#: cps/admin.py:1123 +#: cps/admin.py:1146 msgid "Please Enter a LDAP Service Account and Password" msgstr "" -#: cps/admin.py:1126 +#: cps/admin.py:1149 msgid "Please Enter a LDAP Service Account" msgstr "" -#: cps/admin.py:1131 +#: cps/admin.py:1154 #, python-format msgid "LDAP Group Object Filter Needs to Have One \"%s\" Format Identifier" msgstr "" -#: cps/admin.py:1133 +#: cps/admin.py:1156 msgid "LDAP Group Object Filter Has Unmatched Parenthesis" msgstr "" -#: cps/admin.py:1137 +#: cps/admin.py:1160 #, python-format msgid "LDAP User Object Filter needs to Have One \"%s\" Format Identifier" msgstr "" -#: cps/admin.py:1139 +#: cps/admin.py:1162 msgid "LDAP User Object Filter Has Unmatched Parenthesis" msgstr "" -#: cps/admin.py:1146 +#: cps/admin.py:1169 #, python-format msgid "LDAP Member User Filter needs to Have One \"%s\" Format Identifier" msgstr "" -#: cps/admin.py:1148 +#: cps/admin.py:1171 msgid "LDAP Member User Filter Has Unmatched Parenthesis" msgstr "" -#: cps/admin.py:1155 +#: cps/admin.py:1178 msgid "LDAP CACertificate, Certificate or Key Location is not Valid, Please Enter Correct Path" msgstr "" -#: cps/admin.py:1197 cps/admin.py:1308 cps/admin.py:1405 cps/admin.py:1521 -#: cps/admin.py:1590 cps/shelf.py:100 cps/shelf.py:160 cps/shelf.py:203 -#: cps/shelf.py:279 cps/shelf.py:341 cps/shelf.py:376 cps/shelf.py:451 -msgid "Settings DB is not Writeable" -msgstr "" - -#: cps/admin.py:1208 -msgid "DB Location is not Valid, Please Enter Correct Path" -msgstr "" - -#: cps/admin.py:1223 -msgid "DB is not Writeable" -msgstr "" - -#: cps/admin.py:1235 -msgid "Keyfile Location is not Valid, Please Enter Correct Path" -msgstr "" - -#: cps/admin.py:1239 -msgid "Certfile Location is not Valid, Please Enter Correct Path" -msgstr "" - -#: cps/admin.py:1346 -msgid "Database Settings updated" -msgstr "" - -#: cps/admin.py:1354 -msgid "Database Configuration" -msgstr "" - -#: cps/admin.py:1370 cps/web.py:1479 -msgid "Please fill out all fields!" -msgstr "" - -#: cps/admin.py:1378 -msgid "E-mail is not from valid domain" -msgstr "" - -#: cps/admin.py:1384 cps/admin.py:1543 -msgid "Add new user" -msgstr "" - -#: cps/admin.py:1395 -#, python-format -msgid "User '%(user)s' created" -msgstr "" - -#: cps/admin.py:1401 -msgid "Found an existing account for this e-mail address or name." -msgstr "" - -#: cps/admin.py:1430 -#, python-format -msgid "User '%(nick)s' deleted" -msgstr "" - -#: cps/admin.py:1432 cps/admin.py:1433 -msgid "Can't delete Guest User" -msgstr "" - -#: cps/admin.py:1436 -msgid "No admin user remaining, can't delete user" -msgstr "" - -#: cps/admin.py:1509 cps/admin.py:1634 -#, python-format -msgid "Edit User %(nick)s" -msgstr "" - -#: cps/admin.py:1513 -#, python-format -msgid "User '%(nick)s' updated" -msgstr "" - -#: cps/admin.py:1517 cps/admin.py:1649 cps/web.py:1504 cps/web.py:1564 -msgid "An unknown error occurred. Please try again later." -msgstr "" - -#: cps/admin.py:1552 cps/templates/admin.html:98 -msgid "Edit E-mail Server Settings" -msgstr "" - -#: cps/admin.py:1571 -msgid "Gmail Account Verification Successful" -msgstr "" - -#: cps/admin.py:1597 -#, python-format -msgid "Test e-mail queued for sending to %(email)s, please check Tasks for result" -msgstr "" - -#: cps/admin.py:1600 -#, python-format -msgid "There was an error sending the Test e-mail: %(res)s" -msgstr "" - -#: cps/admin.py:1602 -msgid "Please configure your e-mail address first..." -msgstr "" - -#: cps/admin.py:1604 -msgid "E-mail server settings updated" -msgstr "" - -#: cps/admin.py:1646 -#, python-format -msgid "Password for user %(user)s reset" -msgstr "" - -#: cps/admin.py:1652 cps/web.py:1444 -msgid "Please configure the SMTP mail settings first..." -msgstr "" - -#: cps/admin.py:1663 -msgid "Logfile viewer" -msgstr "" - -#: cps/admin.py:1729 -msgid "Requesting update package" -msgstr "" - -#: cps/admin.py:1730 -msgid "Downloading update package" -msgstr "" - -#: cps/admin.py:1731 -msgid "Unzipping update package" -msgstr "" - -#: cps/admin.py:1732 -msgid "Replacing files" -msgstr "" - -#: cps/admin.py:1733 -msgid "Database connections are closed" -msgstr "" - -#: cps/admin.py:1734 -msgid "Stopping server" -msgstr "" - -#: cps/admin.py:1735 -msgid "Update finished, please press okay and reload page" -msgstr "" - -#: cps/admin.py:1736 cps/admin.py:1737 cps/admin.py:1738 cps/admin.py:1739 -#: cps/admin.py:1740 cps/admin.py:1741 -msgid "Update failed:" -msgstr "" - -#: cps/admin.py:1736 cps/updater.py:385 cps/updater.py:595 cps/updater.py:597 -msgid "HTTP Error" -msgstr "" - -#: cps/admin.py:1737 cps/updater.py:387 cps/updater.py:599 -msgid "Connection error" -msgstr "" - -#: cps/admin.py:1738 cps/updater.py:389 cps/updater.py:601 -msgid "Timeout while establishing connection" -msgstr "" - -#: cps/admin.py:1739 cps/updater.py:391 cps/updater.py:603 -msgid "General error" -msgstr "" - -#: cps/admin.py:1740 -msgid "Update file could not be saved in temp dir" -msgstr "" - -#: cps/admin.py:1741 -msgid "Files could not be replaced during update" -msgstr "" - -#: cps/admin.py:1765 -msgid "Failed to extract at least One LDAP User" -msgstr "" - -#: cps/admin.py:1810 -msgid "Failed to Create at Least One LDAP User" -msgstr "" - -#: cps/admin.py:1823 -#, python-format -msgid "Error: %(ldaperror)s" -msgstr "" - -#: cps/admin.py:1827 -msgid "Error: No user returned in response of LDAP server" -msgstr "" - -#: cps/admin.py:1860 -msgid "At Least One LDAP User Not Found in Database" -msgstr "" - -#: cps/admin.py:1862 -msgid "{} User Successfully Imported" -msgstr "" - -#: cps/converter.py:30 -msgid "not configured" -msgstr "" - -#: cps/converter.py:32 -msgid "Execution permissions missing" -msgstr "" - -#: cps/db.py:651 cps/web.py:667 cps/web.py:1155 -#, python-format -msgid "Custom Column No.%(column)d is not existing in calibre database" -msgstr "" - -#: cps/editbooks.py:300 cps/editbooks.py:302 -msgid "Book Format Successfully Deleted" -msgstr "" - -#: cps/editbooks.py:309 cps/editbooks.py:311 -msgid "Book Successfully Deleted" -msgstr "" - -#: cps/editbooks.py:361 -msgid "You are missing permissions to delete books" -msgstr "" - -#: cps/editbooks.py:376 cps/editbooks.py:763 cps/web.py:523 cps/web.py:1703 -#: cps/web.py:1744 cps/web.py:1811 -msgid "Oops! Selected book title is unavailable. File does not exist or is not accessible" -msgstr "" - -#: cps/editbooks.py:410 -msgid "edit metadata" -msgstr "" - -#: cps/editbooks.py:458 -#, python-format -msgid "%(seriesindex)s is not a valid number, skipping" -msgstr "" - -#: cps/editbooks.py:494 cps/editbooks.py:958 -#, python-format -msgid "'%(langname)s' is not a valid language" -msgstr "" - -#: cps/editbooks.py:634 cps/editbooks.py:985 -#, python-format -msgid "File extension '%(ext)s' is not allowed to be uploaded to this server" -msgstr "" - -#: cps/editbooks.py:638 cps/editbooks.py:989 -msgid "File to be uploaded must have an extension" -msgstr "" - -#: cps/editbooks.py:650 -#, python-format -msgid "Failed to create path %(path)s (Permission denied)." -msgstr "" - -#: cps/editbooks.py:655 -#, python-format -msgid "Failed to store file %(file)s." -msgstr "" - -#: cps/editbooks.py:673 cps/editbooks.py:1076 cps/web.py:1664 +#: cps/admin.py:1223 cps/admin.py:1339 cps/admin.py:1437 cps/admin.py:1554 +#: cps/admin.py:1623 cps/editbooks.py:678 cps/editbooks.py:882 +#: cps/editbooks.py:1130 cps/shelf.py:100 cps/shelf.py:160 cps/shelf.py:203 +#: cps/shelf.py:278 cps/shelf.py:343 cps/shelf.py:380 cps/shelf.py:456 +#: cps/web.py:1742 #, python-format msgid "Database error: %(error)s." msgstr "" -#: cps/editbooks.py:678 +#: cps/admin.py:1235 +msgid "DB Location is not Valid, Please Enter Correct Path" +msgstr "" + +#: cps/admin.py:1253 +msgid "DB is not Writeable" +msgstr "" + +#: cps/admin.py:1266 +msgid "Keyfile Location is not Valid, Please Enter Correct Path" +msgstr "" + +#: cps/admin.py:1270 +msgid "Certfile Location is not Valid, Please Enter Correct Path" +msgstr "" + +#: cps/admin.py:1378 +msgid "Database Settings updated" +msgstr "" + +#: cps/admin.py:1386 +msgid "Database Configuration" +msgstr "" + +#: cps/admin.py:1402 cps/web.py:1557 +msgid "Please fill out all fields!" +msgstr "" + +#: cps/admin.py:1410 +msgid "E-mail is not from valid domain" +msgstr "" + +#: cps/admin.py:1416 cps/admin.py:1576 +msgid "Add new user" +msgstr "" + +#: cps/admin.py:1427 +#, python-format +msgid "User '%(user)s' created" +msgstr "" + +#: cps/admin.py:1433 +msgid "Found an existing account for this e-mail address or name." +msgstr "" + +#: cps/admin.py:1463 +#, python-format +msgid "User '%(nick)s' deleted" +msgstr "" + +#: cps/admin.py:1465 cps/admin.py:1466 +msgid "Can't delete Guest User" +msgstr "" + +#: cps/admin.py:1469 +msgid "No admin user remaining, can't delete user" +msgstr "" + +#: cps/admin.py:1542 cps/admin.py:1667 +#, python-format +msgid "Edit User %(nick)s" +msgstr "" + +#: cps/admin.py:1546 +#, python-format +msgid "User '%(nick)s' updated" +msgstr "" + +#: cps/admin.py:1550 cps/admin.py:1682 cps/web.py:1582 cps/web.py:1642 +msgid "An unknown error occurred. Please try again later." +msgstr "" + +#: cps/admin.py:1585 cps/templates/admin.html:100 +msgid "Edit E-mail Server Settings" +msgstr "" + +#: cps/admin.py:1604 +msgid "Gmail Account Verification Successful" +msgstr "" + +#: cps/admin.py:1630 +#, python-format +msgid "Test e-mail queued for sending to %(email)s, please check Tasks for result" +msgstr "" + +#: cps/admin.py:1633 +#, python-format +msgid "There was an error sending the Test e-mail: %(res)s" +msgstr "" + +#: cps/admin.py:1635 +msgid "Please configure your e-mail address first..." +msgstr "" + +#: cps/admin.py:1637 +msgid "E-mail server settings updated" +msgstr "" + +#: cps/admin.py:1679 +#, python-format +msgid "Password for user %(user)s reset" +msgstr "" + +#: cps/admin.py:1685 cps/web.py:1522 +msgid "Please configure the SMTP mail settings first..." +msgstr "" + +#: cps/admin.py:1696 +msgid "Logfile viewer" +msgstr "" + +#: cps/admin.py:1762 +msgid "Requesting update package" +msgstr "" + +#: cps/admin.py:1763 +msgid "Downloading update package" +msgstr "" + +#: cps/admin.py:1764 +msgid "Unzipping update package" +msgstr "" + +#: cps/admin.py:1765 +msgid "Replacing files" +msgstr "" + +#: cps/admin.py:1766 +msgid "Database connections are closed" +msgstr "" + +#: cps/admin.py:1767 +msgid "Stopping server" +msgstr "" + +#: cps/admin.py:1768 +msgid "Update finished, please press okay and reload page" +msgstr "" + +#: cps/admin.py:1769 cps/admin.py:1770 cps/admin.py:1771 cps/admin.py:1772 +#: cps/admin.py:1773 cps/admin.py:1774 +msgid "Update failed:" +msgstr "" + +#: cps/admin.py:1769 cps/updater.py:384 cps/updater.py:619 cps/updater.py:621 +msgid "HTTP Error" +msgstr "" + +#: cps/admin.py:1770 cps/updater.py:386 cps/updater.py:623 +msgid "Connection error" +msgstr "" + +#: cps/admin.py:1771 cps/updater.py:388 cps/updater.py:625 +msgid "Timeout while establishing connection" +msgstr "" + +#: cps/admin.py:1772 cps/updater.py:390 cps/updater.py:627 +msgid "General error" +msgstr "" + +#: cps/admin.py:1773 +msgid "Update file could not be saved in temp dir" +msgstr "" + +#: cps/admin.py:1774 +msgid "Files could not be replaced during update" +msgstr "" + +#: cps/admin.py:1798 +msgid "Failed to extract at least One LDAP User" +msgstr "" + +#: cps/admin.py:1843 +msgid "Failed to Create at Least One LDAP User" +msgstr "" + +#: cps/admin.py:1856 +#, python-format +msgid "Error: %(ldaperror)s" +msgstr "" + +#: cps/admin.py:1860 +msgid "Error: No user returned in response of LDAP server" +msgstr "" + +#: cps/admin.py:1893 +msgid "At Least One LDAP User Not Found in Database" +msgstr "" + +#: cps/admin.py:1895 +msgid "{} User Successfully Imported" +msgstr "" + +#: cps/converter.py:30 +msgid "not installed" +msgstr "" + +#: cps/converter.py:31 +msgid "Execution permissions missing" +msgstr "" + +#: cps/db.py:674 cps/web.py:710 cps/web.py:1222 +#, python-format +msgid "Custom Column No.%(column)d is not existing in calibre database" +msgstr "" + +#: cps/db.py:917 cps/templates/config_edit.html:204 +#: cps/templates/config_view_edit.html:62 cps/templates/email_edit.html:41 +#: cps/web.py:551 cps/web.py:585 cps/web.py:646 cps/web.py:671 cps/web.py:1003 +#: cps/web.py:1032 cps/web.py:1066 cps/web.py:1093 cps/web.py:1132 +msgid "None" +msgstr "" + +#: cps/editbooks.py:295 cps/editbooks.py:297 +msgid "Book Format Successfully Deleted" +msgstr "" + +#: cps/editbooks.py:304 cps/editbooks.py:306 +msgid "Book Successfully Deleted" +msgstr "" + +#: cps/editbooks.py:358 +msgid "You are missing permissions to delete books" +msgstr "" + +#: cps/editbooks.py:373 cps/editbooks.py:765 cps/web.py:518 cps/web.py:1783 +#: cps/web.py:1825 cps/web.py:1870 +msgid "Oops! Selected book title is unavailable. File does not exist or is not accessible" +msgstr "" + +#: cps/editbooks.py:408 +msgid "edit metadata" +msgstr "" + +#: cps/editbooks.py:457 +#, python-format +msgid "%(seriesindex)s is not a valid number, skipping" +msgstr "" + +#: cps/editbooks.py:493 cps/editbooks.py:1001 +#, python-format +msgid "'%(langname)s' is not a valid language" +msgstr "" + +#: cps/editbooks.py:634 +msgid "User has no rights to upload additional file formats" +msgstr "" + +#: cps/editbooks.py:639 cps/editbooks.py:1029 +#, python-format +msgid "File extension '%(ext)s' is not allowed to be uploaded to this server" +msgstr "" + +#: cps/editbooks.py:643 cps/editbooks.py:1033 +msgid "File to be uploaded must have an extension" +msgstr "" + +#: cps/editbooks.py:655 +#, python-format +msgid "Failed to create path %(path)s (Permission denied)." +msgstr "" + +#: cps/editbooks.py:660 +#, python-format +msgid "Failed to store file %(file)s." +msgstr "" + +#: cps/editbooks.py:683 #, python-format msgid "File format %(ext)s added to %(book)s" msgstr "" -#: cps/editbooks.py:814 +#: cps/editbooks.py:697 cps/editbooks.py:809 +msgid "User has no rights to upload cover" +msgstr "" + +#: cps/editbooks.py:828 msgid "Identifiers are not Case Sensitive, Overwriting Old Identifier" msgstr "" -#: cps/editbooks.py:848 +#: cps/editbooks.py:869 msgid "Metadata successfully updated" msgstr "" -#: cps/editbooks.py:861 -msgid "Error editing book, please check logfile for details" +#: cps/editbooks.py:887 +msgid "Error editing book: {}" msgstr "" -#: cps/editbooks.py:899 +#: cps/editbooks.py:951 msgid "Uploaded book probably exists in the library, consider to change before upload new: " msgstr "" -#: cps/editbooks.py:997 +#: cps/editbooks.py:1041 #, python-format msgid "File %(filename)s could not saved to temp dir" msgstr "" -#: cps/editbooks.py:1016 +#: cps/editbooks.py:1061 #, python-format msgid "Failed to Move Cover File %(file)s: %(error)s" msgstr "" -#: cps/editbooks.py:1063 +#: cps/editbooks.py:1117 #, python-format msgid "File %(file)s uploaded" msgstr "" -#: cps/editbooks.py:1088 +#: cps/editbooks.py:1143 msgid "Source or destination format for conversion missing" msgstr "" -#: cps/editbooks.py:1096 +#: cps/editbooks.py:1151 #, python-format msgid "Book successfully queued for converting to %(book_format)s" msgstr "" -#: cps/editbooks.py:1100 +#: cps/editbooks.py:1155 #, python-format msgid "There was an error converting this book: %(res)s" msgstr "" @@ -599,174 +602,190 @@ msgstr "" msgid "Callback domain is not verified, please follow steps to verify domain in google developer console" msgstr "" -#: cps/helper.py:77 +#: cps/helper.py:81 #, python-format msgid "%(format)s format not found for book id: %(book)d" msgstr "" -#: cps/helper.py:83 cps/tasks/convert.py:73 +#: cps/helper.py:87 cps/tasks/convert.py:75 #, python-format msgid "%(format)s not found on Google Drive: %(fn)s" msgstr "" -#: cps/helper.py:88 +#: cps/helper.py:92 #, python-format msgid "%(format)s not found: %(fn)s" msgstr "" -#: cps/helper.py:93 cps/helper.py:217 cps/templates/detail.html:41 +#: cps/helper.py:97 cps/helper.py:221 cps/templates/detail.html:41 #: cps/templates/detail.html:45 msgid "Send to Kindle" msgstr "" -#: cps/helper.py:94 cps/helper.py:111 cps/helper.py:219 +#: cps/helper.py:98 cps/helper.py:115 cps/helper.py:223 msgid "This e-mail has been sent via Calibre-Web." msgstr "" -#: cps/helper.py:109 +#: cps/helper.py:113 msgid "Calibre-Web test e-mail" msgstr "" -#: cps/helper.py:110 +#: cps/helper.py:114 msgid "Test e-mail" msgstr "" -#: cps/helper.py:127 +#: cps/helper.py:131 msgid "Get Started with Calibre-Web" msgstr "" -#: cps/helper.py:132 +#: cps/helper.py:136 #, python-format msgid "Registration e-mail for user: %(name)s" msgstr "" -#: cps/helper.py:143 cps/helper.py:149 +#: cps/helper.py:147 cps/helper.py:153 #, python-format msgid "Convert %(orig)s to %(format)s and send to Kindle" msgstr "" -#: cps/helper.py:168 cps/helper.py:172 cps/helper.py:176 +#: cps/helper.py:172 cps/helper.py:176 cps/helper.py:180 #, python-format msgid "Send %(format)s to Kindle" msgstr "" -#: cps/helper.py:216 cps/tasks/convert.py:90 +#: cps/helper.py:220 cps/tasks/convert.py:92 #, python-format msgid "%(book)s send to Kindle" msgstr "" -#: cps/helper.py:221 +#: cps/helper.py:225 msgid "The requested file could not be read. Maybe wrong permissions?" msgstr "" -#: cps/helper.py:313 +#: cps/helper.py:353 +msgid "Read status could not set: {}" +msgstr "" + +#: cps/helper.py:376 #, python-format msgid "Deleting bookfolder for book %(id)s failed, path has subfolders: %(path)s" msgstr "" -#: cps/helper.py:319 +#: cps/helper.py:382 #, python-format msgid "Deleting book %(id)s failed: %(message)s" msgstr "" -#: cps/helper.py:330 +#: cps/helper.py:393 #, python-format msgid "Deleting book %(id)s from database only, book path in database not valid: %(path)s" msgstr "" -#: cps/helper.py:385 +#: cps/helper.py:458 #, python-format -msgid "Rename title from: '%(src)s' to '%(dest)s' failed with error: %(error)s" +msgid "Rename author from: '%(src)s' to '%(dest)s' failed with error: %(error)s" msgstr "" -#: cps/helper.py:400 -#, python-format -msgid "Rename file in path '%(src)s' to '%(dest)s' failed with error: %(error)s" -msgstr "" - -#: cps/helper.py:425 cps/helper.py:435 cps/helper.py:443 +#: cps/helper.py:529 cps/helper.py:538 #, python-format msgid "File %(file)s not found on Google Drive" msgstr "" -#: cps/helper.py:464 +#: cps/helper.py:572 +#, python-format +msgid "Rename title from: '%(src)s' to '%(dest)s' failed with error: %(error)s" +msgstr "" + +#: cps/helper.py:592 +msgid "Error in rename file in path: {}" +msgstr "" + +#: cps/helper.py:610 #, python-format msgid "Book path %(path)s not found on Google Drive" msgstr "" -#: cps/helper.py:504 cps/web.py:1659 +#: cps/helper.py:651 cps/web.py:1737 msgid "Found an existing account for this e-mail address" msgstr "" -#: cps/helper.py:512 +#: cps/helper.py:659 msgid "This username is already taken" msgstr "" -#: cps/helper.py:522 +#: cps/helper.py:669 msgid "Invalid e-mail address format" msgstr "" -#: cps/helper.py:595 -msgid "Error Downloading Cover" -msgstr "" - -#: cps/helper.py:598 -msgid "Cover Format Error" -msgstr "" - -#: cps/helper.py:608 -msgid "Failed to create path for cover" -msgstr "" - -#: cps/helper.py:624 -msgid "Cover-file is not a valid image file, or could not be stored" -msgstr "" - -#: cps/helper.py:635 -msgid "Only jpg/jpeg/png/webp/bmp files are supported as coverfile" -msgstr "" - -#: cps/helper.py:648 -msgid "Invalid cover file content" -msgstr "" - -#: cps/helper.py:652 -msgid "Only jpg/jpeg files are supported as coverfile" -msgstr "" - -#: cps/helper.py:704 -msgid "Unrar binary file not found" -msgstr "" - -#: cps/helper.py:715 -msgid "Error excecuting UnRar" -msgstr "" - -#: cps/helper.py:763 -msgid "Waiting" -msgstr "" - -#: cps/helper.py:765 -msgid "Failed" +#: cps/helper.py:754 +msgid "Python modul 'advocate' is not installed but is needed for cover downloads" msgstr "" #: cps/helper.py:767 +msgid "Error Downloading Cover" +msgstr "" + +#: cps/helper.py:770 +msgid "Cover Format Error" +msgstr "" + +#: cps/helper.py:773 +msgid "You are not allowed to access localhost or the local network for cover uploads" +msgstr "" + +#: cps/helper.py:783 +msgid "Failed to create path for cover" +msgstr "" + +#: cps/helper.py:799 +msgid "Cover-file is not a valid image file, or could not be stored" +msgstr "" + +#: cps/helper.py:810 +msgid "Only jpg/jpeg/png/webp/bmp files are supported as coverfile" +msgstr "" + +#: cps/helper.py:822 +msgid "Invalid cover file content" +msgstr "" + +#: cps/helper.py:826 +msgid "Only jpg/jpeg files are supported as coverfile" +msgstr "" + +#: cps/helper.py:878 +msgid "Unrar binary file not found" +msgstr "" + +#: cps/helper.py:889 +msgid "Error excecuting UnRar" +msgstr "" + +#: cps/helper.py:937 +msgid "Waiting" +msgstr "" + +#: cps/helper.py:939 +msgid "Failed" +msgstr "" + +#: cps/helper.py:941 msgid "Started" msgstr "" -#: cps/helper.py:769 +#: cps/helper.py:943 msgid "Finished" msgstr "" -#: cps/helper.py:771 +#: cps/helper.py:945 msgid "Unknown Status" msgstr "" -#: cps/kobo_auth.py:127 -msgid "PLease access calibre-web from non localhost to get valid api_endpoint for kobo device" +#: cps/kobo_auth.py:128 +msgid "Please access Calibre-Web from non localhost to get valid api_endpoint for kobo device" msgstr "" -#: cps/kobo_auth.py:130 cps/kobo_auth.py:158 +#: cps/kobo_auth.py:154 msgid "Kobo Setup" msgstr "" @@ -775,7 +794,7 @@ msgstr "" msgid "Register with %(provider)s" msgstr "" -#: cps/oauth_bb.py:138 cps/remotelogin.py:133 cps/web.py:1535 +#: cps/oauth_bb.py:138 cps/remotelogin.py:130 cps/web.py:1613 #, python-format msgid "you are now logged in as: '%(nickname)s'" msgstr "" @@ -836,163 +855,163 @@ msgstr "" msgid "Google Oauth error: {}" msgstr "" -#: cps/opds.py:384 +#: cps/opds.py:298 msgid "{} Stars" msgstr "" -#: cps/remotelogin.py:65 cps/templates/layout.html:84 -#: cps/templates/login.html:4 cps/templates/login.html:21 cps/web.py:1584 +#: cps/remotelogin.py:62 cps/templates/layout.html:84 +#: cps/templates/login.html:4 cps/templates/login.html:21 cps/web.py:1662 msgid "Login" msgstr "" -#: cps/remotelogin.py:77 cps/remotelogin.py:111 +#: cps/remotelogin.py:74 cps/remotelogin.py:108 msgid "Token not found" msgstr "" -#: cps/remotelogin.py:86 cps/remotelogin.py:119 +#: cps/remotelogin.py:83 cps/remotelogin.py:116 msgid "Token has expired" msgstr "" -#: cps/remotelogin.py:95 +#: cps/remotelogin.py:92 msgid "Success! Please return to your device" msgstr "" -#: cps/render_template.py:39 cps/web.py:416 +#: cps/render_template.py:41 cps/web.py:407 msgid "Books" msgstr "" -#: cps/render_template.py:41 +#: cps/render_template.py:43 msgid "Show recent books" msgstr "" -#: cps/render_template.py:42 cps/templates/index.xml:25 +#: cps/render_template.py:44 cps/templates/index.xml:25 msgid "Hot Books" msgstr "" -#: cps/render_template.py:44 +#: cps/render_template.py:46 msgid "Show Hot Books" msgstr "" -#: cps/render_template.py:46 cps/render_template.py:51 +#: cps/render_template.py:48 cps/render_template.py:53 msgid "Downloaded Books" msgstr "" -#: cps/render_template.py:48 cps/render_template.py:53 +#: cps/render_template.py:50 cps/render_template.py:55 #: cps/templates/user_table.html:167 msgid "Show Downloaded Books" msgstr "" -#: cps/render_template.py:56 cps/templates/index.xml:32 cps/web.py:430 +#: cps/render_template.py:58 cps/templates/index.xml:32 cps/web.py:422 msgid "Top Rated Books" msgstr "" -#: cps/render_template.py:58 cps/templates/user_table.html:161 +#: cps/render_template.py:60 cps/templates/user_table.html:161 msgid "Show Top Rated Books" msgstr "" -#: cps/render_template.py:59 cps/templates/index.xml:54 -#: cps/templates/index.xml:58 cps/web.py:676 +#: cps/render_template.py:61 cps/templates/index.xml:54 +#: cps/templates/index.xml:58 cps/web.py:729 msgid "Read Books" msgstr "" -#: cps/render_template.py:61 +#: cps/render_template.py:63 msgid "Show read and unread" msgstr "" -#: cps/render_template.py:63 cps/templates/index.xml:61 -#: cps/templates/index.xml:65 cps/web.py:679 +#: cps/render_template.py:65 cps/templates/index.xml:61 +#: cps/templates/index.xml:65 cps/web.py:732 msgid "Unread Books" msgstr "" -#: cps/render_template.py:65 +#: cps/render_template.py:67 msgid "Show unread" msgstr "" -#: cps/render_template.py:66 +#: cps/render_template.py:68 msgid "Discover" msgstr "" -#: cps/render_template.py:68 cps/templates/index.xml:50 +#: cps/render_template.py:70 cps/templates/index.xml:50 #: cps/templates/user_table.html:162 msgid "Show Random Books" msgstr "" -#: cps/render_template.py:69 cps/templates/book_table.html:67 -#: cps/templates/index.xml:83 cps/web.py:1041 +#: cps/render_template.py:71 cps/templates/book_table.html:67 +#: cps/templates/index.xml:83 cps/web.py:1135 msgid "Categories" msgstr "" -#: cps/render_template.py:71 cps/templates/user_table.html:158 +#: cps/render_template.py:73 cps/templates/user_table.html:158 msgid "Show category selection" msgstr "" -#: cps/render_template.py:72 cps/templates/book_edit.html:90 +#: cps/render_template.py:74 cps/templates/book_edit.html:90 #: cps/templates/book_table.html:68 cps/templates/index.xml:90 -#: cps/templates/search_form.html:69 cps/web.py:948 cps/web.py:959 +#: cps/templates/search_form.html:69 cps/web.py:1034 cps/web.py:1041 msgid "Series" msgstr "" -#: cps/render_template.py:74 cps/templates/user_table.html:157 +#: cps/render_template.py:76 cps/templates/user_table.html:157 msgid "Show series selection" msgstr "" -#: cps/render_template.py:75 cps/templates/book_table.html:66 +#: cps/render_template.py:77 cps/templates/book_table.html:66 #: cps/templates/index.xml:69 msgid "Authors" msgstr "" -#: cps/render_template.py:77 cps/templates/user_table.html:160 +#: cps/render_template.py:79 cps/templates/user_table.html:160 msgid "Show author selection" msgstr "" -#: cps/render_template.py:79 cps/templates/book_table.html:72 -#: cps/templates/index.xml:76 cps/web.py:925 +#: cps/render_template.py:81 cps/templates/book_table.html:72 +#: cps/templates/index.xml:76 cps/web.py:1006 msgid "Publishers" msgstr "" -#: cps/render_template.py:81 cps/templates/user_table.html:163 +#: cps/render_template.py:83 cps/templates/user_table.html:163 msgid "Show publisher selection" msgstr "" -#: cps/render_template.py:82 cps/templates/book_table.html:70 +#: cps/render_template.py:84 cps/templates/book_table.html:70 #: cps/templates/index.xml:97 cps/templates/search_form.html:107 -#: cps/web.py:1018 +#: cps/web.py:1108 msgid "Languages" msgstr "" -#: cps/render_template.py:85 cps/templates/user_table.html:155 +#: cps/render_template.py:87 cps/templates/user_table.html:155 msgid "Show language selection" msgstr "" -#: cps/render_template.py:86 cps/templates/index.xml:104 +#: cps/render_template.py:88 cps/templates/index.xml:104 msgid "Ratings" msgstr "" -#: cps/render_template.py:88 cps/templates/user_table.html:164 +#: cps/render_template.py:90 cps/templates/user_table.html:164 msgid "Show ratings selection" msgstr "" -#: cps/render_template.py:89 cps/templates/index.xml:112 +#: cps/render_template.py:91 cps/templates/index.xml:112 msgid "File formats" msgstr "" -#: cps/render_template.py:91 cps/templates/user_table.html:165 +#: cps/render_template.py:93 cps/templates/user_table.html:165 msgid "Show file formats selection" msgstr "" -#: cps/render_template.py:93 cps/web.py:703 +#: cps/render_template.py:95 cps/web.py:755 msgid "Archived Books" msgstr "" -#: cps/render_template.py:95 cps/templates/user_table.html:166 +#: cps/render_template.py:97 cps/templates/user_table.html:166 msgid "Show archived books" msgstr "" -#: cps/render_template.py:97 cps/web.py:780 +#: cps/render_template.py:100 cps/web.py:837 msgid "Books List" msgstr "" -#: cps/render_template.py:99 cps/templates/user_table.html:168 +#: cps/render_template.py:102 cps/templates/user_table.html:168 msgid "Show Books List" msgstr "" @@ -1046,260 +1065,264 @@ msgstr "" msgid "Create a Shelf" msgstr "" -#: cps/shelf.py:237 +#: cps/shelf.py:236 msgid "Sorry you are not allowed to edit this shelf" msgstr "" -#: cps/shelf.py:239 +#: cps/shelf.py:238 msgid "Edit a shelf" msgstr "" -#: cps/shelf.py:249 +#: cps/shelf.py:248 msgid "Sorry you are not allowed to create a public shelf" msgstr "" -#: cps/shelf.py:266 +#: cps/shelf.py:265 #, python-format msgid "Shelf %(title)s created" msgstr "" -#: cps/shelf.py:269 +#: cps/shelf.py:268 #, python-format msgid "Shelf %(title)s changed" msgstr "" -#: cps/shelf.py:283 +#: cps/shelf.py:282 msgid "There was an error" msgstr "" -#: cps/shelf.py:305 +#: cps/shelf.py:304 #, python-format msgid "A public shelf with the name '%(title)s' already exists." msgstr "" -#: cps/shelf.py:316 +#: cps/shelf.py:315 #, python-format msgid "A private shelf with the name '%(title)s' already exists." msgstr "" #: cps/shelf.py:337 +msgid "Error deleting Shelf" +msgstr "" + +#: cps/shelf.py:339 msgid "Shelf successfully deleted" msgstr "" -#: cps/shelf.py:386 +#: cps/shelf.py:389 #, python-format msgid "Change order of Shelf: '%(name)s'" msgstr "" -#: cps/shelf.py:456 +#: cps/shelf.py:461 #, python-format msgid "Shelf: '%(name)s'" msgstr "" -#: cps/shelf.py:460 +#: cps/shelf.py:465 msgid "Error opening shelf. Shelf does not exist or is not accessible" msgstr "" -#: cps/updater.py:403 cps/updater.py:414 cps/updater.py:514 cps/updater.py:529 +#: cps/updater.py:426 cps/updater.py:437 cps/updater.py:538 cps/updater.py:553 msgid "Unexpected data while reading update information" msgstr "" -#: cps/updater.py:410 cps/updater.py:521 +#: cps/updater.py:433 cps/updater.py:545 msgid "No update available. You already have the latest version installed" msgstr "" -#: cps/updater.py:428 +#: cps/updater.py:451 msgid "A new update is available. Click on the button below to update to the latest version." msgstr "" -#: cps/updater.py:446 +#: cps/updater.py:469 msgid "Could not fetch update information" msgstr "" -#: cps/updater.py:456 +#: cps/updater.py:479 msgid "Click on the button below to update to the latest stable version." msgstr "" -#: cps/updater.py:465 cps/updater.py:479 cps/updater.py:490 +#: cps/updater.py:488 cps/updater.py:502 cps/updater.py:513 #, python-format msgid "A new update is available. Click on the button below to update to version: %(version)s" msgstr "" -#: cps/updater.py:507 +#: cps/updater.py:531 msgid "No release information available" msgstr "" -#: cps/templates/index.html:5 cps/web.py:440 +#: cps/templates/index.html:5 cps/web.py:434 msgid "Discover (Random Books)" msgstr "" -#: cps/web.py:471 +#: cps/web.py:470 msgid "Hot Books (Most Downloaded)" msgstr "" -#: cps/web.py:507 +#: cps/web.py:501 #, python-format msgid "Downloaded books by %(user)s" msgstr "" -#: cps/web.py:539 +#: cps/web.py:534 #, python-format msgid "Author: %(name)s" msgstr "" -#: cps/web.py:554 +#: cps/web.py:570 #, python-format msgid "Publisher: %(name)s" msgstr "" -#: cps/web.py:569 +#: cps/web.py:598 #, python-format msgid "Series: %(serie)s" msgstr "" -#: cps/web.py:582 +#: cps/web.py:610 #, python-format msgid "Rating: %(rating)s stars" msgstr "" -#: cps/web.py:597 +#: cps/web.py:626 #, python-format msgid "File format: %(format)s" msgstr "" -#: cps/web.py:615 +#: cps/web.py:663 #, python-format msgid "Category: %(name)s" msgstr "" -#: cps/web.py:631 +#: cps/web.py:690 #, python-format msgid "Language: %(name)s" msgstr "" -#: cps/templates/layout.html:56 cps/web.py:737 cps/web.py:1371 +#: cps/templates/layout.html:56 cps/web.py:789 cps/web.py:1444 msgid "Advanced Search" msgstr "" #: cps/templates/book_edit.html:235 cps/templates/feed.xml:33 #: cps/templates/index.xml:11 cps/templates/layout.html:45 #: cps/templates/layout.html:48 cps/templates/search_form.html:226 -#: cps/web.py:750 cps/web.py:1077 +#: cps/web.py:807 cps/web.py:1164 msgid "Search" msgstr "" -#: cps/templates/admin.html:16 cps/web.py:903 +#: cps/templates/admin.html:16 cps/web.py:979 msgid "Downloads" msgstr "" -#: cps/web.py:980 +#: cps/web.py:1068 msgid "Ratings list" msgstr "" -#: cps/web.py:1001 +#: cps/web.py:1095 msgid "File formats list" msgstr "" -#: cps/templates/layout.html:73 cps/templates/tasks.html:7 cps/web.py:1055 +#: cps/templates/layout.html:73 cps/templates/tasks.html:7 cps/web.py:1149 msgid "Tasks" msgstr "" -#: cps/web.py:1215 +#: cps/web.py:1286 msgid "Published after " msgstr "" -#: cps/web.py:1222 +#: cps/web.py:1293 msgid "Published before " msgstr "" -#: cps/web.py:1244 +#: cps/web.py:1315 #, python-format msgid "Rating <= %(rating)s" msgstr "" -#: cps/web.py:1246 +#: cps/web.py:1317 #, python-format msgid "Rating >= %(rating)s" msgstr "" -#: cps/web.py:1248 +#: cps/web.py:1319 #, python-format msgid "Read Status = %(status)s" msgstr "" -#: cps/web.py:1353 +#: cps/web.py:1425 msgid "Error on search for custom columns, please restart Calibre-Web" msgstr "" -#: cps/web.py:1449 +#: cps/web.py:1527 #, python-format msgid "Book successfully queued for sending to %(kindlemail)s" msgstr "" -#: cps/web.py:1453 +#: cps/web.py:1531 #, python-format msgid "Oops! There was an error sending this book: %(res)s" msgstr "" -#: cps/web.py:1455 +#: cps/web.py:1533 msgid "Please update your profile with a valid Send to Kindle E-mail Address." msgstr "" -#: cps/web.py:1472 +#: cps/web.py:1550 msgid "E-Mail server is not configured, please contact your administrator!" msgstr "" -#: cps/templates/layout.html:85 cps/templates/register.html:17 cps/web.py:1473 -#: cps/web.py:1480 cps/web.py:1486 cps/web.py:1505 cps/web.py:1509 -#: cps/web.py:1515 +#: cps/templates/layout.html:85 cps/templates/register.html:17 cps/web.py:1551 +#: cps/web.py:1558 cps/web.py:1564 cps/web.py:1583 cps/web.py:1587 +#: cps/web.py:1593 msgid "Register" msgstr "" -#: cps/web.py:1507 +#: cps/web.py:1585 msgid "Your e-mail is not allowed to register" msgstr "" -#: cps/web.py:1510 +#: cps/web.py:1588 msgid "Confirmation e-mail was send to your e-mail account." msgstr "" -#: cps/web.py:1524 +#: cps/web.py:1602 msgid "Cannot activate LDAP authentication" msgstr "" -#: cps/web.py:1543 +#: cps/web.py:1621 #, python-format msgid "Fallback Login as: '%(nickname)s', LDAP Server not reachable, or user not known" msgstr "" -#: cps/web.py:1549 +#: cps/web.py:1627 #, python-format msgid "Could not login: %(message)s" msgstr "" -#: cps/web.py:1553 cps/web.py:1578 +#: cps/web.py:1631 cps/web.py:1656 msgid "Wrong Username or Password" msgstr "" -#: cps/web.py:1560 +#: cps/web.py:1638 msgid "New Password was send to your email address" msgstr "" -#: cps/web.py:1566 +#: cps/web.py:1644 msgid "Please enter valid username to reset password" msgstr "" -#: cps/web.py:1573 +#: cps/web.py:1651 #, python-format msgid "You are now logged in as: '%(nickname)s'" msgstr "" -#: cps/web.py:1639 cps/web.py:1688 +#: cps/web.py:1717 cps/web.py:1766 #, python-format msgid "%(name)s's profile" msgstr "" -#: cps/web.py:1655 +#: cps/web.py:1733 msgid "Profile updated" msgstr "" @@ -1307,36 +1330,36 @@ msgstr "" msgid "Found no valid gmail.json file with OAuth information" msgstr "" -#: cps/tasks/convert.py:137 +#: cps/tasks/convert.py:154 #, python-format msgid "Calibre ebook-convert %(tool)s not found" msgstr "" -#: cps/tasks/convert.py:163 +#: cps/tasks/convert.py:187 #, python-format msgid "%(format)s format not found on disk" msgstr "" -#: cps/tasks/convert.py:167 +#: cps/tasks/convert.py:191 msgid "Ebook converter failed with unknown error" msgstr "" -#: cps/tasks/convert.py:177 +#: cps/tasks/convert.py:201 #, python-format msgid "Kepubify-converter failed: %(error)s" msgstr "" -#: cps/tasks/convert.py:199 +#: cps/tasks/convert.py:223 #, python-format msgid "Converted file not found or more than one file in folder %(folder)s" msgstr "" -#: cps/tasks/convert.py:222 +#: cps/tasks/convert.py:246 #, python-format msgid "Ebook-converter failed: %(error)s" msgstr "" -#: cps/tasks/convert.py:245 +#: cps/tasks/convert.py:269 #, python-format msgid "Calibre failed with error: %(error)s" msgstr "" @@ -1391,7 +1414,7 @@ msgid "Edit" msgstr "" #: cps/templates/admin.html:25 cps/templates/book_edit.html:16 -#: cps/templates/book_table.html:97 cps/templates/modal_dialogs.html:63 +#: cps/templates/book_table.html:100 cps/templates/modal_dialogs.html:63 #: cps/templates/modal_dialogs.html:116 cps/templates/user_edit.html:67 #: cps/templates/user_table.html:149 msgid "Delete" @@ -1401,179 +1424,179 @@ msgstr "" msgid "Public Shelf" msgstr "" -#: cps/templates/admin.html:51 +#: cps/templates/admin.html:53 msgid "Add New User" msgstr "" -#: cps/templates/admin.html:53 +#: cps/templates/admin.html:55 msgid "Import LDAP Users" msgstr "" -#: cps/templates/admin.html:60 +#: cps/templates/admin.html:62 msgid "E-mail Server Settings" msgstr "" -#: cps/templates/admin.html:65 cps/templates/email_edit.html:31 +#: cps/templates/admin.html:67 cps/templates/email_edit.html:31 msgid "SMTP Hostname" msgstr "" -#: cps/templates/admin.html:69 cps/templates/email_edit.html:35 +#: cps/templates/admin.html:71 cps/templates/email_edit.html:35 msgid "SMTP Port" msgstr "" -#: cps/templates/admin.html:73 cps/templates/email_edit.html:39 +#: cps/templates/admin.html:75 cps/templates/email_edit.html:39 msgid "Encryption" msgstr "" -#: cps/templates/admin.html:77 cps/templates/email_edit.html:47 +#: cps/templates/admin.html:79 cps/templates/email_edit.html:47 msgid "SMTP Login" msgstr "" -#: cps/templates/admin.html:81 cps/templates/admin.html:92 +#: cps/templates/admin.html:83 cps/templates/admin.html:94 #: cps/templates/email_edit.html:55 msgid "From E-mail" msgstr "" -#: cps/templates/admin.html:88 +#: cps/templates/admin.html:90 msgid "E-Mail Service" msgstr "" -#: cps/templates/admin.html:89 +#: cps/templates/admin.html:91 msgid "Gmail via Oauth2" msgstr "" -#: cps/templates/admin.html:104 +#: cps/templates/admin.html:106 msgid "Configuration" msgstr "" -#: cps/templates/admin.html:107 +#: cps/templates/admin.html:109 msgid "Calibre Database Directory" msgstr "" -#: cps/templates/admin.html:111 cps/templates/config_edit.html:68 +#: cps/templates/admin.html:113 cps/templates/config_edit.html:68 msgid "Log Level" msgstr "" -#: cps/templates/admin.html:115 +#: cps/templates/admin.html:117 msgid "Port" msgstr "" -#: cps/templates/admin.html:120 +#: cps/templates/admin.html:122 msgid "External Port" msgstr "" -#: cps/templates/admin.html:127 cps/templates/config_view_edit.html:28 +#: cps/templates/admin.html:129 cps/templates/config_view_edit.html:28 msgid "Books per Page" msgstr "" -#: cps/templates/admin.html:131 +#: cps/templates/admin.html:133 msgid "Uploads" msgstr "" -#: cps/templates/admin.html:135 +#: cps/templates/admin.html:137 msgid "Anonymous Browsing" msgstr "" -#: cps/templates/admin.html:139 +#: cps/templates/admin.html:141 msgid "Public Registration" msgstr "" -#: cps/templates/admin.html:143 +#: cps/templates/admin.html:145 msgid "Magic Link Remote Login" msgstr "" -#: cps/templates/admin.html:147 +#: cps/templates/admin.html:149 msgid "Reverse Proxy Login" msgstr "" -#: cps/templates/admin.html:152 cps/templates/config_edit.html:173 +#: cps/templates/admin.html:154 cps/templates/config_edit.html:173 msgid "Reverse Proxy Header Name" msgstr "" -#: cps/templates/admin.html:157 +#: cps/templates/admin.html:159 msgid "Edit Calibre Database Configuration" msgstr "" -#: cps/templates/admin.html:158 +#: cps/templates/admin.html:160 msgid "Edit Basic Configuration" msgstr "" -#: cps/templates/admin.html:159 +#: cps/templates/admin.html:161 msgid "Edit UI Configuration" msgstr "" -#: cps/templates/admin.html:164 +#: cps/templates/admin.html:166 msgid "Administration" msgstr "" -#: cps/templates/admin.html:165 +#: cps/templates/admin.html:167 msgid "Download Debug Package" msgstr "" -#: cps/templates/admin.html:166 +#: cps/templates/admin.html:168 msgid "View Logs" msgstr "" -#: cps/templates/admin.html:169 +#: cps/templates/admin.html:171 msgid "Reconnect Calibre Database" msgstr "" -#: cps/templates/admin.html:170 +#: cps/templates/admin.html:172 msgid "Restart" msgstr "" -#: cps/templates/admin.html:171 +#: cps/templates/admin.html:173 msgid "Shutdown" msgstr "" -#: cps/templates/admin.html:176 +#: cps/templates/admin.html:178 msgid "Update" msgstr "" -#: cps/templates/admin.html:180 +#: cps/templates/admin.html:182 msgid "Version" msgstr "" -#: cps/templates/admin.html:181 +#: cps/templates/admin.html:183 msgid "Details" msgstr "" -#: cps/templates/admin.html:187 +#: cps/templates/admin.html:189 msgid "Current version" msgstr "" -#: cps/templates/admin.html:194 +#: cps/templates/admin.html:196 msgid "Check for Update" msgstr "" -#: cps/templates/admin.html:195 +#: cps/templates/admin.html:197 msgid "Perform Update" msgstr "" -#: cps/templates/admin.html:208 +#: cps/templates/admin.html:210 msgid "Are you sure you want to restart?" msgstr "" -#: cps/templates/admin.html:213 cps/templates/admin.html:227 -#: cps/templates/admin.html:247 cps/templates/config_db.html:70 +#: cps/templates/admin.html:215 cps/templates/admin.html:229 +#: cps/templates/admin.html:249 cps/templates/config_db.html:70 msgid "OK" msgstr "" -#: cps/templates/admin.html:214 cps/templates/admin.html:228 -#: cps/templates/book_edit.html:213 cps/templates/book_table.html:124 +#: cps/templates/admin.html:216 cps/templates/admin.html:230 +#: cps/templates/book_edit.html:213 cps/templates/book_table.html:127 #: cps/templates/config_db.html:54 cps/templates/config_edit.html:359 -#: cps/templates/config_view_edit.html:173 cps/templates/modal_dialogs.html:64 +#: cps/templates/config_view_edit.html:175 cps/templates/modal_dialogs.html:64 #: cps/templates/modal_dialogs.html:99 cps/templates/modal_dialogs.html:117 #: cps/templates/modal_dialogs.html:135 cps/templates/shelf_edit.html:27 #: cps/templates/user_edit.html:144 msgid "Cancel" msgstr "" -#: cps/templates/admin.html:226 +#: cps/templates/admin.html:228 msgid "Are you sure you want to shutdown?" msgstr "" -#: cps/templates/admin.html:238 +#: cps/templates/admin.html:240 msgid "Updating, please do not reload this page" msgstr "" @@ -1585,44 +1608,43 @@ msgstr "" msgid "In Library" msgstr "" -#: cps/templates/author.html:26 cps/templates/index.html:72 -#: cps/templates/search.html:29 cps/templates/shelf.html:19 +#: cps/templates/author.html:26 cps/templates/index.html:73 +#: cps/templates/search.html:30 cps/templates/shelf.html:19 msgid "Sort according to book date, newest first" msgstr "" -#: cps/templates/author.html:27 cps/templates/index.html:73 -#: cps/templates/search.html:30 cps/templates/shelf.html:20 +#: cps/templates/author.html:27 cps/templates/index.html:74 +#: cps/templates/search.html:31 cps/templates/shelf.html:20 msgid "Sort according to book date, oldest first" msgstr "" -#: cps/templates/author.html:28 cps/templates/index.html:74 -#: cps/templates/search.html:31 cps/templates/shelf.html:21 +#: cps/templates/author.html:28 cps/templates/index.html:75 +#: cps/templates/search.html:32 cps/templates/shelf.html:21 msgid "Sort title in alphabetical order" msgstr "" -#: cps/templates/author.html:29 cps/templates/index.html:75 -#: cps/templates/search.html:32 cps/templates/shelf.html:22 +#: cps/templates/author.html:29 cps/templates/index.html:76 +#: cps/templates/search.html:33 cps/templates/shelf.html:22 msgid "Sort title in reverse alphabetical order" msgstr "" -#: cps/templates/author.html:30 cps/templates/index.html:78 -#: cps/templates/search.html:35 cps/templates/shelf.html:25 +#: cps/templates/author.html:30 cps/templates/index.html:79 +#: cps/templates/search.html:36 cps/templates/shelf.html:25 msgid "Sort according to publishing date, newest first" msgstr "" -#: cps/templates/author.html:31 cps/templates/index.html:79 -#: cps/templates/search.html:36 cps/templates/shelf.html:26 +#: cps/templates/author.html:31 cps/templates/index.html:80 +#: cps/templates/search.html:37 cps/templates/shelf.html:26 msgid "Sort according to publishing date, oldest first" msgstr "" -#: cps/templates/author.html:57 cps/templates/author.html:117 -#: cps/templates/discover.html:30 cps/templates/index.html:29 -#: cps/templates/index.html:111 cps/templates/search.html:65 -#: cps/templates/shelf.html:54 +#: cps/templates/author.html:56 cps/templates/author.html:115 +#: cps/templates/index.html:29 cps/templates/index.html:112 +#: cps/templates/search.html:66 cps/templates/shelf.html:54 msgid "reduce" msgstr "" -#: cps/templates/author.html:101 +#: cps/templates/author.html:99 msgid "More by" msgstr "" @@ -1747,7 +1769,7 @@ msgid "Fetch Metadata" msgstr "" #: cps/templates/book_edit.html:212 cps/templates/config_db.html:53 -#: cps/templates/config_edit.html:358 cps/templates/config_view_edit.html:172 +#: cps/templates/config_edit.html:358 cps/templates/config_view_edit.html:174 #: cps/templates/email_edit.html:65 cps/templates/shelf_edit.html:25 #: cps/templates/shelf_order.html:41 cps/templates/user_edit.html:142 msgid "Save" @@ -1874,26 +1896,34 @@ msgstr "" msgid "Comments" msgstr "" -#: cps/templates/book_table.html:77 cps/templates/book_table.html:79 -#: cps/templates/book_table.html:81 cps/templates/book_table.html:83 -#: cps/templates/book_table.html:87 cps/templates/book_table.html:89 -#: cps/templates/book_table.html:91 cps/templates/book_table.html:93 +#: cps/templates/book_table.html:75 +msgid "Archiv Status" +msgstr "" + +#: cps/templates/book_table.html:77 cps/templates/search_form.html:42 +msgid "Read Status" +msgstr "" + +#: cps/templates/book_table.html:80 cps/templates/book_table.html:82 +#: cps/templates/book_table.html:84 cps/templates/book_table.html:86 +#: cps/templates/book_table.html:90 cps/templates/book_table.html:92 +#: cps/templates/book_table.html:96 msgid "Enter " msgstr "" -#: cps/templates/book_table.html:110 cps/templates/modal_dialogs.html:46 +#: cps/templates/book_table.html:113 cps/templates/modal_dialogs.html:46 msgid "Are you really sure?" msgstr "" -#: cps/templates/book_table.html:114 +#: cps/templates/book_table.html:117 msgid "Books with Title will be merged from:" msgstr "" -#: cps/templates/book_table.html:118 +#: cps/templates/book_table.html:121 msgid "Into Book with Title:" msgstr "" -#: cps/templates/book_table.html:123 +#: cps/templates/book_table.html:126 msgid "Merge" msgstr "" @@ -2069,11 +2099,6 @@ msgstr "" msgid "LDAP Encryption" msgstr "" -#: cps/templates/config_edit.html:204 cps/templates/config_view_edit.html:62 -#: cps/templates/email_edit.html:41 -msgid "None" -msgstr "" - #: cps/templates/config_edit.html:205 msgid "TLS" msgstr "" @@ -2290,11 +2315,11 @@ msgstr "" msgid "Show Random Books in Detail View" msgstr "" -#: cps/templates/config_view_edit.html:165 cps/templates/user_edit.html:87 +#: cps/templates/config_view_edit.html:166 cps/templates/user_edit.html:87 msgid "Add Allowed/Denied Tags" msgstr "" -#: cps/templates/config_view_edit.html:166 +#: cps/templates/config_view_edit.html:167 msgid "Add Allowed/Denied custom column values" msgstr "" @@ -2343,13 +2368,13 @@ msgstr "" msgid "Description:" msgstr "" -#: cps/templates/detail.html:256 cps/templates/search.html:14 +#: cps/templates/detail.html:256 cps/templates/search.html:15 msgid "Add to shelf" msgstr "" #: cps/templates/detail.html:267 cps/templates/detail.html:284 #: cps/templates/feed.xml:79 cps/templates/layout.html:137 -#: cps/templates/search.html:20 +#: cps/templates/search.html:21 msgid "(Public)" msgstr "" @@ -2427,10 +2452,14 @@ msgstr "" msgid "Next" msgstr "" -#: cps/templates/generate_kobo_auth_url.html:5 +#: cps/templates/generate_kobo_auth_url.html:6 msgid "Open the .kobo/Kobo eReader.conf file in a text editor and add (or edit):" msgstr "" +#: cps/templates/generate_kobo_auth_url.html:11 +msgid "Kobo Token:" +msgstr "" + #: cps/templates/http_error.html:31 msgid "Calibre-Web Instance is unconfigured, please contact your administrator" msgstr "" @@ -2447,29 +2476,29 @@ msgstr "" msgid "Logout User" msgstr "" -#: cps/templates/index.html:69 +#: cps/templates/index.html:70 msgid "Sort ascending according to download count" msgstr "" -#: cps/templates/index.html:70 +#: cps/templates/index.html:71 msgid "Sort descending according to download count" msgstr "" -#: cps/templates/index.html:76 cps/templates/search.html:33 +#: cps/templates/index.html:77 cps/templates/search.html:34 #: cps/templates/shelf.html:23 msgid "Sort authors in alphabetical order" msgstr "" -#: cps/templates/index.html:77 cps/templates/search.html:34 +#: cps/templates/index.html:78 cps/templates/search.html:35 #: cps/templates/shelf.html:24 msgid "Sort authors in reverse alphabetical order" msgstr "" -#: cps/templates/index.html:81 +#: cps/templates/index.html:82 msgid "Sort ascending according to series index" msgstr "" -#: cps/templates/index.html:82 +#: cps/templates/index.html:83 msgid "Sort descending according to series index" msgstr "" @@ -2899,10 +2928,6 @@ msgstr "" msgid "Published Date To" msgstr "" -#: cps/templates/search_form.html:42 -msgid "Read Status" -msgstr "" - #: cps/templates/search_form.html:59 msgid "Exclude Tags" msgstr "" diff --git a/optional-requirements.txt b/optional-requirements.txt index f7c7b572..07e1ad88 100644 --- a/optional-requirements.txt +++ b/optional-requirements.txt @@ -1,5 +1,5 @@ # GDrive Integration -google-api-python-client>=1.7.11,<2.37.0 +google-api-python-client>=1.7.11,<2.46.0 gevent>20.6.0,<22.0.0 greenlet>=0.4.17,<1.2.0 httplib2>=0.9.2,<0.21.0 @@ -12,8 +12,8 @@ PyYAML>=3.12 rsa>=3.4.2,<4.9.0 # Gmail -google-auth-oauthlib>=0.4.3,<0.5.0 -google-api-python-client>=1.7.11,<2.37.0 +google-auth-oauthlib>=0.4.3,<0.6.0 +google-api-python-client>=1.7.11,<2.46.0 # goodreads goodreads>=0.3.2,<0.4.0 @@ -28,8 +28,8 @@ Flask-Dance>=2.0.0,<5.2.0 SQLAlchemy-Utils>=0.33.5,<0.39.0 # metadata extraction -rarfile>=2.7 -scholarly>=1.2.0,<1.6 +rarfile>=3.2 +scholarly>=1.2.0,<1.7 markdown2>=2.0.0,<2.5.0 html2text>=2020.1.16,<2022.1.1 python-dateutil>=2.1,<2.9.0 diff --git a/requirements.txt b/requirements.txt index d9bed7bb..7a30ae06 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,8 @@ +APScheduler>=3.6.3,<3.10.0 +werkzeug<2.1.0 Babel>=1.3,<3.0 Flask-Babel>=0.11.1,<2.1.0 -Flask-Login>=0.3.2,<0.5.1 +Flask-Login>=0.3.2,<0.6.1 Flask-Principal>=0.3.2,<0.5.1 backports_abc>=0.4 Flask>=1.0.2,<2.1.0 @@ -12,6 +14,7 @@ SQLAlchemy>=1.3.0,<1.5.0 tornado>=4.1,<6.2 Wand>=0.4.4,<0.7.0 unidecode>=0.04.19,<1.4.0 -lxml>=3.8.0,<4.8.0 +lxml>=3.8.0,<4.9.0 flask-wtf>=0.14.2,<1.1.0 chardet>=3.0.0,<4.1.0 +advocate>=1.0.0,<1.1.0 diff --git a/setup.cfg b/setup.cfg index 12874151..5e427849 100644 --- a/setup.cfg +++ b/setup.cfg @@ -38,9 +38,11 @@ console_scripts = [options] include_package_data = True install_requires = + APScheduler>=3.6.3,<3.8.0 + werkzeug<2.1.0 Babel>=1.3,<3.0 Flask-Babel>=0.11.1,<2.1.0 - Flask-Login>=0.3.2,<0.5.1 + Flask-Login>=0.3.2,<0.6.1 Flask-Principal>=0.3.2,<0.5.1 backports_abc>=0.4 Flask>=1.0.2,<2.1.0 @@ -55,11 +57,12 @@ install_requires = lxml>=3.8.0,<4.8.0 flask-wtf>=0.14.2,<1.1.0 chardet>=3.0.0,<4.1.0 + advocate>=1.0.0,<1.1.0 [options.extras_require] gdrive = - google-api-python-client>=1.7.11,<2.37.0 + google-api-python-client>=1.7.11,<2.44.0 gevent>20.6.0,<22.0.0 greenlet>=0.4.17,<1.2.0 httplib2>=0.9.2,<0.21.0 @@ -71,8 +74,8 @@ gdrive = PyYAML>=3.12 rsa>=3.4.2,<4.9.0 gmail = - google-auth-oauthlib>=0.4.3,<0.5.0 - google-api-python-client>=1.7.11,<2.37.0 + google-auth-oauthlib>=0.4.3,<0.6.0 + google-api-python-client>=1.7.11,<2.44.0 goodreads = goodreads>=0.3.2,<0.4.0 python-Levenshtein>=0.12.0,<0.13.0 @@ -83,8 +86,8 @@ oauth = Flask-Dance>=2.0.0,<5.2.0 SQLAlchemy-Utils>=0.33.5,<0.39.0 metadata = - rarfile>=2.7 - scholarly>=1.2.0,<1.6 + rarfile>=3.2 + scholarly>=1.2.0,<1.7 markdown2>=2.0.0,<2.5.0 html2text>=2020.1.16,<2022.1.1 python-dateutil>=2.1,<2.9.0 diff --git a/test/Calibre-Web TestSummary_Linux.html b/test/Calibre-Web TestSummary_Linux.html index af8cfcd9..df55a037 100644 --- a/test/Calibre-Web TestSummary_Linux.html +++ b/test/Calibre-Web TestSummary_Linux.html @@ -37,20 +37,20 @@
      -

      Start Time: 2022-02-05 20:19:09

      +

      Start Time: 2022-04-25 20:37:58

      -

      Stop Time: 2022-02-06 00:20:42

      +

      Stop Time: 2022-04-26 02:14:54

      -

      Duration: 3h 15 min

      +

      Duration: 4h 44 min

      @@ -330,103 +330,43 @@ - + TestCliGdrivedb - 2 + 3 + 3 0 0 - 2 0 - Detail + Detail - + -
      TestCliGdrivedb - test_cli_gdrive_location
      - - -
      - ERROR -
      - - - +
      TestCliGdrivedb - test_cli_gdrive_folder
      + PASS - + + +
      TestCliGdrivedb - test_cli_gdrive_location
      + + PASS + + + + +
      TestCliGdrivedb - test_gdrive_db_nonwrite
      - -
      - ERROR -
      - - - - + PASS @@ -639,15 +579,15 @@ receiveMessage@chrome://remote/content/marionette/actors/MarionetteCommandsChild - + TestEbookConvertCalibreGDrive + 7 6 - 6 - 0 + 1 0 0 - Detail + Detail @@ -706,6 +646,35 @@ receiveMessage@chrome://remote/content/marionette/actors/MarionetteCommandsChild + + + +
      TestEbookConvertCalibreGDrive - test_thumbnail_cache
      + + +
      + FAIL +
      + + + + + + + @@ -792,15 +761,15 @@ receiveMessage@chrome://remote/content/marionette/actors/MarionetteCommandsChild - + TestEditAdditionalBooks - 19 17 - 0 - 0 + 10 2 + 4 + 1 - Detail + Detail @@ -851,11 +820,34 @@ receiveMessage@chrome://remote/content/marionette/actors/MarionetteCommandsChild - +
      TestEditAdditionalBooks - test_edit_book_identifier
      - PASS + +
      + FAIL +
      + + + + @@ -869,11 +861,31 @@ receiveMessage@chrome://remote/content/marionette/actors/MarionetteCommandsChild - +
      TestEditAdditionalBooks - test_edit_book_identifier_standard
      - PASS + +
      + FAIL +
      + + + + @@ -914,41 +926,26 @@ receiveMessage@chrome://remote/content/marionette/actors/MarionetteCommandsChild - +
      TestEditAdditionalBooks - test_upload_metadata_cbr
      - PASS - - - - - - -
      TestEditAdditionalBooks - test_upload_metadata_cbt
      - - PASS - - - - - - -
      TestEditAdditionalBooks - test_writeonly_calibre_database
      -
      - SKIP + ERROR
      -