Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
D
douban-api-proxy
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
captainwong
douban-api-proxy
Commits
352b4a0b
Commit
352b4a0b
authored
Dec 09, 2020
by
Ozzieisaacs
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Remove Pillow as dependency
parent
d957b2d2
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
60 additions
and
70 deletions
+60
-70
comic.py
cps/comic.py
+25
-19
helper.py
cps/helper.py
+34
-37
uploader.py
cps/uploader.py
+1
-13
optional-requirements.txt
optional-requirements.txt
+0
-1
No files found.
cps/comic.py
View file @
352b4a0b
...
@@ -18,21 +18,21 @@
...
@@ -18,21 +18,21 @@
from
__future__
import
division
,
print_function
,
unicode_literals
from
__future__
import
division
,
print_function
,
unicode_literals
import
os
import
os
import
io
from
.
import
logger
,
isoLanguages
from
.
import
logger
,
isoLanguages
from
.constants
import
BookMeta
from
.constants
import
BookMeta
try
:
from
PIL
import
Image
as
PILImage
use_PIL
=
True
except
ImportError
as
e
:
use_PIL
=
False
log
=
logger
.
create
()
log
=
logger
.
create
()
try
:
from
wand.image
import
Image
use_IM
=
True
except
(
ImportError
,
RuntimeError
)
as
e
:
use_IM
=
False
try
:
try
:
from
comicapi.comicarchive
import
ComicArchive
,
MetaDataStyle
from
comicapi.comicarchive
import
ComicArchive
,
MetaDataStyle
use_comic_meta
=
True
use_comic_meta
=
True
...
@@ -52,20 +52,26 @@ except (ImportError, LookupError) as e:
...
@@ -52,20 +52,26 @@ except (ImportError, LookupError) as e:
use_rarfile
=
False
use_rarfile
=
False
use_comic_meta
=
False
use_comic_meta
=
False
COVER_EXTENSIONS
=
[
'.jpg'
,
'.jpeg'
,
'.png'
,
'.webp'
,
'.bmp'
]
def
_cover_processing
(
tmp_file_name
,
img
,
extension
):
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
# convert to jpg because calibre only supports jpg
if
extension
in
(
'.png'
,
'.webp'
):
cover_ext
=
COVER_EXTENSIONS
imgc
=
PILImage
.
open
(
io
.
BytesIO
(
img
))
cover_ext
.
remove
(
'.jpeg'
)
im
=
imgc
.
convert
(
'RGB'
)
cover_ext
.
remove
(
'.jpg'
)
tmp_bytesio
=
io
.
BytesIO
()
if
extension
in
cover_ext
:
im
.
save
(
tmp_bytesio
,
format
=
'JPEG'
)
with
Image
(
filename
=
tmp_file_name
)
as
imgc
:
img
=
tmp_bytesio
.
getvalue
()
imgc
.
format
=
'jpeg'
imgc
.
transform_colorspace
(
'rgb'
)
imgc
.
save
(
tmp_cover_name
)
return
tmp_cover_name
if
not
img
:
if
not
img
:
return
None
return
None
tmp_cover_name
=
os
.
path
.
join
(
os
.
path
.
dirname
(
tmp_file_name
),
'cover.jpg'
)
with
open
(
tmp_cover_name
,
'wb'
)
as
f
:
with
open
(
tmp_cover_name
,
'wb'
)
as
f
:
f
.
write
(
img
)
f
.
write
(
img
)
return
tmp_cover_name
return
tmp_cover_name
...
@@ -80,7 +86,7 @@ def _extractCover(tmp_file_name, original_file_extension, rarExecutable):
...
@@ -80,7 +86,7 @@ def _extractCover(tmp_file_name, original_file_extension, rarExecutable):
ext
=
os
.
path
.
splitext
(
name
)
ext
=
os
.
path
.
splitext
(
name
)
if
len
(
ext
)
>
1
:
if
len
(
ext
)
>
1
:
extension
=
ext
[
1
]
.
lower
()
extension
=
ext
[
1
]
.
lower
()
if
extension
in
(
'.jpg'
,
'.jpeg'
,
'.png'
,
'.webp'
)
:
if
extension
in
COVER_EXTENSIONS
:
cover_data
=
archive
.
getPage
(
index
)
cover_data
=
archive
.
getPage
(
index
)
break
break
else
:
else
:
...
@@ -90,7 +96,7 @@ def _extractCover(tmp_file_name, original_file_extension, rarExecutable):
...
@@ -90,7 +96,7 @@ def _extractCover(tmp_file_name, original_file_extension, rarExecutable):
ext
=
os
.
path
.
splitext
(
name
)
ext
=
os
.
path
.
splitext
(
name
)
if
len
(
ext
)
>
1
:
if
len
(
ext
)
>
1
:
extension
=
ext
[
1
]
.
lower
()
extension
=
ext
[
1
]
.
lower
()
if
extension
in
(
'.jpg'
,
'.jpeg'
,
'.png'
,
'.webp'
)
:
if
extension
in
COVER_EXTENSIONS
:
cover_data
=
cf
.
read
(
name
)
cover_data
=
cf
.
read
(
name
)
break
break
elif
original_file_extension
.
upper
()
==
'.CBT'
:
elif
original_file_extension
.
upper
()
==
'.CBT'
:
...
@@ -99,7 +105,7 @@ def _extractCover(tmp_file_name, original_file_extension, rarExecutable):
...
@@ -99,7 +105,7 @@ def _extractCover(tmp_file_name, original_file_extension, rarExecutable):
ext
=
os
.
path
.
splitext
(
name
)
ext
=
os
.
path
.
splitext
(
name
)
if
len
(
ext
)
>
1
:
if
len
(
ext
)
>
1
:
extension
=
ext
[
1
]
.
lower
()
extension
=
ext
[
1
]
.
lower
()
if
extension
in
(
'.jpg'
,
'.jpeg'
,
'.png'
,
'.webp'
)
:
if
extension
in
COVER_EXTENSIONS
:
cover_data
=
cf
.
extractfile
(
name
)
.
read
()
cover_data
=
cf
.
extractfile
(
name
)
.
read
()
break
break
elif
original_file_extension
.
upper
()
==
'.CBR'
and
use_rarfile
:
elif
original_file_extension
.
upper
()
==
'.CBR'
and
use_rarfile
:
...
@@ -110,7 +116,7 @@ def _extractCover(tmp_file_name, original_file_extension, rarExecutable):
...
@@ -110,7 +116,7 @@ def _extractCover(tmp_file_name, original_file_extension, rarExecutable):
ext
=
os
.
path
.
splitext
(
name
)
ext
=
os
.
path
.
splitext
(
name
)
if
len
(
ext
)
>
1
:
if
len
(
ext
)
>
1
:
extension
=
ext
[
1
]
.
lower
()
extension
=
ext
[
1
]
.
lower
()
if
extension
in
(
'.jpg'
,
'.jpeg'
,
'.png'
,
'.webp'
)
:
if
extension
in
COVER_EXTENSIONS
:
cover_data
=
cf
.
read
(
name
)
cover_data
=
cf
.
read
(
name
)
break
break
except
Exception
as
e
:
except
Exception
as
e
:
...
...
cps/helper.py
View file @
352b4a0b
...
@@ -50,13 +50,6 @@ try:
...
@@ -50,13 +50,6 @@ try:
except
ImportError
:
except
ImportError
:
use_unidecode
=
False
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
.
import
calibre_db
from
.tasks.convert
import
TaskConvert
from
.tasks.convert
import
TaskConvert
from
.
import
logger
,
config
,
get_locale
,
db
,
ub
from
.
import
logger
,
config
,
get_locale
,
db
,
ub
...
@@ -66,9 +59,15 @@ from .subproc_wrapper import process_wait
...
@@ -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
.services.worker
import
WorkerThread
,
STAT_WAITING
,
STAT_FAIL
,
STAT_STARTED
,
STAT_FINISH_SUCCESS
from
.tasks.mail
import
TaskEmail
from
.tasks.mail
import
TaskEmail
log
=
logger
.
create
()
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
# 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
):
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,
...
@@ -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
):
def
send_test_mail
(
kindle_mail
,
user_name
):
WorkerThread
.
add
(
user_name
,
TaskEmail
(
_
(
u'Calibre-Web test e-mail'
),
None
,
None
,
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
,
_
(
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
return
# Send registration email or password reset email, depending on parameter resend (False means welcome email)
# 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
):
def
send_registration_mail
(
e_mail
,
user_name
,
default_password
,
resend
=
False
):
t
e
xt
=
"Hello
%
s!
\r\n
"
%
user_name
txt
=
"Hello
%
s!
\r\n
"
%
user_name
if
not
resend
:
if
not
resend
:
t
e
xt
+=
"Your new account at Calibre-Web has been created. Thanks for joining us!
\r\n
"
txt
+=
"Your new account at Calibre-Web has been created. Thanks for joining us!
\r\n
"
t
e
xt
+=
"Please log in to your account using the following informations:
\r\n
"
txt
+=
"Please log in to your account using the following informations:
\r\n
"
t
e
xt
+=
"User name:
%
s
\r\n
"
%
user_name
txt
+=
"User name:
%
s
\r\n
"
%
user_name
t
e
xt
+=
"Password:
%
s
\r\n
"
%
default_password
txt
+=
"Password:
%
s
\r\n
"
%
default_password
t
e
xt
+=
"Don't forget to change your password after first login.
\r\n
"
txt
+=
"Don't forget to change your password after first login.
\r\n
"
t
e
xt
+=
"Sincerely
\r\n\r\n
"
txt
+=
"Sincerely
\r\n\r\n
"
t
e
xt
+=
"Your Calibre-Web team"
txt
+=
"Your Calibre-Web team"
WorkerThread
.
add
(
None
,
TaskEmail
(
WorkerThread
.
add
(
None
,
TaskEmail
(
subject
=
_
(
u'Get Started with Calibre-Web'
),
subject
=
_
(
u'Get Started with Calibre-Web'
),
filepath
=
None
,
filepath
=
None
,
...
@@ -131,7 +130,7 @@ def send_registration_mail(e_mail, user_name, default_password, resend=False):
...
@@ -131,7 +130,7 @@ def send_registration_mail(e_mail, user_name, default_password, resend=False):
settings
=
config
.
get_mail_settings
(),
settings
=
config
.
get_mail_settings
(),
recipient
=
e_mail
,
recipient
=
e_mail
,
taskMessage
=
_
(
u"Registration e-mail for user:
%(name)
s"
,
name
=
user_name
),
taskMessage
=
_
(
u"Registration e-mail for user:
%(name)
s"
,
name
=
user_name
),
text
=
t
e
xt
text
=
txt
))
))
return
return
...
@@ -177,7 +176,7 @@ def check_send_to_kindle(entry):
...
@@ -177,7 +176,7 @@ def check_send_to_kindle(entry):
'convert'
:
0
,
'convert'
:
0
,
'text'
:
_
(
'Send
%(format)
s to Kindle'
,
format
=
'Pdf'
)})
'text'
:
_
(
'Send
%(format)
s to Kindle'
,
format
=
'Pdf'
)})
if
config
.
config_converterpath
:
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'
,
bookformats
.
append
({
'format'
:
'Mobi'
,
'convert'
:
1
,
'convert'
:
1
,
'text'
:
_
(
'Convert
%(orig)
s to
%(format)
s and send to Kindle'
,
'text'
:
_
(
'Convert
%(orig)
s to
%(format)
s and send to Kindle'
,
...
@@ -586,16 +585,15 @@ def save_cover_from_url(url, book_path):
...
@@ -586,16 +585,15 @@ def save_cover_from_url(url, book_path):
requests
.
exceptions
.
Timeout
)
as
ex
:
requests
.
exceptions
.
Timeout
)
as
ex
:
log
.
info
(
u'Cover Download Error
%
s'
,
ex
)
log
.
info
(
u'Cover Download Error
%
s'
,
ex
)
return
False
,
_
(
"Error Downloading Cover"
)
return
False
,
_
(
"Error Downloading Cover"
)
except
UnidentifiedImageError
as
ex
:
#
except UnidentifiedImageError as ex:
log
.
info
(
u'File Format Error
%
s'
,
ex
)
#
log.info(u'File Format Error %s', ex)
return
False
,
_
(
"Cover Format Error"
)
#
return False, _("Cover Format Error")
def
save_cover_from_filestorage
(
filepath
,
saved_filename
,
img
):
def
save_cover_from_filestorage
(
filepath
,
saved_filename
,
img
):
if
hasattr
(
img
,
'_content'
):
if
hasattr
(
img
,
"metadata"
):
f
=
open
(
os
.
path
.
join
(
filepath
,
saved_filename
),
"wb"
)
img
.
save
(
filename
=
os
.
path
.
join
(
filepath
,
saved_filename
))
f
.
write
(
img
.
_content
)
img
.
close
()
f
.
close
()
else
:
else
:
# check if file path exists, otherwise create it, copy file to calibre path and delete temp file
# check if file path exists, otherwise create it, copy file to calibre path and delete temp file
if
not
os
.
path
.
exists
(
filepath
):
if
not
os
.
path
.
exists
(
filepath
):
...
@@ -616,20 +614,19 @@ def save_cover_from_filestorage(filepath, saved_filename, img):
...
@@ -616,20 +614,19 @@ def save_cover_from_filestorage(filepath, saved_filename, img):
def
save_cover
(
img
,
book_path
):
def
save_cover
(
img
,
book_path
):
content_type
=
img
.
headers
.
get
(
'content-type'
)
content_type
=
img
.
headers
.
get
(
'content-type'
)
if
use_
PIL
:
if
use_
IM
:
if
content_type
not
in
(
'image/jpeg'
,
'image/png'
,
'image/webp'
):
if
content_type
not
in
(
'image/jpeg'
,
'image/png'
,
'image/webp'
,
'image/bmp'
):
log
.
error
(
"Only jpg/jpeg/png/webp files are supported as coverfile"
)
log
.
error
(
"Only jpg/jpeg/png/webp
/bmp
files are supported as coverfile"
)
return
False
,
_
(
"Only jpg/jpeg/png/webp 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
# 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'
):
if
hasattr
(
img
,
'stream'
):
imgc
=
PILImage
.
open
(
img
.
stream
)
imgc
=
Image
(
blob
=
img
.
stream
)
else
:
else
:
imgc
=
PILImage
.
open
(
io
.
BytesIO
(
img
.
content
))
imgc
=
Image
(
blob
=
io
.
BytesIO
(
img
.
content
))
im
=
imgc
.
convert
(
'RGB'
)
imgc
.
format
=
'jpeg'
tmp_bytesio
=
io
.
BytesIO
()
imgc
.
transform_colorspace
(
"rgb"
)
im
.
save
(
tmp_bytesio
,
format
=
'JPEG'
)
img
=
imgc
img
.
_content
=
tmp_bytesio
.
getvalue
()
else
:
else
:
if
content_type
not
in
'image/jpeg'
:
if
content_type
not
in
'image/jpeg'
:
log
.
error
(
"Only jpg/jpeg files are supported as coverfile"
)
log
.
error
(
"Only jpg/jpeg files are supported as coverfile"
)
...
...
cps/uploader.py
View file @
352b4a0b
...
@@ -66,14 +66,6 @@ except ImportError as e:
...
@@ -66,14 +66,6 @@ except ImportError as e:
log
.
debug
(
'Cannot import fb2, extracting fb2 metadata will not work:
%
s'
,
e
)
log
.
debug
(
'Cannot import fb2, extracting fb2 metadata will not work:
%
s'
,
e
)
use_fb2_meta
=
False
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
):
def
process
(
tmp_file_path
,
original_file_name
,
original_file_extension
,
rarExecutable
):
meta
=
None
meta
=
None
...
@@ -179,10 +171,6 @@ def get_versions():
...
@@ -179,10 +171,6 @@ def get_versions():
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
:
PILVersion
=
'v'
+
PILversion
else
:
PILVersion
=
u'not installed'
if
comic
.
use_comic_meta
:
if
comic
.
use_comic_meta
:
ComicVersion
=
comic
.
comic_version
or
u'installed'
ComicVersion
=
comic
.
comic_version
or
u'installed'
else
:
else
:
...
@@ -191,7 +179,7 @@ def get_versions():
...
@@ -191,7 +179,7 @@ def get_versions():
'PyPdf'
:
PVersion
,
'PyPdf'
:
PVersion
,
'lxml'
:
XVersion
,
'lxml'
:
XVersion
,
'Wand'
:
WVersion
,
'Wand'
:
WVersion
,
'Pillow'
:
PILVersion
,
#
'Pillow': PILVersion,
'Comic_API'
:
ComicVersion
}
'Comic_API'
:
ComicVersion
}
...
...
optional-requirements.txt
View file @
352b4a0b
...
@@ -26,7 +26,6 @@ SQLAlchemy-Utils>=0.33.5,<0.37.0
...
@@ -26,7 +26,6 @@ SQLAlchemy-Utils>=0.33.5,<0.37.0
# extracting metadata
# extracting metadata
lxml
>=3.8.0,<4.6.0
lxml
>=3.8.0,<4.6.0
Pillow
>=4.0.0,<7.2.0
rarfile
>=2.7
rarfile
>=2.7
# other
# other
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment