Merge remote-tracking branch 'github_3/hotfix/epub-import'

Improved cover extraction from epub files
pull/1073/head
Ozzieisaacs 5 years ago
commit a371e40c66

@ -37,6 +37,7 @@ except ImportError:
from flask_login.__about__ import __version__ as flask_loginVersion from flask_login.__about__ import __version__ as flask_loginVersion
try: try:
import unidecode import unidecode
# _() necessary to make babel aware of string for translation
unidecode_version = _(u'installed') unidecode_version = _(u'installed')
except ImportError: except ImportError:
unidecode_version = _(u'not installed') unidecode_version = _(u'not installed')
@ -62,8 +63,8 @@ _VERSIONS = OrderedDict(
iso639=isoLanguages.__version__, iso639=isoLanguages.__version__,
pytz=pytz.__version__, pytz=pytz.__version__,
Unidecode = unidecode_version, Unidecode = unidecode_version,
Flask_SimpleLDAP = _(u'installed') if bool(services.ldap) else _(u'not installed'), Flask_SimpleLDAP = u'installed' if bool(services.ldap) else u'not installed',
Goodreads = _(u'installed') if bool(services.goodreads_support) else _(u'not installed'), Goodreads = u'installed' if bool(services.goodreads_support) else u'not installed',
) )
_VERSIONS.update(uploader.get_versions()) _VERSIONS.update(uploader.get_versions())

@ -19,6 +19,7 @@
from __future__ import division, print_function, unicode_literals from __future__ import division, print_function, unicode_literals
import os import os
import re import re
from flask_babel import gettext as _
from . import config, logger from . import config, logger
from .subproc_wrapper import process_wait from .subproc_wrapper import process_wait
@ -26,7 +27,8 @@ from .subproc_wrapper import process_wait
log = logger.create() log = logger.create()
_NOT_CONFIGURED = 'not configured' # _() necessary to make babel aware of string for translation
_NOT_CONFIGURED = _('not configured')
_NOT_INSTALLED = 'not installed' _NOT_INSTALLED = 'not installed'
_EXECUTION_ERROR = 'Execution permissions missing' _EXECUTION_ERROR = 'Execution permissions missing'

@ -64,7 +64,12 @@ def get_epub_info(tmp_file_path, original_file_name, original_file_extension):
for s in ['title', 'description', 'creator', 'language', 'subject']: for s in ['title', 'description', 'creator', 'language', 'subject']:
tmp = p.xpath('dc:%s/text()' % s, namespaces=ns) tmp = p.xpath('dc:%s/text()' % s, namespaces=ns)
if len(tmp) > 0: if len(tmp) > 0:
epub_metadata[s] = p.xpath('dc:%s/text()' % s, namespaces=ns)[0] if s == 'creator':
epub_metadata[s] = ' & '.join(p.xpath('dc:%s/text()' % s, namespaces=ns))
elif s == 'subject':
epub_metadata[s] = ', '.join(p.xpath('dc:%s/text()' % s, namespaces=ns))
else:
epub_metadata[s] = p.xpath('dc:%s/text()' % s, namespaces=ns)[0]
else: else:
epub_metadata[s] = "Unknown" epub_metadata[s] = "Unknown"
@ -109,18 +114,20 @@ def get_epub_info(tmp_file_path, original_file_name, original_file_extension):
meta_cover = tree.xpath("/pkg:package/pkg:metadata/pkg:meta[@name='cover']/@content", namespaces=ns) meta_cover = tree.xpath("/pkg:package/pkg:metadata/pkg:meta[@name='cover']/@content", namespaces=ns)
if len(meta_cover) > 0: if len(meta_cover) > 0:
coversection = tree.xpath("/pkg:package/pkg:manifest/pkg:item[@id='"+meta_cover[0]+"']/@href", namespaces=ns) coversection = tree.xpath("/pkg:package/pkg:manifest/pkg:item[@id='"+meta_cover[0]+"']/@href", namespaces=ns)
if len(coversection) > 0: else:
filetype = coversection[0].rsplit('.', 1)[-1] coversection = tree.xpath("/pkg:package/pkg:guide/pkg:reference/@href", namespaces=ns)
if filetype == "xhtml" or filetype == "html": # if cover is (x)html format if len(coversection) > 0:
markup = epubZip.read(os.path.join(coverpath, coversection[0])) filetype = coversection[0].rsplit('.', 1)[-1]
markupTree = etree.fromstring(markup) if filetype == "xhtml" or filetype == "html": # if cover is (x)html format
# no matter xhtml or html with no namespace markup = epubZip.read(os.path.join(coverpath, coversection[0]))
imgsrc = markupTree.xpath("//*[local-name() = 'img']/@src") markupTree = etree.fromstring(markup)
# imgsrc maybe startwith "../"" so fullpath join then relpath to cwd # no matter xhtml or html with no namespace
filename = os.path.relpath(os.path.join(os.path.dirname(os.path.join(coverpath, coversection[0])), imgsrc[0])) imgsrc = markupTree.xpath("//*[local-name() = 'img']/@src")
coverfile = extractCover(epubZip, filename, "", tmp_file_path) # imgsrc maybe startwith "../"" so fullpath join then relpath to cwd
else: filename = os.path.relpath(os.path.join(os.path.dirname(os.path.join(coverpath, coversection[0])), imgsrc[0]))
coverfile = extractCover(epubZip, coversection[0], coverpath, tmp_file_path) coverfile = extractCover(epubZip, filename, "", tmp_file_path)
else:
coverfile = extractCover(epubZip, coversection[0], coverpath, tmp_file_path)
if not epub_metadata['title']: if not epub_metadata['title']:
title = original_file_name title = original_file_name

