1
0
mirror of https://github.com/janeczku/calibre-web synced 2024-11-24 10:37:23 +00:00

Show dependencies in about section from automatic dependency check

Bugfix and refactored dependency check
Added output of googledrive dependencies as fallback option
This commit is contained in:
Ozzieisaacs 2021-11-06 20:17:00 +04:00
parent 25b09a532f
commit 27e8fbd248
5 changed files with 162 additions and 119 deletions

View File

@ -33,8 +33,9 @@ try:
except ImportError:
flaskwtf_version = _(u'not installed')
from . import db, calibre_db, converter, uploader, server, isoLanguages, constants
from . import db, calibre_db, converter, uploader, server, isoLanguages, constants, gdriveutils, dep_check
from .render_template import render_title_template
try:
from flask_login import __version__ as flask_loginVersion
except ImportError:
@ -67,38 +68,59 @@ from . import services
about = flask.Blueprint('about', __name__)
ret = dict()
req = dep_check.load_dependencys(False)
opt = dep_check.load_dependencys(True)
for i in (req + opt):
ret[i[1]] = i[0]
_VERSIONS = OrderedDict(
Platform = '{0[0]} {0[2]} {0[3]} {0[4]} {0[5]}'.format(platform.uname()),
Python=sys.version,
Calibre_Web=constants.STABLE_VERSION['version'] + ' - '
+ constants.NIGHTLY_VERSION[0].replace('%','%%') + ' - '
+ constants.NIGHTLY_VERSION[1].replace('%','%%'),
WebServer=server.VERSION,
Flask=flask.__version__,
Flask_Login=flask_loginVersion,
Flask_Principal=flask_principal.__version__,
Flask_WTF=flaskwtf_version,
Werkzeug=werkzeug.__version__,
Babel=babel.__version__,
Jinja2=jinja2.__version__,
Requests=requests.__version__,
SqlAlchemy=sqlalchemy.__version__,
pySqlite=sqlite3.version,
SQLite=sqlite3.sqlite_version,
iso639=isoLanguages.__version__,
pytz=pytz.__version__,
Unidecode=unidecode_version,
Scholarly=scholarly_version,
Flask_SimpleLDAP=u'installed' if bool(services.ldap) else None,
python_LDAP=services.ldapVersion if bool(services.ldapVersion) else None,
Goodreads=u'installed' if bool(services.goodreads_support) else None,
jsonschema=services.SyncToken.__version__ if bool(services.SyncToken) else None,
flask_dance=flask_danceVersion,
greenlet=greenlet_Version
)
_VERSIONS.update(uploader.get_versions())
if not ret:
_VERSIONS = OrderedDict(
Platform = '{0[0]} {0[2]} {0[3]} {0[4]} {0[5]}'.format(platform.uname()),
Python=sys.version,
Calibre_Web=constants.STABLE_VERSION['version'] + ' - '
+ constants.NIGHTLY_VERSION[0].replace('%','%%') + ' - '
+ constants.NIGHTLY_VERSION[1].replace('%','%%'),
WebServer=server.VERSION,
Flask=flask.__version__,
Flask_Login=flask_loginVersion,
Flask_Principal=flask_principal.__version__,
Flask_WTF=flaskwtf_version,
Werkzeug=werkzeug.__version__,
Babel=babel.__version__,
Jinja2=jinja2.__version__,
Requests=requests.__version__,
SqlAlchemy=sqlalchemy.__version__,
pySqlite=sqlite3.version,
SQLite=sqlite3.sqlite_version,
iso639=isoLanguages.__version__,
pytz=pytz.__version__,
Unidecode=unidecode_version,
Scholarly=scholarly_version,
Flask_SimpleLDAP=u'installed' if bool(services.ldap) else None,
python_LDAP=services.ldapVersion if bool(services.ldapVersion) else None,
Goodreads=u'installed' if bool(services.goodreads_support) else None,
jsonschema=services.SyncToken.__version__ if bool(services.SyncToken) else None,
flask_dance=flask_danceVersion,
greenlet=greenlet_Version
)
_VERSIONS.update(gdriveutils.get_versions())
_VERSIONS.update(uploader.get_versions(True))
else:
_VERSIONS = OrderedDict(
Platform = '{0[0]} {0[2]} {0[3]} {0[4]} {0[5]}'.format(platform.uname()),
Python = sys.version,
Calibre_Web = constants.STABLE_VERSION['version'] + ' - '
+ constants.NIGHTLY_VERSION[0].replace('%', '%%') + ' - '
+ constants.NIGHTLY_VERSION[1].replace('%', '%%'),
Werkzeug = werkzeug.__version__,
Jinja2=jinja2.__version__,
pySqlite = sqlite3.version,
SQLite = sqlite3.sqlite_version,
Unidecode=unidecode_version,
)
_VERSIONS.update(ret)
_VERSIONS.update(uploader.get_versions(False))
def collect_stats():
_VERSIONS['ebook converter'] = _(converter.get_calibre_version())
@ -115,5 +137,3 @@ def stats():
series = calibre_db.session.query(db.Series).count()
return render_title_template('stats.html', bookcounter=counter, authorcounter=authors, versions=collect_stats(),
categorycounter=categorys, seriecounter=series, title=_(u"Statistics"), page="stat")

View File

@ -18,66 +18,76 @@ if not importlib:
except ImportError as e:
pkgresources = False
def dependency_check(optional=False):
dep = list()
def load_dependencys(optional=False):
deps = list()
if importlib or pkgresources:
if optional:
req_path = os.path.join(BASE_DIR, "optional-requirements.txt")
else:
req_path = os.path.join(BASE_DIR, "requirements.txt")
if os.path.exists(req_path):
try:
with open(req_path, 'r') as f:
for line in f:
if not line.startswith('#') and not line == '\n' and not line.startswith('git'):
res = re.match(r'(.*?)([<=>\s]+)([\d\.]+),?\s?([<=>\s]+)?([\d\.]+)?', line.strip())
try:
if importlib:
dep_version = version(res.group(1))
else:
dep_version = pkg_resources.get_distribution(res.group(1)).version
except ImportNotFound:
if optional:
continue
else:
return [{'name':res.group(1),
'target': "available",
'found': "Not available"
}]
with open(req_path, 'r') as f:
for line in f:
if not line.startswith('#') and not line == '\n' and not line.startswith('git'):
res = re.match(r'(.*?)([<=>\s]+)([\d\.]+),?\s?([<=>\s]+)?([\d\.]+)?', line.strip())
try:
if importlib:
dep_version = version(res.group(1))
else:
dep_version = pkg_resources.get_distribution(res.group(1)).version
except ImportNotFound:
if optional:
continue
'''else:
return [{'name':res.group(1),
'target': "available",
'found': "Not available"
}]'''
deps.append([dep_version, res.group(1), res.group(2), res.group(3), res.group(4), res.group(5)])
return deps
if res.group(2).strip() == "==":
if dep_version.split('.') != res.group(3).split('.'):
dep.append({'name': res.group(1),
'found': dep_version,
"target": res.group(2) + res.group(3)})
continue
elif res.group(2).strip() == ">=":
if dep_version.split('.') < res.group(3).split('.'):
dep.append({'name': res.group(1),
'found': dep_version,
"target": res.group(2) + res.group(3)})
continue
elif res.group(2).strip() == ">":
if dep_version.split('.') <= res.group(3).split('.'):
dep.append({'name': res.group(1),
'found': dep_version,
"target": res.group(2) + res.group(3)})
continue
if res.group(4) and res.group(5):
if res.group(4).strip() == "<":
if dep_version.split('.') >= res.group(5).split('.'):
dep.append(
{'name': res.group(1),
'found': dep_version,
"target": res.group(4) + res.group(5)})
continue
elif res.group(2).strip() == "<=":
if dep_version.split('.') > res.group(5).split('.'):
dep.append(
{'name': res.group(1),
'found': dep_version,
"target": res.group(4) + res.group(5)})
continue
except Exception as e:
print(e)
return dep
def dependency_check(optional=False):
d = list()
deps = load_dependencys(optional)
for dep in deps:
dep_version_int = [int(x) for x in dep[0].split('.')]
low_check = [int(x) for x in dep[3].split('.')]
try:
high_check = [int(x) for x in dep[5].split('.')]
except AttributeError:
high_check = None
if dep[2].strip() == "==":
if dep_version_int != low_check:
d.append({'name': dep[1],
'found': dep[0],
"target": dep[2] + dep[3]})
continue
elif dep[2].strip() == ">=":
if dep_version_int < low_check:
d.append({'name': dep[1],
'found': dep[0],
"target": dep[2] + dep[3]})
continue
elif dep[2].strip() == ">":
if dep_version_int <= low_check:
d.append({'name': dep[1],
'found': dep[0],
"target": dep[2] + dep[3]})
continue
if dep[4] and dep[5]:
if dep[4].strip() == "<":
if dep_version_int >= high_check:
d.append(
{'name': dep[1],
'found': dep[0],
"target": dep[4] + dep[5]})
continue
elif dep[4].strip() == "<=":
if dep_version_int > high_check:
d.append(
{'name': dep[1],
'found': dep[0],
"target": dep[4] + dep[5]})
continue
return d

