mirror of
https://github.com/janeczku/calibre-web
synced 2024-12-17 21:50:31 +00:00
Merge branch 'Develop' - Improved compability for python 3.12+
This commit is contained in:
commit
a84c316e3d
@ -1 +1,3 @@
|
|||||||
graft src/calibreweb
|
graft src/calibreweb
|
||||||
|
global-exclude __pycache__
|
||||||
|
global-exclude *.pyc
|
||||||
|
@ -31,12 +31,10 @@ from flask_principal import Principal
|
|||||||
|
|
||||||
from . import logger
|
from . import logger
|
||||||
from .cli import CliParameter
|
from .cli import CliParameter
|
||||||
from .constants import CONFIG_DIR
|
|
||||||
from .reverseproxy import ReverseProxied
|
from .reverseproxy import ReverseProxied
|
||||||
from .server import WebServer
|
from .server import WebServer
|
||||||
from .dep_check import dependency_check
|
from .dep_check import dependency_check
|
||||||
from .updater import Updater
|
from .updater import Updater
|
||||||
from .babel import babel, get_locale
|
|
||||||
from . import config_sql
|
from . import config_sql
|
||||||
from . import cache_buster
|
from . import cache_buster
|
||||||
from . import ub, db
|
from . import ub, db
|
||||||
@ -183,6 +181,7 @@ def create_app():
|
|||||||
app.secret_key = os.getenv('SECRET_KEY', config_sql.get_flask_session_key(ub.session))
|
app.secret_key = os.getenv('SECRET_KEY', config_sql.get_flask_session_key(ub.session))
|
||||||
|
|
||||||
web_server.init_app(app, config)
|
web_server.init_app(app, config)
|
||||||
|
from .cw_babel import babel, get_locale
|
||||||
if hasattr(babel, "localeselector"):
|
if hasattr(babel, "localeselector"):
|
||||||
babel.init_app(app)
|
babel.init_app(app)
|
||||||
babel.localeselector(get_locale)
|
babel.localeselector(get_locale)
|
||||||
|
@ -42,19 +42,17 @@ opt = dep_check.load_dependencies(True)
|
|||||||
for i in (req + opt):
|
for i in (req + opt):
|
||||||
modules[i[1]] = i[0]
|
modules[i[1]] = i[0]
|
||||||
modules['Jinja2'] = importlib.metadata.version("jinja2")
|
modules['Jinja2'] = importlib.metadata.version("jinja2")
|
||||||
try:
|
if sys.version_info < (3, 12):
|
||||||
modules['pySqlite'] = sqlite3.version
|
modules['pySqlite'] = sqlite3.version
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
modules['SQLite'] = sqlite3.sqlite_version
|
modules['SQLite'] = sqlite3.sqlite_version
|
||||||
sorted_modules = OrderedDict((sorted(modules.items(), key=lambda x: x[0].casefold())))
|
sorted_modules = OrderedDict((sorted(modules.items(), key=lambda x: x[0].casefold())))
|
||||||
|
|
||||||
|
|
||||||
def collect_stats():
|
def collect_stats():
|
||||||
if constants.NIGHTLY_VERSION[0] == "$Format:%H$":
|
if constants.NIGHTLY_VERSION[0] == "$Format:%H$":
|
||||||
calibre_web_version = constants.STABLE_VERSION['version'].replace("b", " Beta")
|
calibre_web_version = constants.STABLE_VERSION.replace("b", " Beta")
|
||||||
else:
|
else:
|
||||||
calibre_web_version = (constants.STABLE_VERSION['version'].replace("b", " Beta") + ' - '
|
calibre_web_version = (constants.STABLE_VERSION.replace("b", " Beta") + ' - '
|
||||||
+ constants.NIGHTLY_VERSION[0].replace('%', '%%') + ' - '
|
+ constants.NIGHTLY_VERSION[0].replace('%', '%%') + ' - '
|
||||||
+ constants.NIGHTLY_VERSION[1].replace('%', '%%'))
|
+ constants.NIGHTLY_VERSION[1].replace('%', '%%'))
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ from .gdriveutils import is_gdrive_ready, gdrive_support
|
|||||||
from .render_template import render_title_template, get_sidebar_config
|
from .render_template import render_title_template, get_sidebar_config
|
||||||
from .services.worker import WorkerThread
|
from .services.worker import WorkerThread
|
||||||
from .usermanagement import user_login_required
|
from .usermanagement import user_login_required
|
||||||
from .babel import get_available_translations, get_available_locale, get_user_locale_language
|
from .cw_babel import get_available_translations, get_available_locale, get_user_locale_language
|
||||||
from . import debug_info
|
from . import debug_info
|
||||||
from .string_helper import strip_whitespaces
|
from .string_helper import strip_whitespaces
|
||||||
|
|
||||||
@ -219,7 +219,7 @@ def admin():
|
|||||||
form_date += timedelta(hours=int(commit[20:22]), minutes=int(commit[23:]))
|
form_date += timedelta(hours=int(commit[20:22]), minutes=int(commit[23:]))
|
||||||
commit = format_datetime(form_date - tz, format='short')
|
commit = format_datetime(form_date - tz, format='short')
|
||||||
else:
|
else:
|
||||||
commit = version['version'].replace("b", " Beta")
|
commit = version.replace("b", " Beta")
|
||||||
|
|
||||||
all_user = ub.session.query(ub.User).all()
|
all_user = ub.session.query(ub.User).all()
|
||||||
# email_settings = mail_config.get_mail_settings()
|
# email_settings = mail_config.get_mail_settings()
|
||||||
|
@ -29,8 +29,8 @@ from .constants import DEFAULT_SETTINGS_FILE, DEFAULT_GDRIVE_FILE
|
|||||||
|
|
||||||
def version_info():
|
def version_info():
|
||||||
if _NIGHTLY_VERSION[1].startswith('$Format'):
|
if _NIGHTLY_VERSION[1].startswith('$Format'):
|
||||||
return "Calibre-Web version: %s - unknown git-clone" % _STABLE_VERSION['version'].replace("b", " Beta")
|
return "Calibre-Web version: %s - unknown git-clone" % _STABLE_VERSION.replace("b", " Beta")
|
||||||
return "Calibre-Web version: %s -%s" % (_STABLE_VERSION['version'].replace("b", " Beta"), _NIGHTLY_VERSION[1])
|
return "Calibre-Web version: %s -%s" % (_STABLE_VERSION.replace("b", " Beta"), _NIGHTLY_VERSION[1])
|
||||||
|
|
||||||
|
|
||||||
class CliParameter(object):
|
class CliParameter(object):
|
||||||
|
@ -19,9 +19,6 @@
|
|||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
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 - production, development, or test
|
||||||
APP_MODE = os.environ.get('APP_MODE', 'production')
|
APP_MODE = os.environ.get('APP_MODE', 'production')
|
||||||
@ -175,7 +172,8 @@ BookMeta = namedtuple('BookMeta', 'file_path, extension, title, author, cover, d
|
|||||||
'series_id, languages, publisher, pubdate, identifiers')
|
'series_id, languages, publisher, pubdate, identifiers')
|
||||||
|
|
||||||
# python build process likes to have x.y.zbw -> b for beta and w a counting number
|
# python build process likes to have x.y.zbw -> b for beta and w a counting number
|
||||||
STABLE_VERSION = {'version': '0.6.24b'}
|
STABLE_VERSION = '0.6.24b'
|
||||||
|
# _version = STABLE_VERSION['version']
|
||||||
|
|
||||||
NIGHTLY_VERSION = dict()
|
NIGHTLY_VERSION = dict()
|
||||||
NIGHTLY_VERSION[0] = '$Format:%H$'
|
NIGHTLY_VERSION[0] = '$Format:%H$'
|
||||||
|
@ -63,7 +63,7 @@ def dependency_check(optional=False):
|
|||||||
deps = load_dependencies(optional)
|
deps = load_dependencies(optional)
|
||||||
for dep in deps:
|
for dep in deps:
|
||||||
try:
|
try:
|
||||||
dep_version_int = [int(x) if x.isnumeric() else 0 for x in dep[0].split('.')]
|
dep_version_int = [int(x) if x.isnumeric() else 0 for x in dep[0].split('.')[:3]]
|
||||||
low_check = [int(x) for x in dep[3].split('.')]
|
low_check = [int(x) for x in dep[3].split('.')]
|
||||||
high_check = [int(x) for x in dep[5].split('.')]
|
high_check = [int(x) for x in dep[5].split('.')]
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
|
@ -25,20 +25,7 @@ log = logger.create()
|
|||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from iso639 import languages
|
|
||||||
# iso_version = importlib.metadata.version("iso639")
|
|
||||||
get = languages.get
|
|
||||||
try:
|
|
||||||
if sys.version_info >= (3, 12):
|
|
||||||
import pkg_resources
|
|
||||||
except ImportError:
|
|
||||||
print("Python 3.12 isn't compatible with iso-639. Please install pycountry.")
|
|
||||||
except ImportError as ex:
|
|
||||||
from pycountry import languages as pyc_languages
|
from pycountry import languages as pyc_languages
|
||||||
#try:
|
|
||||||
# iso_version = importlib.metadata.version("pycountry") + ' (PyCountry)'
|
|
||||||
#except (ImportError, Exception):
|
|
||||||
# iso_version = "?" + ' (PyCountry)'
|
|
||||||
|
|
||||||
def _copy_fields(l):
|
def _copy_fields(l):
|
||||||
l.part1 = getattr(l, 'alpha_2', None)
|
l.part1 = getattr(l, 'alpha_2', None)
|
||||||
@ -52,6 +39,11 @@ except ImportError as ex:
|
|||||||
return _copy_fields(pyc_languages.get(alpha_2=part1))
|
return _copy_fields(pyc_languages.get(alpha_2=part1))
|
||||||
if name is not None:
|
if name is not None:
|
||||||
return _copy_fields(pyc_languages.get(name=name))
|
return _copy_fields(pyc_languages.get(name=name))
|
||||||
|
except ImportError as ex:
|
||||||
|
if sys.version_info >= (3, 12):
|
||||||
|
print("Python 3.12 isn't compatible with iso-639. Please install pycountry.")
|
||||||
|
from iso639 import languages
|
||||||
|
get = languages.get
|
||||||
|
|
||||||
|
|
||||||
def get_language_names(locale):
|
def get_language_names(locale):
|
||||||
@ -109,6 +101,6 @@ def get_lang3(lang):
|
|||||||
ret_value = lang
|
ret_value = lang
|
||||||
else:
|
else:
|
||||||
ret_value = ""
|
ret_value = ""
|
||||||
except KeyError:
|
except (KeyError, AttributeError):
|
||||||
ret_value = lang
|
ret_value = lang
|
||||||
return ret_value
|
return ret_value
|
||||||
|
@ -42,6 +42,7 @@ class BackgroundScheduler:
|
|||||||
if cls._instance is None:
|
if cls._instance is None:
|
||||||
cls._instance = super(BackgroundScheduler, cls).__new__(cls)
|
cls._instance = super(BackgroundScheduler, cls).__new__(cls)
|
||||||
cls.log = logger.create()
|
cls.log = logger.create()
|
||||||
|
logger.logging.getLogger('tzlocal').setLevel(logger.logging.WARNING)
|
||||||
cls.scheduler = BScheduler()
|
cls.scheduler = BScheduler()
|
||||||
cls.scheduler.start()
|
cls.scheduler.start()
|
||||||
|
|
||||||
|
@ -614,7 +614,7 @@ class Updater(threading.Thread):
|
|||||||
if version is False:
|
if version is False:
|
||||||
status['current_commit_hash'] = _(u'Unknown')
|
status['current_commit_hash'] = _(u'Unknown')
|
||||||
else:
|
else:
|
||||||
status['current_commit_hash'] = version['version']
|
status['current_commit_hash'] = version
|
||||||
try:
|
try:
|
||||||
headers = {'Accept': 'application/vnd.github.v3+json'}
|
headers = {'Accept': 'application/vnd.github.v3+json'}
|
||||||
r = requests.get(repository_url, headers=headers, timeout=10)
|
r = requests.get(repository_url, headers=headers, timeout=10)
|
||||||
|
10
cps/web.py
10
cps/web.py
@ -23,6 +23,7 @@ import json
|
|||||||
import mimetypes
|
import mimetypes
|
||||||
import chardet # dependency of requests
|
import chardet # dependency of requests
|
||||||
import copy
|
import copy
|
||||||
|
import importlib
|
||||||
|
|
||||||
from flask import Blueprint, jsonify
|
from flask import Blueprint, jsonify
|
||||||
from flask import request, redirect, send_from_directory, make_response, flash, abort, url_for, Response
|
from flask import request, redirect, send_from_directory, make_response, flash, abort, url_for, Response
|
||||||
@ -36,7 +37,6 @@ from sqlalchemy.exc import IntegrityError, InvalidRequestError, OperationalError
|
|||||||
from sqlalchemy.sql.expression import text, func, false, not_, and_, or_
|
from sqlalchemy.sql.expression import text, func, false, not_, and_, or_
|
||||||
from sqlalchemy.orm.attributes import flag_modified
|
from sqlalchemy.orm.attributes import flag_modified
|
||||||
from sqlalchemy.sql.functions import coalesce
|
from sqlalchemy.sql.functions import coalesce
|
||||||
|
|
||||||
from werkzeug.datastructures import Headers
|
from werkzeug.datastructures import Headers
|
||||||
from werkzeug.security import generate_password_hash, check_password_hash
|
from werkzeug.security import generate_password_hash, check_password_hash
|
||||||
|
|
||||||
@ -51,7 +51,7 @@ from .helper import check_valid_domain, check_email, check_username, \
|
|||||||
edit_book_read_status, valid_password
|
edit_book_read_status, valid_password
|
||||||
from .pagination import Pagination
|
from .pagination import Pagination
|
||||||
from .redirect import get_redirect_location
|
from .redirect import get_redirect_location
|
||||||
from .babel import get_available_locale
|
from .cw_babel import get_available_locale
|
||||||
from .usermanagement import login_required_if_no_ano
|
from .usermanagement import login_required_if_no_ano
|
||||||
from .kobo_sync_status import remove_synced_book
|
from .kobo_sync_status import remove_synced_book
|
||||||
from .render_template import render_title_template
|
from .render_template import render_title_template
|
||||||
@ -86,6 +86,10 @@ except ImportError:
|
|||||||
sort = sorted # Just use regular sort then, may cause issues with badly named pages in cbz/cbr files
|
sort = sorted # Just use regular sort then, may cause issues with badly named pages in cbz/cbr files
|
||||||
|
|
||||||
|
|
||||||
|
sql_version = importlib.metadata.version("sqlalchemy")
|
||||||
|
sqlalchemy_version2 = ([int(x) for x in sql_version.split('.')] >= [2, 0, 0])
|
||||||
|
|
||||||
|
|
||||||
@app.after_request
|
@app.after_request
|
||||||
def add_security_headers(resp):
|
def add_security_headers(resp):
|
||||||
default_src = ([host.strip() for host in config.config_trustedhosts.split(',') if host] +
|
default_src = ([host.strip() for host in config.config_trustedhosts.split(',') if host] +
|
||||||
@ -532,7 +536,7 @@ def render_author_books(page, author_id, order):
|
|||||||
flash(_("Oops! Selected book is unavailable. File does not exist or is not accessible"),
|
flash(_("Oops! Selected book is unavailable. File does not exist or is not accessible"),
|
||||||
category="error")
|
category="error")
|
||||||
return redirect(url_for("web.index"))
|
return redirect(url_for("web.index"))
|
||||||
if constants.sqlalchemy_version2:
|
if sqlalchemy_version2:
|
||||||
author = calibre_db.session.get(db.Authors, author_id)
|
author = calibre_db.session.get(db.Authors, author_id)
|
||||||
else:
|
else:
|
||||||
author = calibre_db.session.query(db.Authors).get(author_id)
|
author = calibre_db.session.query(db.Authors).get(author_id)
|
||||||
|
127
pyproject.toml
Normal file
127
pyproject.toml
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
[build-system]
|
||||||
|
requires = ["setuptools>=61.2"]
|
||||||
|
build-backend = "setuptools.build_meta"
|
||||||
|
|
||||||
|
[project]
|
||||||
|
name = "calibreweb"
|
||||||
|
description = "Web app for browsing, reading and downloading eBooks stored in a Calibre database."
|
||||||
|
authors = [{name = "@OzzieIsaacs", email = "Ozzie.Fernandez.Isaacs@googlemail.com"}]
|
||||||
|
maintainers = [{name = "@OzzieIsaacs"}]
|
||||||
|
license = {text = "GPLv3+"}
|
||||||
|
classifiers = [
|
||||||
|
"Development Status :: 5 - Production/Stable",
|
||||||
|
"License :: OSI Approved :: GNU Affero General Public License v3",
|
||||||
|
"Programming Language :: Python :: 3",
|
||||||
|
"Programming Language :: Python :: 3.6",
|
||||||
|
"Programming Language :: Python :: 3.7",
|
||||||
|
"Programming Language :: Python :: 3.8",
|
||||||
|
"Programming Language :: Python :: 3.9",
|
||||||
|
"Programming Language :: Python :: 3.10",
|
||||||
|
"Programming Language :: Python :: 3.11",
|
||||||
|
"Operating System :: OS Independent",
|
||||||
|
]
|
||||||
|
keywords = [
|
||||||
|
"calibre",
|
||||||
|
"calibre-web",
|
||||||
|
"library",
|
||||||
|
]
|
||||||
|
requires-python = ">=3.6"
|
||||||
|
dependencies = [
|
||||||
|
"APScheduler>=3.6.3,<3.11.0",
|
||||||
|
"Babel>=1.3,<3.0",
|
||||||
|
"Flask-Babel>=0.11.1,<4.1.0",
|
||||||
|
"Flask-Principal>=0.3.2,<0.5.1",
|
||||||
|
"Flask>=1.0.2,<3.1.0",
|
||||||
|
"iso-639>=0.4.5,<0.5.0",
|
||||||
|
"PyPDF>=3.15.6,<5.1.0",
|
||||||
|
"pytz>=2016.10",
|
||||||
|
"requests>=2.32.0,<2.33.0",
|
||||||
|
"SQLAlchemy>=1.3.0,<2.1.0",
|
||||||
|
"tornado>=6.3,<6.5",
|
||||||
|
"Wand>=0.4.4,<0.7.0",
|
||||||
|
"unidecode>=0.04.19,<1.4.0",
|
||||||
|
"lxml>=4.9.1,<5.3.0",
|
||||||
|
"flask-wtf>=0.14.2,<1.3.0",
|
||||||
|
"chardet>=3.0.0,<5.3.0",
|
||||||
|
"netifaces-plus>=0.12.0,<0.13.0",
|
||||||
|
"urllib3>=1.22,<3.0",
|
||||||
|
"Flask-Limiter>=2.3.0,<3.9.0",
|
||||||
|
"regex>=2022.3.2,<2024.6.25",
|
||||||
|
"bleach>=6.0.0,<6.2.0",
|
||||||
|
"python-magic>=0.4.27,<0.5.0",
|
||||||
|
"flask-httpAuth>=4.4.0,<5.0.0",
|
||||||
|
"cryptography>=30.0.0,<44.0.0",
|
||||||
|
]
|
||||||
|
dynamic = ["version"]
|
||||||
|
|
||||||
|
[project.urls]
|
||||||
|
Homepage = "https://github.com/janeczku/calibre-web"
|
||||||
|
"Bug Tracker" = "https://github.com/janeczku/calibre-web/issues"
|
||||||
|
"Release Management" = "https://github.com/janeczku/calibre-web/releases"
|
||||||
|
Documentation = "https://github.com/janeczku/calibre-web/wiki"
|
||||||
|
"Source Code" = "https://github.com/janeczku/calibre-web"
|
||||||
|
|
||||||
|
[project.readme]
|
||||||
|
file = "README.md"
|
||||||
|
content-type = "text/markdown"
|
||||||
|
|
||||||
|
[project.optional-dependencies]
|
||||||
|
gdrive = [
|
||||||
|
"google-api-python-client>=1.7.11,<2.200.0",
|
||||||
|
"gevent>20.6.0,<24.3.0",
|
||||||
|
"greenlet>=0.4.17,<3.1.0",
|
||||||
|
"httplib2>=0.9.2,<0.23.0",
|
||||||
|
"oauth2client>=4.0.0,<4.1.4",
|
||||||
|
"uritemplate>=3.0.0,<4.2.0",
|
||||||
|
"pyasn1-modules>=0.0.8,<0.5.0",
|
||||||
|
"pyasn1>=0.1.9,<0.7.0",
|
||||||
|
"PyDrive2>=1.3.1,<1.20.0",
|
||||||
|
"PyYAML>=3.12,<6.1",
|
||||||
|
"rsa>=3.4.2,<4.10.0",
|
||||||
|
]
|
||||||
|
gmail = [
|
||||||
|
"google-auth-oauthlib>=0.4.3,<1.3.0",
|
||||||
|
"google-api-python-client>=1.7.11,<2.200.0",
|
||||||
|
]
|
||||||
|
goodreads = [
|
||||||
|
"goodreads>=0.3.2,<0.4.0",
|
||||||
|
"python-Levenshtein>=0.12.0,<0.27.0",
|
||||||
|
]
|
||||||
|
ldap = [
|
||||||
|
"python-ldap>=3.0.0,<3.5.0",
|
||||||
|
"Flask-SimpleLDAP>=1.4.0,<2.1.0",
|
||||||
|
]
|
||||||
|
oauth = [
|
||||||
|
"Flask-Dance>=2.0.0,<7.1.0",
|
||||||
|
"SQLAlchemy-Utils>=0.33.5,<0.42.0",
|
||||||
|
]
|
||||||
|
metadata = [
|
||||||
|
"rarfile>=3.2,<5.0",
|
||||||
|
"scholarly>=1.2.0,<1.8",
|
||||||
|
"markdown2>=2.0.0,<2.5.0",
|
||||||
|
"html2text>=2020.1.16,<2024.2.26",
|
||||||
|
"python-dateutil>=2.1,<2.10.0",
|
||||||
|
"beautifulsoup4>=4.0.1,<4.13.0",
|
||||||
|
"faust-cchardet>=2.1.18,<2.1.20",
|
||||||
|
"py7zr>=0.15.0,<0.21.0",
|
||||||
|
"mutagen>=1.40.0,<1.50.0",
|
||||||
|
"pycountry>=20.0.0,<25.0.0",
|
||||||
|
]
|
||||||
|
comics = [
|
||||||
|
"natsort>=2.2.0,<8.5.0",
|
||||||
|
"comicapi>=2.2.0,<3.3.0",
|
||||||
|
]
|
||||||
|
kobo = [
|
||||||
|
"jsonschema>=3.2.0,<4.24.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[project.scripts]
|
||||||
|
cps = "calibreweb:main"
|
||||||
|
|
||||||
|
[tool.setuptools]
|
||||||
|
include-package-data = true
|
||||||
|
license-files = ["LICENSE"]
|
||||||
|
|
||||||
|
[tool.setuptools.dynamic]
|
||||||
|
version = {attr = "calibreweb.cps.constants.STABLE_VERSION"}
|
||||||
|
|
110
setup.cfg
110
setup.cfg
@ -1,110 +0,0 @@
|
|||||||
[metadata]
|
|
||||||
name = calibreweb
|
|
||||||
url = https://github.com/janeczku/calibre-web
|
|
||||||
project_urls =
|
|
||||||
Bug Tracker = https://github.com/janeczku/calibre-web/issues
|
|
||||||
Release Management = https://github.com/janeczku/calibre-web/releases
|
|
||||||
Documentation = https://github.com/janeczku/calibre-web/wiki
|
|
||||||
Source Code = https://github.com/janeczku/calibre-web
|
|
||||||
description = Web app for browsing, reading and downloading eBooks stored in a Calibre database.
|
|
||||||
long_description = file: README.md
|
|
||||||
long_description_content_type = text/markdown
|
|
||||||
author = @OzzieIsaacs
|
|
||||||
author_email = Ozzie.Fernandez.Isaacs@googlemail.com
|
|
||||||
maintainer = @OzzieIsaacs
|
|
||||||
license = GPLv3+
|
|
||||||
license_files = LICENSE
|
|
||||||
classifiers =
|
|
||||||
Development Status :: 5 - Production/Stable
|
|
||||||
License :: OSI Approved :: GNU Affero General Public License v3
|
|
||||||
Programming Language :: Python :: 3
|
|
||||||
Programming Language :: Python :: 3.6
|
|
||||||
Programming Language :: Python :: 3.7
|
|
||||||
Programming Language :: Python :: 3.8
|
|
||||||
Programming Language :: Python :: 3.9
|
|
||||||
Programming Language :: Python :: 3.10
|
|
||||||
Programming Language :: Python :: 3.11
|
|
||||||
Operating System :: OS Independent
|
|
||||||
keywords =
|
|
||||||
calibre
|
|
||||||
calibre-web
|
|
||||||
library
|
|
||||||
python_requires = >=3.5
|
|
||||||
|
|
||||||
[options.entry_points]
|
|
||||||
console_scripts =
|
|
||||||
cps = calibreweb:main
|
|
||||||
|
|
||||||
[options]
|
|
||||||
include_package_data = True
|
|
||||||
install_requires =
|
|
||||||
APScheduler>=3.6.3,<3.11.0
|
|
||||||
Babel>=1.3,<3.0
|
|
||||||
Flask-Babel>=0.11.1,<4.1.0
|
|
||||||
Flask-Principal>=0.3.2,<0.5.1
|
|
||||||
Flask>=1.0.2,<3.1.0
|
|
||||||
iso-639>=0.4.5,<0.5.0
|
|
||||||
PyPDF>=3.15.6,<4.3.0
|
|
||||||
pytz>=2016.10
|
|
||||||
requests>=2.28.0,<2.32.0
|
|
||||||
SQLAlchemy>=1.3.0,<2.1.0
|
|
||||||
tornado>=6.3,<6.5
|
|
||||||
Wand>=0.4.4,<0.7.0
|
|
||||||
unidecode>=0.04.19,<1.4.0
|
|
||||||
lxml>=4.9.1,<5.3.0
|
|
||||||
flask-wtf>=0.14.2,<1.3.0
|
|
||||||
chardet>=3.0.0,<5.3.0
|
|
||||||
advocate>=1.0.0,<1.1.0
|
|
||||||
Flask-Limiter>=2.3.0,<3.9.0
|
|
||||||
regex>=2022.3.2,<2024.6.25
|
|
||||||
bleach>=6.0.0,<6.2.0
|
|
||||||
python-magic>=0.4.27,<0.5.0
|
|
||||||
flask-httpAuth>=4.4.0,<5.0.0
|
|
||||||
|
|
||||||
|
|
||||||
[options.packages.find]
|
|
||||||
where = src
|
|
||||||
include = cps/services*
|
|
||||||
|
|
||||||
[options.extras_require]
|
|
||||||
gdrive =
|
|
||||||
google-api-python-client>=1.7.11,<2.200.0
|
|
||||||
gevent>20.6.0,<24.3.0
|
|
||||||
greenlet>=0.4.17,<3.1.0
|
|
||||||
httplib2>=0.9.2,<0.23.0
|
|
||||||
oauth2client>=4.0.0,<4.1.4
|
|
||||||
uritemplate>=3.0.0,<4.2.0
|
|
||||||
pyasn1-modules>=0.0.8,<0.5.0
|
|
||||||
pyasn1>=0.1.9,<0.7.0
|
|
||||||
PyDrive2>=1.3.1,<1.20.0
|
|
||||||
PyYAML>=3.12,<6.1
|
|
||||||
rsa>=3.4.2,<4.10.0
|
|
||||||
gmail =
|
|
||||||
google-auth-oauthlib>=0.4.3,<1.3.0
|
|
||||||
google-api-python-client>=1.7.11,<2.200.0
|
|
||||||
goodreads =
|
|
||||||
goodreads>=0.3.2,<0.4.0
|
|
||||||
python-Levenshtein>=0.12.0,<0.26.0
|
|
||||||
ldap =
|
|
||||||
python-ldap>=3.0.0,<3.5.0
|
|
||||||
Flask-SimpleLDAP>=1.4.0,<2.1.0
|
|
||||||
oauth =
|
|
||||||
Flask-Dance>=2.0.0,<7.1.0
|
|
||||||
SQLAlchemy-Utils>=0.33.5,<0.42.0
|
|
||||||
metadata =
|
|
||||||
rarfile>=3.2,<5.0
|
|
||||||
scholarly>=1.2.0,<1.8
|
|
||||||
markdown2>=2.0.0,<2.5.0
|
|
||||||
html2text>=2020.1.16,<2024.2.26
|
|
||||||
python-dateutil>=2.1,<2.10.0
|
|
||||||
beautifulsoup4>=4.0.1,<4.13.0
|
|
||||||
faust-cchardet>=2.1.18,<2.1.20
|
|
||||||
py7zr>=0.15.0,<0.21.0
|
|
||||||
mutagen>=1.40.0,<1.50.0
|
|
||||||
pycountry>=20.0.0,<25.0.0
|
|
||||||
comics =
|
|
||||||
natsort>=2.2.0,<8.5.0
|
|
||||||
comicapi>=2.2.0,<3.3.0
|
|
||||||
kobo =
|
|
||||||
jsonschema>=3.2.0,<4.24.0
|
|
||||||
|
|
43
setup.py
43
setup.py
@ -1,43 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web)
|
|
||||||
# Copyright (C) 2019 decentral1se
|
|
||||||
#
|
|
||||||
# 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 <http://www.gnu.org/licenses/>.
|
|
||||||
#
|
|
||||||
# """Calibre-web distribution package setuptools installer."""
|
|
||||||
|
|
||||||
from setuptools import setup
|
|
||||||
import os
|
|
||||||
import re
|
|
||||||
import codecs
|
|
||||||
|
|
||||||
here = os.path.abspath(os.path.dirname(__file__))
|
|
||||||
|
|
||||||
def read(*parts):
|
|
||||||
with codecs.open(os.path.join(here, *parts), 'r') as fp:
|
|
||||||
return fp.read()
|
|
||||||
|
|
||||||
def find_version(*file_paths):
|
|
||||||
version_file = read(*file_paths)
|
|
||||||
version_match = re.search(r"^STABLE_VERSION\s+=\s+{['\"]version['\"]:\s*['\"](.*)['\"]}",
|
|
||||||
version_file, re.M)
|
|
||||||
if version_match:
|
|
||||||
return version_match.group(1)
|
|
||||||
raise RuntimeError("Unable to find version string.")
|
|
||||||
|
|
||||||
setup(
|
|
||||||
version=find_version("src", "calibreweb", "cps", "constants.py")
|
|
||||||
)
|
|
@ -37,20 +37,20 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-xs-6 col-md-6 col-sm-offset-3" style="margin-top:50px;">
|
<div class="col-xs-6 col-md-6 col-sm-offset-3" style="margin-top:50px;">
|
||||||
|
|
||||||
<p class='text-justify attribute'><strong>Start Time: </strong>2024-10-31 19:45:00</p>
|
<p class='text-justify attribute'><strong>Start Time: </strong>2024-11-02 08:09:02</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-xs-6 col-md-6 col-sm-offset-3">
|
<div class="col-xs-6 col-md-6 col-sm-offset-3">
|
||||||
|
|
||||||
<p class='text-justify attribute'><strong>Stop Time: </strong>2024-11-01 03:02:38</p>
|
<p class='text-justify attribute'><strong>Stop Time: </strong>2024-11-02 15:03:00</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-xs-6 col-md-6 col-sm-offset-3">
|
<div class="col-xs-6 col-md-6 col-sm-offset-3">
|
||||||
<p class='text-justify attribute'><strong>Duration: </strong>6h 11 min</p>
|
<p class='text-justify attribute'><strong>Duration: </strong>5h 47 min</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -2732,11 +2732,11 @@ IndexError: list index out of range</pre>
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
<tr id="su" class="passClass">
|
<tr id="su" class="failClass">
|
||||||
<td>TestKoboSync</td>
|
<td>TestKoboSync</td>
|
||||||
<td class="text-center">12</td>
|
<td class="text-center">12</td>
|
||||||
<td class="text-center">12</td>
|
<td class="text-center">11</td>
|
||||||
<td class="text-center">0</td>
|
<td class="text-center">1</td>
|
||||||
<td class="text-center">0</td>
|
<td class="text-center">0</td>
|
||||||
<td class="text-center">0</td>
|
<td class="text-center">0</td>
|
||||||
<td class="text-center">
|
<td class="text-center">
|
||||||
@ -2827,11 +2827,31 @@ IndexError: list index out of range</pre>
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
<tr id='pt30.10' class='hiddenRow bg-success'>
|
<tr id="ft30.10" class="none bg-danger">
|
||||||
<td>
|
<td>
|
||||||
<div class='testcase'>TestKoboSync - test_sync_shelf</div>
|
<div class='testcase'>TestKoboSync - test_sync_shelf</div>
|
||||||
</td>
|
</td>
|
||||||
<td colspan='6' align='center'>PASS</td>
|
<td colspan='6'>
|
||||||
|
<div class="text-center">
|
||||||
|
<a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_ft30.10')">FAIL</a>
|
||||||
|
</div>
|
||||||
|
<!--css div popup start-->
|
||||||
|
<div id="div_ft30.10" class="popup_window test_output" style="display:block;">
|
||||||
|
<div class='close_button pull-right'>
|
||||||
|
<button type="button" class="close" aria-label="Close" onfocus="this.blur();"
|
||||||
|
onclick="document.getElementById('div_ft30.10').style.display='none'"><span
|
||||||
|
aria-hidden="true">×</span></button>
|
||||||
|
</div>
|
||||||
|
<div class="text-left pull-left">
|
||||||
|
<pre class="text-left">Traceback (most recent call last):
|
||||||
|
File "/home/ozzie/Development/calibre-web-test/test/test_kobo_sync.py", line 372, in test_sync_shelf
|
||||||
|
self.assertEqual(1, len(data), data)
|
||||||
|
AssertionError: 1 != 0 : []</pre>
|
||||||
|
</div>
|
||||||
|
<div class="clearfix"></div>
|
||||||
|
</div>
|
||||||
|
<!--css div popup end-->
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
|
||||||
@ -3913,49 +3933,43 @@ IndexError: list index out of range</pre>
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
<tr id="su" class="errorClass">
|
<tr id="su" class="passClass">
|
||||||
<td>_ErrorHolder</td>
|
<td>TestPipInstall</td>
|
||||||
<td class="text-center">1</td>
|
<td class="text-center">3</td>
|
||||||
|
<td class="text-center">3</td>
|
||||||
<td class="text-center">0</td>
|
<td class="text-center">0</td>
|
||||||
<td class="text-center">0</td>
|
<td class="text-center">0</td>
|
||||||
<td class="text-center">1</td>
|
|
||||||
<td class="text-center">0</td>
|
<td class="text-center">0</td>
|
||||||
<td class="text-center">
|
<td class="text-center">
|
||||||
<a onclick="showClassDetail('c41', 1)">Detail</a>
|
<a onclick="showClassDetail('c41', 3)">Detail</a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<tr id="et41.1" class="none bg-info">
|
<tr id='pt41.1' class='hiddenRow bg-success'>
|
||||||
<td>
|
<td>
|
||||||
<div class='testcase'>setUpClass (test_pip_install)</div>
|
<div class='testcase'>TestPipInstall - test_command_start</div>
|
||||||
</td>
|
</td>
|
||||||
<td colspan='6'>
|
<td colspan='6' align='center'>PASS</td>
|
||||||
<div class="text-center">
|
</tr>
|
||||||
<a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_et41.1')">ERROR</a>
|
|
||||||
</div>
|
|
||||||
<!--css div popup start-->
|
|
||||||
<div id="div_et41.1" class="popup_window test_output" style="display:block;">
|
<tr id='pt41.2' class='hiddenRow bg-success'>
|
||||||
<div class='close_button pull-right'>
|
<td>
|
||||||
<button type="button" class="close" aria-label="Close" onfocus="this.blur();"
|
<div class='testcase'>TestPipInstall - test_foldername_database_location</div>
|
||||||
onclick="document.getElementById('div_et41.1').style.display='none'"><span
|
|
||||||
aria-hidden="true">×</span></button>
|
|
||||||
</div>
|
|
||||||
<div class="text-left pull-left">
|
|
||||||
<pre class="text-left">Traceback (most recent call last):
|
|
||||||
File "/home/ozzie/Development/calibre-web-test/test/test_pip_install.py", line 39, in setUpClass
|
|
||||||
make_release.main(args)
|
|
||||||
File "/home/ozzie/Development/calibre-web-test/build_release/make_release.py", line 456, in main
|
|
||||||
update_requirements()
|
|
||||||
File "/home/ozzie/Development/calibre-web-test/build_release/make_release.py", line 92, in update_requirements
|
|
||||||
with open(os.path.join(FILEPATH, "pyproject.toml"), 'r') as fp:
|
|
||||||
FileNotFoundError: [Errno 2] No such file or directory: '/home/ozzie/Development/calibre-web/pyproject.toml'</pre>
|
|
||||||
</div>
|
|
||||||
<div class="clearfix"></div>
|
|
||||||
</div>
|
|
||||||
<!--css div popup end-->
|
|
||||||
</td>
|
</td>
|
||||||
|
<td colspan='6' align='center'>PASS</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<tr id='pt41.3' class='hiddenRow bg-success'>
|
||||||
|
<td>
|
||||||
|
<div class='testcase'>TestPipInstall - test_module_start</div>
|
||||||
|
</td>
|
||||||
|
<td colspan='6' align='center'>PASS</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
|
||||||
@ -4641,12 +4655,12 @@ FileNotFoundError: [Errno 2] No such file or directory: '/home/ozzie/Develop
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
<tr id="su" class="skipClass">
|
<tr id="su" class="errorClass">
|
||||||
<td>TestUpdater</td>
|
<td>TestUpdater</td>
|
||||||
<td class="text-center">9</td>
|
<td class="text-center">9</td>
|
||||||
<td class="text-center">8</td>
|
<td class="text-center">3</td>
|
||||||
<td class="text-center">0</td>
|
<td class="text-center">1</td>
|
||||||
<td class="text-center">0</td>
|
<td class="text-center">4</td>
|
||||||
<td class="text-center">1</td>
|
<td class="text-center">1</td>
|
||||||
<td class="text-center">
|
<td class="text-center">
|
||||||
<a onclick="showClassDetail('c52', 9)">Detail</a>
|
<a onclick="showClassDetail('c52', 9)">Detail</a>
|
||||||
@ -4673,38 +4687,154 @@ FileNotFoundError: [Errno 2] No such file or directory: '/home/ozzie/Develop
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
<tr id='pt52.3' class='hiddenRow bg-success'>
|
<tr id="et52.3" class="none bg-info">
|
||||||
<td>
|
<td>
|
||||||
<div class='testcase'>TestUpdater - test_check_update_stable_errors</div>
|
<div class='testcase'>TestUpdater - test_check_update_stable_errors</div>
|
||||||
</td>
|
</td>
|
||||||
<td colspan='6' align='center'>PASS</td>
|
<td colspan='6'>
|
||||||
|
<div class="text-center">
|
||||||
|
<a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_et52.3')">ERROR</a>
|
||||||
|
</div>
|
||||||
|
<!--css div popup start-->
|
||||||
|
<div id="div_et52.3" class="popup_window test_output" style="display:block;">
|
||||||
|
<div class='close_button pull-right'>
|
||||||
|
<button type="button" class="close" aria-label="Close" onfocus="this.blur();"
|
||||||
|
onclick="document.getElementById('div_et52.3').style.display='none'"><span
|
||||||
|
aria-hidden="true">×</span></button>
|
||||||
|
</div>
|
||||||
|
<div class="text-left pull-left">
|
||||||
|
<pre class="text-left">Traceback (most recent call last):
|
||||||
|
File "/home/ozzie/Development/calibre-web-test/test/test_updater.py", line 153, in test_check_update_stable_errors
|
||||||
|
self.check_updater('Timeout', "alert", 13)
|
||||||
|
File "/home/ozzie/Development/calibre-web-test/test/test_updater.py", line 87, in check_updater
|
||||||
|
self.assertTrue(responsetext in self.check_element_on_page((By.ID, "message")).text)
|
||||||
|
AttributeError: 'bool' object has no attribute 'text'</pre>
|
||||||
|
</div>
|
||||||
|
<div class="clearfix"></div>
|
||||||
|
</div>
|
||||||
|
<!--css div popup end-->
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<tr id='pt52.4' class='hiddenRow bg-success'>
|
<tr id="et52.4" class="none bg-info">
|
||||||
<td>
|
<td>
|
||||||
<div class='testcase'>TestUpdater - test_check_update_stable_versions</div>
|
<div class='testcase'>TestUpdater - test_check_update_stable_versions</div>
|
||||||
</td>
|
</td>
|
||||||
<td colspan='6' align='center'>PASS</td>
|
<td colspan='6'>
|
||||||
|
<div class="text-center">
|
||||||
|
<a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_et52.4')">ERROR</a>
|
||||||
|
</div>
|
||||||
|
<!--css div popup start-->
|
||||||
|
<div id="div_et52.4" class="popup_window test_output" style="display:block;">
|
||||||
|
<div class='close_button pull-right'>
|
||||||
|
<button type="button" class="close" aria-label="Close" onfocus="this.blur();"
|
||||||
|
onclick="document.getElementById('div_et52.4').style.display='none'"><span
|
||||||
|
aria-hidden="true">×</span></button>
|
||||||
|
</div>
|
||||||
|
<div class="text-left pull-left">
|
||||||
|
<pre class="text-left">Traceback (most recent call last):
|
||||||
|
File "/home/ozzie/Development/calibre-web-test/test/test_updater.py", line 181, in test_check_update_stable_versions
|
||||||
|
self.check_updater('{}.{}.{}'.format(*version3), "alert-warning")
|
||||||
|
File "/home/ozzie/Development/calibre-web-test/test/test_updater.py", line 87, in check_updater
|
||||||
|
self.assertTrue(responsetext in self.check_element_on_page((By.ID, "message")).text)
|
||||||
|
AttributeError: 'bool' object has no attribute 'text'</pre>
|
||||||
|
</div>
|
||||||
|
<div class="clearfix"></div>
|
||||||
|
</div>
|
||||||
|
<!--css div popup end-->
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<tr id='pt52.5' class='hiddenRow bg-success'>
|
<tr id="et52.5" class="none bg-info">
|
||||||
<td>
|
<td>
|
||||||
<div class='testcase'>TestUpdater - test_perform_update</div>
|
<div class='testcase'>TestUpdater - test_perform_update</div>
|
||||||
</td>
|
</td>
|
||||||
<td colspan='6' align='center'>PASS</td>
|
<td colspan='6'>
|
||||||
|
<div class="text-center">
|
||||||
|
<a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_et52.5')">ERROR</a>
|
||||||
|
</div>
|
||||||
|
<!--css div popup start-->
|
||||||
|
<div id="div_et52.5" class="popup_window test_output" style="display:block;">
|
||||||
|
<div class='close_button pull-right'>
|
||||||
|
<button type="button" class="close" aria-label="Close" onfocus="this.blur();"
|
||||||
|
onclick="document.getElementById('div_et52.5').style.display='none'"><span
|
||||||
|
aria-hidden="true">×</span></button>
|
||||||
|
</div>
|
||||||
|
<div class="text-left pull-left">
|
||||||
|
<pre class="text-left">Traceback (most recent call last):
|
||||||
|
File "/home/ozzie/Development/calibre-web-test/test/test_updater.py", line 390, in test_perform_update
|
||||||
|
performUpdate.click()
|
||||||
|
File "/home/ozzie/Development/calibre-web-test/venv/lib/python3.10/site-packages/selenium/webdriver/remote/webelement.py", line 93, in click
|
||||||
|
self._execute(Command.CLICK_ELEMENT)
|
||||||
|
File "/home/ozzie/Development/calibre-web-test/venv/lib/python3.10/site-packages/selenium/webdriver/remote/webelement.py", line 403, in _execute
|
||||||
|
return self._parent.execute(command, params)
|
||||||
|
File "/home/ozzie/Development/calibre-web-test/venv/lib/python3.10/site-packages/selenium/webdriver/remote/webdriver.py", line 440, in execute
|
||||||
|
self.error_handler.check_response(response)
|
||||||
|
File "/home/ozzie/Development/calibre-web-test/venv/lib/python3.10/site-packages/selenium/webdriver/remote/errorhandler.py", line 245, in check_response
|
||||||
|
raise exception_class(message, screen, stacktrace)
|
||||||
|
selenium.common.exceptions.ElementNotInteractableException: Message: Element <div id="perform_update" class="btn btn-primary hidden"> could not be scrolled into view
|
||||||
|
Stacktrace:
|
||||||
|
RemoteError@chrome://remote/content/shared/RemoteError.sys.mjs:8:8
|
||||||
|
WebDriverError@chrome://remote/content/shared/webdriver/Errors.sys.mjs:193:5
|
||||||
|
ElementNotInteractableError@chrome://remote/content/shared/webdriver/Errors.sys.mjs:353:5
|
||||||
|
webdriverClickElement@chrome://remote/content/marionette/interaction.sys.mjs:167:11
|
||||||
|
interaction.clickElement@chrome://remote/content/marionette/interaction.sys.mjs:136:11
|
||||||
|
clickElement@chrome://remote/content/marionette/actors/MarionetteCommandsChild.sys.mjs:205:29
|
||||||
|
receiveMessage@chrome://remote/content/marionette/actors/MarionetteCommandsChild.sys.mjs:85:31</pre>
|
||||||
|
</div>
|
||||||
|
<div class="clearfix"></div>
|
||||||
|
</div>
|
||||||
|
<!--css div popup end-->
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<tr id='pt52.6' class='hiddenRow bg-success'>
|
<tr id="et52.6" class="none bg-info">
|
||||||
<td>
|
<td>
|
||||||
<div class='testcase'>TestUpdater - test_perform_update_stable_errors</div>
|
<div class='testcase'>TestUpdater - test_perform_update_stable_errors</div>
|
||||||
</td>
|
</td>
|
||||||
<td colspan='6' align='center'>PASS</td>
|
<td colspan='6'>
|
||||||
|
<div class="text-center">
|
||||||
|
<a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_et52.6')">ERROR</a>
|
||||||
|
</div>
|
||||||
|
<!--css div popup start-->
|
||||||
|
<div id="div_et52.6" class="popup_window test_output" style="display:block;">
|
||||||
|
<div class='close_button pull-right'>
|
||||||
|
<button type="button" class="close" aria-label="Close" onfocus="this.blur();"
|
||||||
|
onclick="document.getElementById('div_et52.6').style.display='none'"><span
|
||||||
|
aria-hidden="true">×</span></button>
|
||||||
|
</div>
|
||||||
|
<div class="text-left pull-left">
|
||||||
|
<pre class="text-left">Traceback (most recent call last):
|
||||||
|
File "/home/ozzie/Development/calibre-web-test/test/test_updater.py", line 330, in test_perform_update_stable_errors
|
||||||
|
performUpdate.click()
|
||||||
|
File "/home/ozzie/Development/calibre-web-test/venv/lib/python3.10/site-packages/selenium/webdriver/remote/webelement.py", line 93, in click
|
||||||
|
self._execute(Command.CLICK_ELEMENT)
|
||||||
|
File "/home/ozzie/Development/calibre-web-test/venv/lib/python3.10/site-packages/selenium/webdriver/remote/webelement.py", line 403, in _execute
|
||||||
|
return self._parent.execute(command, params)
|
||||||
|
File "/home/ozzie/Development/calibre-web-test/venv/lib/python3.10/site-packages/selenium/webdriver/remote/webdriver.py", line 440, in execute
|
||||||
|
self.error_handler.check_response(response)
|
||||||
|
File "/home/ozzie/Development/calibre-web-test/venv/lib/python3.10/site-packages/selenium/webdriver/remote/errorhandler.py", line 245, in check_response
|
||||||
|
raise exception_class(message, screen, stacktrace)
|
||||||
|
selenium.common.exceptions.ElementNotInteractableException: Message: Element <div id="perform_update" class="btn btn-primary hidden"> could not be scrolled into view
|
||||||
|
Stacktrace:
|
||||||
|
RemoteError@chrome://remote/content/shared/RemoteError.sys.mjs:8:8
|
||||||
|
WebDriverError@chrome://remote/content/shared/webdriver/Errors.sys.mjs:193:5
|
||||||
|
ElementNotInteractableError@chrome://remote/content/shared/webdriver/Errors.sys.mjs:353:5
|
||||||
|
webdriverClickElement@chrome://remote/content/marionette/interaction.sys.mjs:167:11
|
||||||
|
interaction.clickElement@chrome://remote/content/marionette/interaction.sys.mjs:136:11
|
||||||
|
clickElement@chrome://remote/content/marionette/actors/MarionetteCommandsChild.sys.mjs:205:29
|
||||||
|
receiveMessage@chrome://remote/content/marionette/actors/MarionetteCommandsChild.sys.mjs:85:31</pre>
|
||||||
|
</div>
|
||||||
|
<div class="clearfix"></div>
|
||||||
|
</div>
|
||||||
|
<!--css div popup end-->
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
|
||||||
@ -4744,11 +4874,31 @@ FileNotFoundError: [Errno 2] No such file or directory: '/home/ozzie/Develop
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
<tr id='pt52.9' class='hiddenRow bg-success'>
|
<tr id="ft52.9" class="none bg-danger">
|
||||||
<td>
|
<td>
|
||||||
<div class='testcase'>TestUpdater - test_update_write_protect</div>
|
<div class='testcase'>TestUpdater - test_update_write_protect</div>
|
||||||
</td>
|
</td>
|
||||||
<td colspan='6' align='center'>PASS</td>
|
<td colspan='6'>
|
||||||
|
<div class="text-center">
|
||||||
|
<a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_ft52.9')">FAIL</a>
|
||||||
|
</div>
|
||||||
|
<!--css div popup start-->
|
||||||
|
<div id="div_ft52.9" class="popup_window test_output" style="display:block;">
|
||||||
|
<div class='close_button pull-right'>
|
||||||
|
<button type="button" class="close" aria-label="Close" onfocus="this.blur();"
|
||||||
|
onclick="document.getElementById('div_ft52.9').style.display='none'"><span
|
||||||
|
aria-hidden="true">×</span></button>
|
||||||
|
</div>
|
||||||
|
<div class="text-left pull-left">
|
||||||
|
<pre class="text-left">Traceback (most recent call last):
|
||||||
|
File "/home/ozzie/Development/calibre-web-test/test/test_updater.py", line 431, in test_update_write_protect
|
||||||
|
self.assertTrue(self.check_element_on_page((By.ID, "message")))
|
||||||
|
AssertionError: False is not true</pre>
|
||||||
|
</div>
|
||||||
|
<div class="clearfix"></div>
|
||||||
|
</div>
|
||||||
|
<!--css div popup end-->
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
|
||||||
@ -4877,11 +5027,11 @@ FileNotFoundError: [Errno 2] No such file or directory: '/home/ozzie/Develop
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
<tr id="su" class="passClass">
|
<tr id="su" class="failClass">
|
||||||
<td>TestUploadEPubs</td>
|
<td>TestUploadEPubs</td>
|
||||||
<td class="text-center">6</td>
|
<td class="text-center">6</td>
|
||||||
<td class="text-center">6</td>
|
<td class="text-center">5</td>
|
||||||
<td class="text-center">0</td>
|
<td class="text-center">1</td>
|
||||||
<td class="text-center">0</td>
|
<td class="text-center">0</td>
|
||||||
<td class="text-center">0</td>
|
<td class="text-center">0</td>
|
||||||
<td class="text-center">
|
<td class="text-center">
|
||||||
@ -4936,11 +5086,33 @@ FileNotFoundError: [Errno 2] No such file or directory: '/home/ozzie/Develop
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
<tr id='pt54.6' class='hiddenRow bg-success'>
|
<tr id="ft54.6" class="none bg-danger">
|
||||||
<td>
|
<td>
|
||||||
<div class='testcase'>TestUploadEPubs - test_upload_epub_lang</div>
|
<div class='testcase'>TestUploadEPubs - test_upload_epub_lang</div>
|
||||||
</td>
|
</td>
|
||||||
<td colspan='6' align='center'>PASS</td>
|
<td colspan='6'>
|
||||||
|
<div class="text-center">
|
||||||
|
<a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_ft54.6')">FAIL</a>
|
||||||
|
</div>
|
||||||
|
<!--css div popup start-->
|
||||||
|
<div id="div_ft54.6" class="popup_window test_output" style="display:block;">
|
||||||
|
<div class='close_button pull-right'>
|
||||||
|
<button type="button" class="close" aria-label="Close" onfocus="this.blur();"
|
||||||
|
onclick="document.getElementById('div_ft54.6').style.display='none'"><span
|
||||||
|
aria-hidden="true">×</span></button>
|
||||||
|
</div>
|
||||||
|
<div class="text-left pull-left">
|
||||||
|
<pre class="text-left">Traceback (most recent call last):
|
||||||
|
File "/home/ozzie/Development/calibre-web-test/test/test_upload_epubs.py", line 88, in test_upload_epub_lang
|
||||||
|
details = self.verify_upload(epub_file, check_warning=True)
|
||||||
|
File "/home/ozzie/Development/calibre-web-test/test/test_upload_epubs.py", line 79, in verify_upload
|
||||||
|
self.assertTrue(self.check_element_on_page((By.ID, "flash_warning")))
|
||||||
|
AssertionError: False is not true</pre>
|
||||||
|
</div>
|
||||||
|
<div class="clearfix"></div>
|
||||||
|
</div>
|
||||||
|
<!--css div popup end-->
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
|
||||||
@ -5841,10 +6013,10 @@ FileNotFoundError: [Errno 2] No such file or directory: '/home/ozzie/Develop
|
|||||||
|
|
||||||
<tr id='total_row' class="text-center bg-grey">
|
<tr id='total_row' class="text-center bg-grey">
|
||||||
<td>Total</td>
|
<td>Total</td>
|
||||||
<td>523</td>
|
<td>525</td>
|
||||||
<td>512</td>
|
<td>508</td>
|
||||||
<td>0</td>
|
<td>3</td>
|
||||||
<td>2</td>
|
<td>5</td>
|
||||||
<td>9</td>
|
<td>9</td>
|
||||||
<td> </td>
|
<td> </td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -6041,7 +6213,7 @@ FileNotFoundError: [Errno 2] No such file or directory: '/home/ozzie/Develop
|
|||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<th>Werkzeug</th>
|
<th>Werkzeug</th>
|
||||||
<td>3.1.0</td>
|
<td>3.1.1</td>
|
||||||
<td>Basic</td>
|
<td>Basic</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
@ -6389,7 +6561,7 @@ FileNotFoundError: [Errno 2] No such file or directory: '/home/ozzie/Develop
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
drawCircle(512, 0, 2, 9);
|
drawCircle(508, 3, 5, 9);
|
||||||
showCase(5);
|
showCase(5);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user