@ -1,9 +1,9 @@
{% extends "layout.html" %} {% extends "layout.html" %}
{% block body %} {% block body %}
<h3>{{_('About')}}</h3> <h3>{{_('About')}}</h3>
<p>{{instance}} powered by <p>{{instance}} powered by
<a href="https://github.com/janeczku/calibre-web" title="Calibre-Web">Calibre-Web</a>. <a href="https://github.com/janeczku/calibre-web" title="Calibre-Web">Calibre-Web</a>.
</p> </p>
<h3>{{_('Calibre library statistics')}}</h3> <h3>{{_('Calibre library statistics')}}</h3>
<table id="stats" class="table"> <table id="stats" class="table">
<tbody> <tbody>
@ -37,7 +37,7 @@
{% for library,version in versions.items() %} {% for library,version in versions.items() %}
<tr> <tr>
<th>{{library}}</th> <th>{{library}}</th>
<td>{{version}}</td> <td>{{_(version)}}</td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>

@ -5,18 +5,19 @@
# FIRST AUTHOR OzzieIsaacs, 2016. # FIRST AUTHOR OzzieIsaacs, 2016.
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Calibre-Web\n" "Project-Id-Version: Calibre-Web\n"
"Report-Msgid-Bugs-To: https://github.com/janeczku/Calibre-Web\n" "Report-Msgid-Bugs-To: https://github.com/janeczku/Calibre-Web\n"
"POT-Creation-Date: 2019-09-17 18:24+0200\n" "POT-Creation-Date: 2019-09-17 18:24+0200\n"
"PO-Revision-Date: 2019-08-06 18:36+0200\n" "PO-Revision-Date: 2019-10-20 15:14+0200\n"
"Last-Translator: Ozzie Isaacs\n" "Last-Translator: Ozzie Isaacs\n"
"Language: de\n" "Language: de\n"
"Language-Team: \n" "Language-Team: \n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n" "Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.7.0\n" "Generated-By: Babel 2.7.0\n"
"X-Generator: Poedit 2.2.4\n"
#: cps/about.py:40 cps/about.py:65 cps/about.py:66 cps/uploader.py:228 #: cps/about.py:40 cps/about.py:65 cps/about.py:66 cps/uploader.py:228
msgid "installed" msgid "installed"
@ -289,7 +290,7 @@ msgstr "Callback Domain ist nicht verifiziert, bitte Domain in der Google Develo
#: cps/helper.py:79 #: cps/helper.py:79
#, python-format #, python-format
msgid "%(format)s format not found for book id: %(book)d" msgid "%(format)s format not found for book id: %(book)d"
msgstr "%(format)s Format für Buch-ID %(book)d nicht gefunden " msgstr "%(format)s Format für Buch-ID %(book)d nicht gefunden"
#: cps/helper.py:91 #: cps/helper.py:91
#, python-format #, python-format
@ -880,7 +881,7 @@ msgstr "Lese ein Buch"
#: cps/web.py:1332 #: cps/web.py:1332
msgid "Error opening eBook. File does not exist or file is not accessible." msgid "Error opening eBook. File does not exist or file is not accessible."
msgstr "Fehler beim Öffnen des eBooks. Datei existiert nicht oder ist nicht zugänglich. " msgstr "Fehler beim Öffnen des eBooks. Datei existiert nicht oder ist nicht zugänglich."
#: cps/worker.py:328 #: cps/worker.py:328
#, python-format #, python-format
@ -2178,6 +2179,9 @@ msgstr "Benutzer löschen"
msgid "Recent Downloads" msgid "Recent Downloads"
msgstr "Letzte Downloads" msgstr "Letzte Downloads"
msgid "not configured"
msgstr "Nicht konfiguriert"
#~ msgid "Show sorted books" #~ msgid "Show sorted books"
#~ msgstr "Zeige Bücher sortiert" #~ msgstr "Zeige Bücher sortiert"
@ -2274,9 +2278,6 @@ msgstr "Letzte Downloads"
#~ msgid "Excecution permissions missing" #~ msgid "Excecution permissions missing"
#~ msgstr "Ausführungsberechtigung nicht vorhanden" #~ msgstr "Ausführungsberechtigung nicht vorhanden"
#~ msgid "not configured"
#~ msgstr "Nicht konfiguriert"
#~ msgid "Error excecuting UnRar" #~ msgid "Error excecuting UnRar"
#~ msgstr "Fehler bei der Ausführung von UnRar" #~ msgstr "Fehler bei der Ausführung von UnRar"
@ -2307,12 +2308,5 @@ msgstr "Letzte Downloads"
#~ msgid "Google OAuth Client Secret" #~ msgid "Google OAuth Client Secret"
#~ msgstr "Google OAuth Client-Secret" #~ msgstr "Google OAuth Client-Secret"
#~ msgid "Installed"
#~ msgstr ""
#~ msgid "Not installed"
#~ msgstr ""
#~ msgid "Use" #~ msgid "Use"
#~ msgstr "Benutzen" #~ msgstr "Benutzen"