View File

@ -114,7 +114,7 @@ def search_objects_add(db_book_object, db_type, input_elements):
type_elements = c_elements.value
else:
type_elements = c_elements.name
if inp_element == type_elements:
if inp_element.lower() == type_elements.lower(): # Lowercase check
found = True
break
if not found:
@ -503,7 +503,7 @@ def edit_book_languages(languages, book, upload=False, invalid=None):
def edit_book_publisher(publishers, book):
changed = False
if publishers:
if publishers:
publisher = publishers.rstrip().strip()
if len(book.publishers) == 0 or (len(book.publishers) > 0 and publisher != book.publishers[0].name):
changed |= modify_database_object([publisher], book.publishers, db.Publishers, calibre_db.session,

View File

@ -35,6 +35,15 @@ except ImportError:
from sqlalchemy.exc import OperationalError, InvalidRequestError
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:
httplib2_version = "not installed"
try:
from apiclient import errors
from httplib2 import ServerNotFoundError
@ -659,3 +668,8 @@ def get_error_text(client_secrets=None):
return 'Callback url (redirect url) is missing in client_secrets.json'
if client_secrets:
client_secrets.update(filedata['web'])
def get_versions():
return {'six': six_version,
'httplib2': httplib2_version}

View File

@ -157,7 +157,7 @@ def parse_xmp(pdf_file):
def parse_xmp(pdf_file):
"""
Parse XMP Metadata and prepare for BookMeta object
Parse XMP Metadata and prepare for BookMeta object
"""
try:
xmp_info = pdf_file.getXmpMetadata()
@ -170,8 +170,8 @@ def parse_xmp(pdf_file):
xmp_author = xmp_info.dc_creator # list
except AttributeError:
xmp_author = ['Unknown']
if xmp_info.dc_title:
if xmp_info.dc_title:
xmp_title = xmp_info.dc_title['x-default']
else:
xmp_title = ''
@ -187,7 +187,7 @@ def parse_xmp(pdf_file):
languages.append(isoLanguages.get_lang3(i))
except AttributeError:
languages.append('')
xmp_tags = ', '.join(xmp_info.dc_subject)
xmp_publisher = ', '.join(xmp_info.dc_publisher)
@ -274,31 +274,30 @@ def pdf_preview(tmp_file_path, tmp_dir):
return None
def get_versions():
def get_versions(all=True):
ret = dict()
if not use_generic_pdf_cover:
IVersion = ImageVersion.MAGICK_VERSION
WVersion = ImageVersion.VERSION
ret['Image Magick'] = ImageVersion.MAGICK_VERSION
else:
IVersion = u'not installed'
WVersion = u'not installed'
if use_pdf_meta:
PVersion='v'+PyPdfVersion
else:
PVersion=u'not installed'
if lxmlversion:
XVersion = 'v'+'.'.join(map(str, lxmlversion))
else:
XVersion = u'not installed'
if comic.use_comic_meta:
ComicVersion = comic.comic_version or u'installed'
else:
ComicVersion = u'not installed'
return {'Image Magick': IVersion,
'PyPdf': PVersion,
'lxml':XVersion,
'Wand': WVersion,
# 'Pillow': PILVersion,
'Comic_API': ComicVersion}
ret['Image Magick'] = u'not installed'
if all:
if not use_generic_pdf_cover:
ret['Wand'] = ImageVersion.VERSION
else:
ret['Wand'] = u'not installed'
if use_pdf_meta:
ret['PyPdf'] = PyPdfVersion
else:
ret['PyPdf'] = u'not installed'
if lxmlversion:
ret['lxml'] = '.'.join(map(str, lxmlversion))
else:
ret['lxml'] = u'not installed'
if comic.use_comic_meta:
ret['Comic_API'] = comic.comic_version or u'installed'
else:
ret['Comic_API'] = u'not installed'
return ret
def upload(uploadfile, rarExcecutable):