Remove Pillow as dependency

This commit is contained in:
Ozzieisaacs 2020-12-09 14:18:39 +01:00
parent d957b2d20f
commit 352b4a0b73
4 changed files with 60 additions and 70 deletions

View File

@ -18,21 +18,21 @@
from __future__ import division, print_function, unicode_literals
import os
import io
from . import logger, isoLanguages
from .constants import BookMeta
try:
from PIL import Image as PILImage
use_PIL = True
except ImportError as e:
use_PIL = False
log = logger.create()
try:
from wand.image import Image
use_IM = True
except (ImportError, RuntimeError) as e:
use_IM = False
try:
from comicapi.comicarchive import ComicArchive, MetaDataStyle
use_comic_meta = True
@ -52,20 +52,26 @@ except (ImportError, LookupError) as e:
use_rarfile = False
use_comic_meta = False
COVER_EXTENSIONS = ['.jpg', '.jpeg', '.png', '.webp', '.bmp']
def _cover_processing(tmp_file_name, img, extension):
if use_PIL:
tmp_cover_name = os.path.join(os.path.dirname(tmp_file_name), 'cover.jpg')
if use_IM:
# convert to jpg because calibre only supports jpg
if extension in ('.png', '.webp'):
imgc = PILImage.open(io.BytesIO(img))
im = imgc.convert('RGB')
tmp_bytesio = io.BytesIO()
im.save(tmp_bytesio, format='JPEG')
img = tmp_bytesio.getvalue()
cover_ext = COVER_EXTENSIONS
cover_ext.remove('.jpeg')
cover_ext.remove('.jpg')
if extension in cover_ext:
with Image(filename=tmp_file_name) as imgc:
imgc.format = 'jpeg'
imgc.transform_colorspace('rgb')
imgc.save(tmp_cover_name)
return tmp_cover_name
if not img:
return None
tmp_cover_name = os.path.join(os.path.dirname(tmp_file_name), 'cover.jpg')
with open(tmp_cover_name, 'wb') as f:
f.write(img)
return tmp_cover_name
@ -80,7 +86,7 @@ def _extractCover(tmp_file_name, original_file_extension, rarExecutable):
ext = os.path.splitext(name)
if len(ext) > 1:
extension = ext[1].lower()
if extension in ('.jpg', '.jpeg', '.png', '.webp'):
if extension in COVER_EXTENSIONS:
cover_data = archive.getPage(index)
break
else:
@ -90,7 +96,7 @@ def _extractCover(tmp_file_name, original_file_extension, rarExecutable):
ext = os.path.splitext(name)
if len(ext) > 1:
extension = ext[1].lower()
if extension in ('.jpg', '.jpeg', '.png', '.webp'):
if extension in COVER_EXTENSIONS:
cover_data = cf.read(name)
break
elif original_file_extension.upper() == '.CBT':
@ -99,7 +105,7 @@ def _extractCover(tmp_file_name, original_file_extension, rarExecutable):
ext = os.path.splitext(name)
if len(ext) > 1:
extension = ext[1].lower()
if extension in ('.jpg', '.jpeg', '.png', '.webp'):
if extension in COVER_EXTENSIONS:
cover_data = cf.extractfile(name).read()
break
elif original_file_extension.upper() == '.CBR' and use_rarfile:
@ -110,7 +116,7 @@ def _extractCover(tmp_file_name, original_file_extension, rarExecutable):
ext = os.path.splitext(name)
if len(ext) > 1:
extension = ext[1].lower()
if extension in ('.jpg', '.jpeg', '.png', '.webp'):
if extension in COVER_EXTENSIONS:
cover_data = cf.read(name)
break
except Exception as e:

View File