@ -210,24 +210,24 @@ def get_versions():
IVersion = ImageVersion.MAGICK_VERSION IVersion = ImageVersion.MAGICK_VERSION
WVersion = ImageVersion.VERSION WVersion = ImageVersion.VERSION
else: else:
IVersion = _(u'not installed') IVersion = u'not installed'
WVersion = _(u'not installed') WVersion = u'not installed'
if use_pdf_meta: if use_pdf_meta:
PVersion='v'+PyPdfVersion PVersion='v'+PyPdfVersion
else: else:
PVersion=_(u'not installed') PVersion=u'not installed'
if lxmlversion: if lxmlversion:
XVersion = 'v'+'.'.join(map(str, lxmlversion)) XVersion = 'v'+'.'.join(map(str, lxmlversion))
else: else:
XVersion = _(u'not installed') XVersion = u'not installed'
if use_PIL: if use_PIL:
PILVersion = 'v' + PILversion PILVersion = 'v' + PILversion
else: else:
PILVersion = _(u'not installed') PILVersion = u'not installed'
if comic.use_comic_meta: if comic.use_comic_meta:
ComicVersion = _(u'installed') ComicVersion = u'installed'
else: else:
ComicVersion = _(u'not installed') ComicVersion = u'not installed'
return {'Image Magick': IVersion, return {'Image Magick': IVersion,
'PyPdf': PVersion, 'PyPdf': PVersion,
'lxml':XVersion, 'lxml':XVersion,

Loading…
Cancel
Save