@ -50,13 +50,6 @@ try:
except ImportError:
use_unidecode = False
try:
from PIL import Image as PILImage
from PIL import UnidentifiedImageError
use_PIL = True
except ImportError:
use_PIL = False
from . import calibre_db
from .tasks.convert import TaskConvert
from . import logger, config, get_locale, db, ub
@ -66,9 +59,15 @@ from .subproc_wrapper import process_wait
from .services.worker import WorkerThread, STAT_WAITING, STAT_FAIL, STAT_STARTED, STAT_FINISH_SUCCESS
from .tasks.mail import TaskEmail
log = logger.create()
try:
from wand.image import Image
use_IM = True
except (ImportError, RuntimeError) as e:
log.debug('Cannot import Image, generating covers from non jpg files will not work: %s', e)
use_IM = False
# Convert existing book entry to new format
def convert_book_format(book_id, calibrepath, old_book_format, new_book_format, user_id, kindle_mail=None):
@ -109,21 +108,21 @@ def convert_book_format(book_id, calibrepath, old_book_format, new_book_format,
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"),
_(u'This e-mail has been sent via Calibre-Web.')))
_(u'This e-mail has been sent via Calibre-Web.')))
return
# Send registration email or password reset email, depending on parameter resend (False means welcome email)
def send_registration_mail(e_mail, user_name, default_password, resend=False):
text = "Hello %s!\r\n" % user_name
txt = "Hello %s!\r\n" % user_name
if not resend:
text += "Your new account at Calibre-Web has been created. Thanks for joining us!\r\n"
text += "Please log in to your account using the following informations:\r\n"
text += "User name: %s\r\n" % user_name
text += "Password: %s\r\n" % default_password
text += "Don't forget to change your password after first login.\r\n"
text += "Sincerely\r\n\r\n"
text += "Your Calibre-Web team"
txt += "Your new account at Calibre-Web has been created. Thanks for joining us!\r\n"
txt += "Please log in to your account using the following informations:\r\n"
txt += "User name: %s\r\n" % user_name
txt += "Password: %s\r\n" % default_password
txt += "Don't forget to change your password after first login.\r\n"
txt += "Sincerely\r\n\r\n"
txt += "Your Calibre-Web team"
WorkerThread.add(None, TaskEmail(
subject=_(u'Get Started with Calibre-Web'),
filepath=None,
@ -131,7 +130,7 @@ def send_registration_mail(e_mail, user_name, default_password, resend=False):
settings=config.get_mail_settings(),
recipient=e_mail,
taskMessage=_(u"Registration e-mail for user: %(name)s", name=user_name),
text=text
text=txt
))
return
@ -177,7 +176,7 @@ def check_send_to_kindle(entry):
'convert': 0,
'text': _('Send %(format)s to Kindle', format='Pdf')})
if config.config_converterpath:
if 'EPUB' in formats and not 'MOBI' in formats:
if 'EPUB' in formats and 'MOBI' not in formats:
bookformats.append({'format': 'Mobi',
'convert':1,
'text': _('Convert %(orig)s to %(format)s and send to Kindle',
@ -586,16 +585,15 @@ def save_cover_from_url(url, book_path):
requests.exceptions.Timeout) as ex:
log.info(u'Cover Download Error %s', ex)
return False, _("Error Downloading Cover")
except UnidentifiedImageError as ex:
log.info(u'File Format Error %s', ex)
return False, _("Cover Format Error")
# except UnidentifiedImageError as ex:
# log.info(u'File Format Error %s', ex)
# return False, _("Cover Format Error")
def save_cover_from_filestorage(filepath, saved_filename, img):
if hasattr(img, '_content'):
f = open(os.path.join(filepath, saved_filename), "wb")
f.write(img._content)
f.close()
if hasattr(img,"metadata"):
img.save(filename=os.path.join(filepath, saved_filename))
img.close()
else:
# check if file path exists, otherwise create it, copy file to calibre path and delete temp file
if not os.path.exists(filepath):
@ -616,20 +614,19 @@ def save_cover_from_filestorage(filepath, saved_filename, img):
def save_cover(img, book_path):
content_type = img.headers.get('content-type')
if use_PIL:
if content_type not in ('image/jpeg', 'image/png', 'image/webp'):
log.error("Only jpg/jpeg/png/webp files are supported as coverfile")
return False, _("Only jpg/jpeg/png/webp files are supported as coverfile")
if use_IM:
if content_type not in ('image/jpeg', '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 in ('image/png', 'image/webp'):
if content_type != 'image/jpg':
if hasattr(img, 'stream'):
imgc = PILImage.open(img.stream)
imgc = Image(blob=img.stream)
else:
imgc = PILImage.open(io.BytesIO(img.content))
im = imgc.convert('RGB')
tmp_bytesio = io.BytesIO()
im.save(tmp_bytesio, format='JPEG')
img._content = tmp_bytesio.getvalue()
imgc = Image(blob=io.BytesIO(img.content))
imgc.format = 'jpeg'
imgc.transform_colorspace("rgb")
img = imgc
else:
if content_type not in 'image/jpeg':
log.error("Only jpg/jpeg files are supported as coverfile")

View File

@ -66,14 +66,6 @@ except ImportError as e:
log.debug('Cannot import fb2, extracting fb2 metadata will not work: %s', e)
use_fb2_meta = False
try:
from PIL import Image as PILImage
from PIL import __version__ as PILversion
use_PIL = True
except ImportError as e:
log.debug('Cannot import Pillow, using png and webp images as cover will not work: %s', e)
use_PIL = False
def process(tmp_file_path, original_file_name, original_file_extension, rarExecutable):
meta = None
@ -179,10 +171,6 @@ def get_versions():
XVersion = 'v'+'.'.join(map(str, lxmlversion))
else:
XVersion = u'not installed'
if use_PIL:
PILVersion = 'v' + PILversion
else:
PILVersion = u'not installed'
if comic.use_comic_meta:
ComicVersion = comic.comic_version or u'installed'
else:
@ -191,7 +179,7 @@ def get_versions():
'PyPdf': PVersion,
'lxml':XVersion,
'Wand': WVersion,
'Pillow': PILVersion,
# 'Pillow': PILVersion,
'Comic_API': ComicVersion}

View File

@ -26,7 +26,6 @@ SQLAlchemy-Utils>=0.33.5,<0.37.0
# extracting metadata
lxml>=3.8.0,<4.6.0
Pillow>=4.0.0,<7.2.0
rarfile>=2.7
# other