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
1a458fe3
Commit
1a458fe3
authored
May 21, 2020
by
Ozzieisaacs
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix for #1407 converting books should now be possible again
parent
a4841836
Show whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
397 additions
and
324 deletions
+397
-324
__init__.py
cps/__init__.py
+7
-1
about.py
cps/about.py
+5
-5
admin.py
cps/admin.py
+6
-6
db.py
cps/db.py
+175
-136
editbooks.py
cps/editbooks.py
+70
-69
helper.py
cps/helper.py
+21
-21
kobo.py
cps/kobo.py
+9
-9
opds.py
cps/opds.py
+17
-17
server.py
cps/server.py
+3
-0
shelf.py
cps/shelf.py
+5
-5
web.py
cps/web.py
+48
-47
worker.py
cps/worker.py
+31
-8
No files found.
cps/__init__.py
View file @
1a458fe3
...
...
@@ -37,6 +37,9 @@ from . import config_sql, logger, cache_buster, cli, ub, db
from
.reverseproxy
import
ReverseProxied
from
.server
import
WebServer
# import queue
# queue = queue.Queue()
mimetypes
.
init
()
mimetypes
.
add_type
(
'application/xhtml+xml'
,
'.xhtml'
)
mimetypes
.
add_type
(
'application/epub+zip'
,
'.epub'
)
...
...
@@ -82,6 +85,8 @@ log = logger.create()
from
.
import
services
calibre_db
=
db
.
CalibreDB
()
def
create_app
():
app
.
wsgi_app
=
ReverseProxied
(
app
.
wsgi_app
)
# For python2 convert path to unicode
...
...
@@ -98,7 +103,8 @@ def create_app():
app
.
secret_key
=
os
.
getenv
(
'SECRET_KEY'
,
config_sql
.
get_flask_session_key
(
ub
.
session
))
web_server
.
init_app
(
app
,
config
)
db
.
setup_db
(
config
,
cli
.
settingspath
)
calibre_db
.
setup_db
(
config
,
cli
.
settingspath
)
calibre_db
.
start
()
babel
.
init_app
(
app
)
_BABEL_TRANSLATIONS
.
update
(
str
(
item
)
for
item
in
babel
.
list_translations
())
...
...
cps/about.py
View file @
1a458fe3
...
...
@@ -30,7 +30,7 @@ import babel, pytz, requests, sqlalchemy
import
werkzeug
,
flask
,
flask_login
,
flask_principal
,
jinja2
from
flask_babel
import
gettext
as
_
from
.
import
db
,
converter
,
uploader
,
server
,
isoLanguages
,
constants
from
.
import
db
,
c
alibre_db
,
c
onverter
,
uploader
,
server
,
isoLanguages
,
constants
from
.web
import
render_title_template
try
:
from
flask_login
import
__version__
as
flask_loginVersion
...
...
@@ -85,10 +85,10 @@ _VERSIONS.update(uploader.get_versions())
@
about
.
route
(
"/stats"
)
@
flask_login
.
login_required
def
stats
():
counter
=
db
.
session
.
query
(
db
.
Books
)
.
count
()
authors
=
db
.
session
.
query
(
db
.
Authors
)
.
count
()
categorys
=
db
.
session
.
query
(
db
.
Tags
)
.
count
()
series
=
db
.
session
.
query
(
db
.
Series
)
.
count
()
counter
=
calibre_
db
.
session
.
query
(
db
.
Books
)
.
count
()
authors
=
calibre_
db
.
session
.
query
(
db
.
Authors
)
.
count
()
categorys
=
calibre_
db
.
session
.
query
(
db
.
Tags
)
.
count
()
series
=
calibre_
db
.
session
.
query
(
db
.
Series
)
.
count
()
_VERSIONS
[
'ebook converter'
]
=
_
(
converter
.
get_calibre_version
())
_VERSIONS
[
'unrar'
]
=
_
(
converter
.
get_unrar_version
())
_VERSIONS
[
'kepubify'
]
=
_
(
converter
.
get_kepubify_version
())
...
...
cps/admin.py
View file @
1a458fe3
...
...
@@ -38,7 +38,7 @@ from sqlalchemy.exc import IntegrityError
from
sqlalchemy.sql.expression
import
func
from
.
import
constants
,
logger
,
helper
,
services
from
.
import
db
,
ub
,
web_server
,
get_locale
,
config
,
updater_thread
,
babel
,
gdriveutils
from
.
import
db
,
calibre_db
,
ub
,
web_server
,
get_locale
,
config
,
updater_thread
,
babel
,
gdriveutils
from
.helper
import
speaking_language
,
check_valid_domain
,
send_test_mail
,
reset_password
,
generate_password_hash
from
.gdriveutils
import
is_gdrive_ready
,
gdrive_support
from
.web
import
admin_required
,
render_title_template
,
before_request
,
unconfigured
,
login_required_if_no_ano
...
...
@@ -86,7 +86,7 @@ def shutdown():
showtext
=
{}
if
task
in
(
0
,
1
):
# valid commandos received
# close all database connections
db
.
dispose
()
calibre_
db
.
dispose
()
ub
.
dispose
()
if
task
==
0
:
...
...
@@ -99,7 +99,7 @@ def shutdown():
if
task
==
2
:
log
.
warning
(
"reconnecting to calibre database"
)
db
.
setup_db
(
config
,
ub
.
app_DB_path
)
calibre_
db
.
setup_db
(
config
,
ub
.
app_DB_path
)
showtext
[
'text'
]
=
_
(
u'Reconnect successful'
)
return
json
.
dumps
(
showtext
)
...
...
@@ -148,9 +148,9 @@ def configuration():
@
login_required
@
admin_required
def
view_configuration
():
readColumn
=
db
.
session
.
query
(
db
.
Custom_Columns
)
\
readColumn
=
calibre_
db
.
session
.
query
(
db
.
Custom_Columns
)
\
.
filter
(
and_
(
db
.
Custom_Columns
.
datatype
==
'bool'
,
db
.
Custom_Columns
.
mark_for_delete
==
0
))
.
all
()
restrictColumns
=
db
.
session
.
query
(
db
.
Custom_Columns
)
\
restrictColumns
=
calibre_
db
.
session
.
query
(
db
.
Custom_Columns
)
\
.
filter
(
and_
(
db
.
Custom_Columns
.
datatype
==
'text'
,
db
.
Custom_Columns
.
mark_for_delete
==
0
))
.
all
()
return
render_title_template
(
"config_view_edit.html"
,
conf
=
config
,
readColumns
=
readColumn
,
restrictColumns
=
restrictColumns
,
...
...
@@ -944,7 +944,7 @@ def edit_user(user_id):
translations
=
babel
.
list_translations
()
+
[
LC
(
'en'
)]
kobo_support
=
feature_support
[
'kobo'
]
and
config
.
config_kobo_sync
for
book
in
content
.
downloads
:
downloadbook
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book
.
book_id
)
.
first
()
downloadbook
=
calibre_
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book
.
book_id
)
.
first
()
if
downloadbook
:
downloads
.
append
(
downloadbook
)
else
:
...
...
cps/db.py
100755 → 100644
View file @
1a458fe3
...
...
@@ -23,18 +23,22 @@ import os
import
re
import
ast
from
datetime
import
datetime
import
threading
import
time
import
queue
from
sqlalchemy
import
create_engine
,
event
from
sqlalchemy
import
create_engine
from
sqlalchemy
import
Table
,
Column
,
ForeignKey
,
CheckConstraint
from
sqlalchemy
import
String
,
Integer
,
Boolean
,
TIMESTAMP
,
Float
from
sqlalchemy.orm
import
relationship
,
sessionmaker
,
scoped_session
from
sqlalchemy.ext.declarative
import
declarative_base
from
sqlalchemy.exc
import
OperationalError
session
=
None
from
.
import
logger
#
session = None
cc_exceptions
=
[
'datetime'
,
'comments'
,
'composite'
,
'series'
]
cc_classes
=
{}
engine
=
None
#
engine = None
Base
=
declarative_base
()
...
...
@@ -226,6 +230,7 @@ class Publishers(Base):
class
Data
(
Base
):
__tablename__
=
'data'
__table_args__
=
{
'schema'
:
'calibre'
}
id
=
Column
(
Integer
,
primary_key
=
True
)
book
=
Column
(
Integer
,
ForeignKey
(
'books.id'
),
nullable
=
False
)
...
...
@@ -314,24 +319,45 @@ class Custom_Columns(Base):
return
display_dict
def
update_title_sort
(
config
,
conn
=
None
):
# user defined sort function for calibre databases (Series, etc.)
def
_title_sort
(
title
):
# calibre sort stuff
title_pat
=
re
.
compile
(
config
.
config_title_regex
,
re
.
IGNORECASE
)
match
=
title_pat
.
search
(
title
)
if
match
:
prep
=
match
.
group
(
1
)
title
=
title
.
replace
(
prep
,
''
)
+
', '
+
prep
return
title
.
strip
()
class
CalibreDB
(
threading
.
Thread
):
def
__init__
(
self
):
threading
.
Thread
.
__init__
(
self
)
self
.
engine
=
None
self
.
session
=
None
self
.
queue
=
None
self
.
log
=
None
def
add_queue
(
self
,
queue
):
self
.
queue
=
queue
self
.
log
=
logger
.
create
()
def
run
(
self
):
while
True
:
i
=
self
.
queue
.
get
()
if
i
==
'dummy'
:
self
.
queue
.
task_done
()
break
if
i
[
'task'
]
==
'add_format'
:
cur_book
=
self
.
session
.
query
(
Books
)
.
filter
(
Books
.
id
==
i
[
'id'
])
.
first
()
cur_book
.
data
.
append
(
i
[
'format'
])
try
:
# db.session.merge(cur_book)
self
.
session
.
commit
()
except
OperationalError
as
e
:
self
.
session
.
rollback
()
self
.
log
.
error
(
"Database error:
%
s"
,
e
)
# self._handleError(_(u"Database error: %(error)s.", error=e))
# return
self
.
queue
.
task_done
()
conn
=
conn
or
session
.
connection
()
.
connection
.
connection
conn
.
create_function
(
"title_sort"
,
1
,
_title_sort
)
def
stop
(
self
):
self
.
queue
.
put
(
'dummy'
)
def
setup_db
(
config
,
app_db_path
):
dispose
()
global
engine
def
setup_db
(
self
,
config
,
app_db_path
):
self
.
dispose
()
#
global engine
if
not
config
.
config_calibre_dir
:
config
.
invalidate
()
...
...
@@ -344,21 +370,21 @@ def setup_db(config, app_db_path):
try
:
#engine = create_engine('sqlite:///{0}'.format(dbpath),
engine
=
create_engine
(
'sqlite://'
,
self
.
engine
=
create_engine
(
'sqlite://'
,
echo
=
False
,
isolation_level
=
"SERIALIZABLE"
,
connect_args
=
{
'check_same_thread'
:
False
})
engine
.
execute
(
"attach database '{}' as calibre;"
.
format
(
dbpath
))
engine
.
execute
(
"attach database '{}' as app_settings;"
.
format
(
app_db_path
))
self
.
engine
.
execute
(
"attach database '{}' as calibre;"
.
format
(
dbpath
))
self
.
engine
.
execute
(
"attach database '{}' as app_settings;"
.
format
(
app_db_path
))
conn
=
engine
.
connect
()
conn
=
self
.
engine
.
connect
()
# conn.text_factory = lambda b: b.decode(errors = 'ignore') possible fix for #1302
except
Exception
as
e
:
config
.
invalidate
(
e
)
return
False
config
.
db_configured
=
True
update_title_sort
(
config
,
conn
.
connection
)
self
.
update_title_sort
(
config
,
conn
.
connection
)
if
not
cc_classes
:
cc
=
conn
.
execute
(
"SELECT id, datatype FROM custom_columns"
)
...
...
@@ -408,19 +434,32 @@ def setup_db(config, app_db_path):
backref
=
'books'
))
global
session
#
global session
Session
=
scoped_session
(
sessionmaker
(
autocommit
=
False
,
autoflush
=
False
,
bind
=
engine
))
session
=
Session
()
bind
=
self
.
engine
))
self
.
session
=
Session
()
return
True
def
update_title_sort
(
self
,
config
,
conn
=
None
):
# user defined sort function for calibre databases (Series, etc.)
def
_title_sort
(
title
):
# calibre sort stuff
title_pat
=
re
.
compile
(
config
.
config_title_regex
,
re
.
IGNORECASE
)
match
=
title_pat
.
search
(
title
)
if
match
:
prep
=
match
.
group
(
1
)
title
=
title
.
replace
(
prep
,
''
)
+
', '
+
prep
return
title
.
strip
()
conn
=
conn
or
self
.
session
.
connection
()
.
connection
.
connection
conn
.
create_function
(
"title_sort"
,
1
,
_title_sort
)
def
dispose
(
):
global
session
def
dispose
(
self
):
#
global session
old_session
=
session
session
=
None
old_session
=
self
.
session
self
.
session
=
None
if
old_session
:
try
:
old_session
.
close
()
except
:
pass
...
...
@@ -443,7 +482,7 @@ def dispose():
Base
.
metadata
.
remove
(
table
)
def
reconnect_db
(
config
,
app_db_path
):
session
.
close
()
engine
.
dispose
()
setup_db
(
config
,
app_db_path
)
def
reconnect_db
(
self
,
config
,
app_db_path
):
self
.
session
.
close
()
self
.
engine
.
dispose
()
self
.
setup_db
(
config
,
app_db_path
)
cps/editbooks.py
View file @
1a458fe3
...
...
@@ -33,7 +33,8 @@ from flask_login import current_user, login_required
from
sqlalchemy.exc
import
OperationalError
from
.
import
constants
,
logger
,
isoLanguages
,
gdriveutils
,
uploader
,
helper
from
.
import
config
,
get_locale
,
db
,
ub
,
worker
from
.
import
config
,
get_locale
,
ub
,
worker
,
db
from
.
import
calibre_db
from
.helper
import
order_authors
,
common_filters
from
.web
import
login_required_if_no_ano
,
render_title_template
,
edit_required
,
upload_required
...
...
@@ -175,7 +176,7 @@ def modify_identifiers(input_identifiers, db_identifiers, db_session):
@
login_required
def
delete_book
(
book_id
,
book_format
):
if
current_user
.
role_delete_books
():
book
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book_id
)
.
first
()
book
=
calibre_
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book_id
)
.
first
()
if
book
:
try
:
result
,
error
=
helper
.
delete_book
(
book
,
config
.
config_calibre_dir
,
book_format
=
book_format
.
upper
())
...
...
@@ -193,13 +194,13 @@ def delete_book(book_id, book_format):
# check if only this book links to:
# author, language, series, tags, custom columns
modify_database_object
([
u''
],
book
.
authors
,
db
.
Authors
,
db
.
session
,
'author'
)
modify_database_object
([
u''
],
book
.
tags
,
db
.
Tags
,
db
.
session
,
'tags'
)
modify_database_object
([
u''
],
book
.
series
,
db
.
Series
,
db
.
session
,
'series'
)
modify_database_object
([
u''
],
book
.
languages
,
db
.
Languages
,
db
.
session
,
'languages'
)
modify_database_object
([
u''
],
book
.
publishers
,
db
.
Publishers
,
db
.
session
,
'publishers'
)
modify_database_object
([
u''
],
book
.
authors
,
db
.
Authors
,
calibre_
db
.
session
,
'author'
)
modify_database_object
([
u''
],
book
.
tags
,
db
.
Tags
,
calibre_
db
.
session
,
'tags'
)
modify_database_object
([
u''
],
book
.
series
,
db
.
Series
,
calibre_
db
.
session
,
'series'
)
modify_database_object
([
u''
],
book
.
languages
,
db
.
Languages
,
calibre_
db
.
session
,
'languages'
)
modify_database_object
([
u''
],
book
.
publishers
,
db
.
Publishers
,
calibre_
db
.
session
,
'publishers'
)
cc
=
db
.
session
.
query
(
db
.
Custom_Columns
)
.
\
cc
=
calibre_
db
.
session
.
query
(
db
.
Custom_Columns
)
.
\
filter
(
db
.
Custom_Columns
.
datatype
.
notin_
(
db
.
cc_exceptions
))
.
all
()
for
c
in
cc
:
cc_string
=
"custom_column_"
+
str
(
c
.
id
)
...
...
@@ -209,32 +210,32 @@ def delete_book(book_id, book_format):
del_cc
=
getattr
(
book
,
cc_string
)[
0
]
getattr
(
book
,
cc_string
)
.
remove
(
del_cc
)
log
.
debug
(
'remove '
+
str
(
c
.
id
))
db
.
session
.
delete
(
del_cc
)
db
.
session
.
commit
()
calibre_
db
.
session
.
delete
(
del_cc
)
calibre_
db
.
session
.
commit
()
elif
c
.
datatype
==
'rating'
:
del_cc
=
getattr
(
book
,
cc_string
)[
0
]
getattr
(
book
,
cc_string
)
.
remove
(
del_cc
)
if
len
(
del_cc
.
books
)
==
0
:
log
.
debug
(
'remove '
+
str
(
c
.
id
))
db
.
session
.
delete
(
del_cc
)
db
.
session
.
commit
()
calibre_
db
.
session
.
delete
(
del_cc
)
calibre_
db
.
session
.
commit
()
else
:
del_cc
=
getattr
(
book
,
cc_string
)[
0
]
getattr
(
book
,
cc_string
)
.
remove
(
del_cc
)
log
.
debug
(
'remove '
+
str
(
c
.
id
))
db
.
session
.
delete
(
del_cc
)
db
.
session
.
commit
()
calibre_
db
.
session
.
delete
(
del_cc
)
calibre_
db
.
session
.
commit
()
else
:
modify_database_object
([
u''
],
getattr
(
book
,
cc_string
),
db
.
cc_classes
[
c
.
id
],
db
.
session
,
'custom'
)
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book_id
)
.
delete
()
calibre_
db
.
session
,
'custom'
)
calibre_
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book_id
)
.
delete
()
else
:
db
.
session
.
query
(
db
.
Data
)
.
filter
(
db
.
Data
.
book
==
book
.
id
)
.
\
calibre_
db
.
session
.
query
(
db
.
Data
)
.
filter
(
db
.
Data
.
book
==
book
.
id
)
.
\
filter
(
db
.
Data
.
format
==
book_format
)
.
delete
()
db
.
session
.
commit
()
calibre_
db
.
session
.
commit
()
except
Exception
as
e
:
log
.
debug
(
e
)
db
.
session
.
rollback
()
calibre_
db
.
session
.
rollback
()
else
:
# book not found
log
.
error
(
'Book with id "
%
s" could not be deleted: not found'
,
book_id
)
...
...
@@ -247,9 +248,9 @@ def delete_book(book_id, book_format):
def
render_edit_book
(
book_id
):
db
.
update_title_sort
(
config
)
cc
=
db
.
session
.
query
(
db
.
Custom_Columns
)
.
filter
(
db
.
Custom_Columns
.
datatype
.
notin_
(
db
.
cc_exceptions
))
.
all
()
book
=
db
.
session
.
query
(
db
.
Books
)
\
calibre_
db
.
update_title_sort
(
config
)
cc
=
calibre_
db
.
session
.
query
(
db
.
Custom_Columns
)
.
filter
(
db
.
Custom_Columns
.
datatype
.
notin_
(
db
.
cc_exceptions
))
.
all
()
book
=
calibre_
db
.
session
.
query
(
db
.
Books
)
\
.
filter
(
db
.
Books
.
id
==
book_id
)
.
filter
(
common_filters
())
.
first
()
if
not
book
:
...
...
@@ -304,7 +305,7 @@ def edit_book_ratings(to_save, book):
ratingx2
=
int
(
float
(
to_save
[
"rating"
])
*
2
)
if
ratingx2
!=
old_rating
:
changed
=
True
is_rating
=
db
.
session
.
query
(
db
.
Ratings
)
.
filter
(
db
.
Ratings
.
rating
==
ratingx2
)
.
first
()
is_rating
=
calibre_
db
.
session
.
query
(
db
.
Ratings
)
.
filter
(
db
.
Ratings
.
rating
==
ratingx2
)
.
first
()
if
is_rating
:
book
.
ratings
.
append
(
is_rating
)
else
:
...
...
@@ -326,7 +327,7 @@ def edit_book_languages(to_save, book):
for
l
in
unknown_languages
:
log
.
error
(
'
%
s is not a valid language'
,
l
)
flash
(
_
(
u"
%(langname)
s is not a valid language"
,
langname
=
l
),
category
=
"error"
)
return
modify_database_object
(
list
(
input_l
),
book
.
languages
,
db
.
Languages
,
db
.
session
,
'languages'
)
return
modify_database_object
(
list
(
input_l
),
book
.
languages
,
db
.
Languages
,
calibre_
db
.
session
,
'languages'
)
def
edit_book_publisher
(
to_save
,
book
):
...
...
@@ -334,15 +335,15 @@ def edit_book_publisher(to_save, book):
if
to_save
[
"publisher"
]:
publisher
=
to_save
[
"publisher"
]
.
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
,
db
.
session
,
'publisher'
)
changed
|=
modify_database_object
([
publisher
],
book
.
publishers
,
db
.
Publishers
,
calibre_
db
.
session
,
'publisher'
)
elif
len
(
book
.
publishers
):
changed
|=
modify_database_object
([],
book
.
publishers
,
db
.
Publishers
,
db
.
session
,
'publisher'
)
changed
|=
modify_database_object
([],
book
.
publishers
,
db
.
Publishers
,
calibre_
db
.
session
,
'publisher'
)
return
changed
def
edit_cc_data
(
book_id
,
book
,
to_save
):
changed
=
False
cc
=
db
.
session
.
query
(
db
.
Custom_Columns
)
.
filter
(
db
.
Custom_Columns
.
datatype
.
notin_
(
db
.
cc_exceptions
))
.
all
()
cc
=
calibre_
db
.
session
.
query
(
db
.
Custom_Columns
)
.
filter
(
db
.
Custom_Columns
.
datatype
.
notin_
(
db
.
cc_exceptions
))
.
all
()
for
c
in
cc
:
cc_string
=
"custom_column_"
+
str
(
c
.
id
)
if
not
c
.
is_multiple
:
...
...
@@ -365,12 +366,12 @@ def edit_cc_data(book_id, book, to_save):
else
:
del_cc
=
getattr
(
book
,
cc_string
)[
0
]
getattr
(
book
,
cc_string
)
.
remove
(
del_cc
)
db
.
session
.
delete
(
del_cc
)
calibre_
db
.
session
.
delete
(
del_cc
)
changed
=
True
else
:
cc_class
=
db
.
cc_classes
[
c
.
id
]
new_cc
=
cc_class
(
value
=
to_save
[
cc_string
],
book
=
book_id
)
db
.
session
.
add
(
new_cc
)
calibre_
db
.
session
.
add
(
new_cc
)
changed
=
True
else
:
...
...
@@ -382,18 +383,18 @@ def edit_cc_data(book_id, book, to_save):
del_cc
=
getattr
(
book
,
cc_string
)[
0
]
getattr
(
book
,
cc_string
)
.
remove
(
del_cc
)
if
len
(
del_cc
.
books
)
==
0
:
db
.
session
.
delete
(
del_cc
)
calibre_
db
.
session
.
delete
(
del_cc
)
changed
=
True
cc_class
=
db
.
cc_classes
[
c
.
id
]
new_cc
=
db
.
session
.
query
(
cc_class
)
.
filter
(
new_cc
=
calibre_
db
.
session
.
query
(
cc_class
)
.
filter
(
cc_class
.
value
==
to_save
[
cc_string
]
.
strip
())
.
first
()
# if no cc val is found add it
if
new_cc
is
None
:
new_cc
=
cc_class
(
value
=
to_save
[
cc_string
]
.
strip
())
db
.
session
.
add
(
new_cc
)
calibre_
db
.
session
.
add
(
new_cc
)
changed
=
True
db
.
session
.
flush
()
new_cc
=
db
.
session
.
query
(
cc_class
)
.
filter
(
calibre_
db
.
session
.
flush
()
new_cc
=
calibre_
db
.
session
.
query
(
cc_class
)
.
filter
(
cc_class
.
value
==
to_save
[
cc_string
]
.
strip
())
.
first
()
# add cc value to book
getattr
(
book
,
cc_string
)
.
append
(
new_cc
)
...
...
@@ -403,12 +404,12 @@ def edit_cc_data(book_id, book, to_save):
del_cc
=
getattr
(
book
,
cc_string
)[
0
]
getattr
(
book
,
cc_string
)
.
remove
(
del_cc
)
if
not
del_cc
.
books
or
len
(
del_cc
.
books
)
==
0
:
db
.
session
.
delete
(
del_cc
)
calibre_
db
.
session
.
delete
(
del_cc
)
changed
=
True
else
:
input_tags
=
to_save
[
cc_string
]
.
split
(
','
)
input_tags
=
list
(
map
(
lambda
it
:
it
.
strip
(),
input_tags
))
changed
|=
modify_database_object
(
input_tags
,
getattr
(
book
,
cc_string
),
db
.
cc_classes
[
c
.
id
],
db
.
session
,
changed
|=
modify_database_object
(
input_tags
,
getattr
(
book
,
cc_string
),
db
.
cc_classes
[
c
.
id
],
calibre_
db
.
session
,
'custom'
)
return
changed
...
...
@@ -446,7 +447,7 @@ def upload_single_file(request, book, book_id):
return
redirect
(
url_for
(
'web.show_book'
,
book_id
=
book
.
id
))
file_size
=
os
.
path
.
getsize
(
saved_filename
)
is_format
=
db
.
session
.
query
(
db
.
Data
)
.
filter
(
db
.
Data
.
book
==
book_id
)
.
\
is_format
=
calibre_
db
.
session
.
query
(
db
.
Data
)
.
filter
(
db
.
Data
.
book
==
book_id
)
.
\
filter
(
db
.
Data
.
format
==
file_ext
.
upper
())
.
first
()
# Format entry already exists, no need to update the database
...
...
@@ -455,11 +456,11 @@ def upload_single_file(request, book, book_id):
else
:
try
:
db_format
=
db
.
Data
(
book_id
,
file_ext
.
upper
(),
file_size
,
file_name
)
db
.
session
.
add
(
db_format
)
db
.
session
.
commit
()
db
.
update_title_sort
(
config
)
calibre_
db
.
session
.
add
(
db_format
)
calibre_
db
.
session
.
commit
()
calibre_
db
.
update_title_sort
(
config
)
except
OperationalError
as
e
:
db
.
session
.
rollback
()
calibre_
db
.
session
.
rollback
()
log
.
error
(
'Database error:
%
s'
,
e
)
flash
(
_
(
u"Database error:
%(error)
s."
,
error
=
e
),
category
=
"error"
)
return
redirect
(
url_for
(
'web.show_book'
,
book_id
=
book
.
id
))
...
...
@@ -498,8 +499,8 @@ def edit_book(book_id):
return
render_edit_book
(
book_id
)
# create the function for sorting...
db
.
update_title_sort
(
config
)
book
=
db
.
session
.
query
(
db
.
Books
)
\
calibre_
db
.
update_title_sort
(
config
)
book
=
calibre_
db
.
session
.
query
(
db
.
Books
)
\
.
filter
(
db
.
Books
.
id
==
book_id
)
.
filter
(
common_filters
())
.
first
()
# Book not found
...
...
@@ -531,13 +532,13 @@ def edit_book(book_id):
if
input_authors
==
[
''
]:
input_authors
=
[
_
(
u'Unknown'
)]
# prevent empty Author
modif_date
|=
modify_database_object
(
input_authors
,
book
.
authors
,
db
.
Authors
,
db
.
session
,
'author'
)
modif_date
|=
modify_database_object
(
input_authors
,
book
.
authors
,
db
.
Authors
,
calibre_
db
.
session
,
'author'
)
# Search for each author if author is in database, if not, authorname and sorted authorname is generated new
# everything then is assembled for sorted author field in database
sort_authors_list
=
list
()
for
inp
in
input_authors
:
stored_author
=
db
.
session
.
query
(
db
.
Authors
)
.
filter
(
db
.
Authors
.
name
==
inp
)
.
first
()
stored_author
=
calibre_
db
.
session
.
query
(
db
.
Authors
)
.
filter
(
db
.
Authors
.
name
==
inp
)
.
first
()
if
not
stored_author
:
stored_author
=
helper
.
get_sorted_author
(
inp
)
else
:
...
...
@@ -581,17 +582,17 @@ def edit_book(book_id):
# Handle identifiers
input_identifiers
=
identifier_list
(
to_save
,
book
)
modif_date
|=
modify_identifiers
(
input_identifiers
,
book
.
identifiers
,
db
.
session
)
modif_date
|=
modify_identifiers
(
input_identifiers
,
book
.
identifiers
,
calibre_
db
.
session
)
# Handle book tags
input_tags
=
to_save
[
"tags"
]
.
split
(
','
)
input_tags
=
list
(
map
(
lambda
it
:
it
.
strip
(),
input_tags
))
modif_date
|=
modify_database_object
(
input_tags
,
book
.
tags
,
db
.
Tags
,
db
.
session
,
'tags'
)
modif_date
|=
modify_database_object
(
input_tags
,
book
.
tags
,
db
.
Tags
,
calibre_
db
.
session
,
'tags'
)
# Handle book series
input_series
=
[
to_save
[
"series"
]
.
strip
()]
input_series
=
[
x
for
x
in
input_series
if
x
!=
''
]
modif_date
|=
modify_database_object
(
input_series
,
book
.
series
,
db
.
Series
,
db
.
session
,
'series'
)
modif_date
|=
modify_database_object
(
input_series
,
book
.
series
,
db
.
Series
,
calibre_
db
.
session
,
'series'
)
if
to_save
[
"pubdate"
]:
try
:
...
...
@@ -615,7 +616,7 @@ def edit_book(book_id):
if
modif_date
:
book
.
last_modified
=
datetime
.
utcnow
()
db
.
session
.
commit
()
calibre_
db
.
session
.
commit
()
if
config
.
config_use_google_drive
:
gdriveutils
.
updateGdriveCalibreFromLocal
()
if
"detail_view"
in
to_save
:
...
...
@@ -624,12 +625,12 @@ def edit_book(book_id):
flash
(
_
(
"Metadata successfully updated"
),
category
=
"success"
)
return
render_edit_book
(
book_id
)
else
:
db
.
session
.
rollback
()
calibre_
db
.
session
.
rollback
()
flash
(
error
,
category
=
"error"
)
return
render_edit_book
(
book_id
)
except
Exception
as
e
:
log
.
exception
(
e
)
db
.
session
.
rollback
()
calibre_
db
.
session
.
rollback
()
flash
(
_
(
"Error editing book, please check logfile for details"
),
category
=
"error"
)
return
redirect
(
url_for
(
'web.show_book'
,
book_id
=
book
.
id
))
...
...
@@ -671,8 +672,8 @@ def upload():
for
requested_file
in
request
.
files
.
getlist
(
"btn-upload"
):
try
:
# create the function for sorting...
db
.
update_title_sort
(
config
)
db
.
session
.
connection
()
.
connection
.
connection
.
create_function
(
'uuid4'
,
0
,
lambda
:
str
(
uuid4
()))
calibre_
db
.
update_title_sort
(
config
)
calibre_
db
.
session
.
connection
()
.
connection
.
connection
.
create_function
(
'uuid4'
,
0
,
lambda
:
str
(
uuid4
()))
# check if file extension is correct
if
'.'
in
requested_file
.
filename
:
...
...
@@ -708,13 +709,13 @@ def upload():
+
Markup
(
render_title_template
(
'book_exists_flash.html'
,
entry
=
entry
)),
category
=
"warning"
)
# handle authors
is_author
=
db
.
session
.
query
(
db
.
Authors
)
.
filter
(
db
.
Authors
.
name
==
authr
)
.
first
()
is_author
=
calibre_
db
.
session
.
query
(
db
.
Authors
)
.
filter
(
db
.
Authors
.
name
==
authr
)
.
first
()
if
is_author
:
db_author
=
is_author
authr
=
is_author
.
name
else
:
db_author
=
db
.
Authors
(
authr
,
helper
.
get_sorted_author
(
authr
),
""
)
db
.
session
.
add
(
db_author
)
calibre_
db
.
session
.
add
(
db_author
)
title_dir
=
helper
.
get_valid_filename
(
title
)
author_dir
=
helper
.
get_valid_filename
(
authr
)
...
...
@@ -746,29 +747,29 @@ def upload():
# handle series
db_series
=
None
is_series
=
db
.
session
.
query
(
db
.
Series
)
.
filter
(
db
.
Series
.
name
==
series
)
.
first
()
is_series
=
calibre_
db
.
session
.
query
(
db
.
Series
)
.
filter
(
db
.
Series
.
name
==
series
)
.
first
()
if
is_series
:
db_series
=
is_series
elif
series
!=
''
:
db_series
=
db
.
Series
(
series
,
""
)
db
.
session
.
add
(
db_series
)
calibre_
db
.
session
.
add
(
db_series
)
# add language actually one value in list
input_language
=
meta
.
languages
db_language
=
None
if
input_language
!=
""
:
input_language
=
isoLanguages
.
get
(
name
=
input_language
)
.
part3
hasLanguage
=
db
.
session
.
query
(
db
.
Languages
)
.
filter
(
db
.
Languages
.
lang_code
==
input_language
)
.
first
()
hasLanguage
=
calibre_
db
.
session
.
query
(
db
.
Languages
)
.
filter
(
db
.
Languages
.
lang_code
==
input_language
)
.
first
()
if
hasLanguage
:
db_language
=
hasLanguage
else
:
db_language
=
db
.
Languages
(
input_language
)
db
.
session
.
add
(
db_language
)
calibre_
db
.
session
.
add
(
db_language
)
# If the language of the file is excluded from the users view, it's not imported, to allow the user to view
# the book it's language is set to the filter language
if
db_language
!=
current_user
.
filter_language
()
and
current_user
.
filter_language
()
!=
"all"
:
db_language
=
db
.
session
.
query
(
db
.
Languages
)
.
\
db_language
=
calibre_
db
.
session
.
query
(
db
.
Languages
)
.
\
filter
(
db
.
Languages
.
lang_code
==
current_user
.
filter_language
())
.
first
()
# combine path and normalize path from windows systems
...
...
@@ -788,25 +789,25 @@ def upload():
input_tags
=
tags
.
split
(
','
)
input_tags
=
list
(
map
(
lambda
it
:
it
.
strip
(),
input_tags
))
if
input_tags
[
0
]
!=
""
:
modify_database_object
(
input_tags
,
db_book
.
tags
,
db
.
Tags
,
db
.
session
,
'tags'
)
modify_database_object
(
input_tags
,
db_book
.
tags
,
db
.
Tags
,
calibre_
db
.
session
,
'tags'
)
# flush content, get db_book.id available
db_book
.
data
.
append
(
db_data
)
db
.
session
.
add
(
db_book
)
db
.
session
.
flush
()
calibre_
db
.
session
.
add
(
db_book
)
calibre_
db
.
session
.
flush
()
# add comment
book_id
=
db_book
.
id
upload_comment
=
Markup
(
meta
.
description
)
.
unescape
()
if
upload_comment
!=
""
:
db
.
session
.
add
(
db
.
Comments
(
upload_comment
,
book_id
))
calibre_
db
.
session
.
add
(
db
.
Comments
(
upload_comment
,
book_id
))
# save data to database, reread data
db
.
session
.
commit
()
db
.
update_title_sort
(
config
)
calibre_
db
.
session
.
commit
()
calibre_
db
.
update_title_sort
(
config
)
# Reread book. It's important not to filter the result, as it could have language which hide it from
# current users view (tags are not stored/extracted from metadata and could also be limited)
book
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book_id
)
.
first
()
book
=
calibre_
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book_id
)
.
first
()
# upload book to gdrive if nesseccary and add "(bookid)" to folder name
if
config
.
config_use_google_drive
:
gdriveutils
.
updateGdriveCalibreFromLocal
()
...
...
@@ -823,7 +824,7 @@ def upload():
flash
(
_
(
u"Failed to Move Cover File
%(file)
s:
%(error)
s"
,
file
=
new_coverpath
,
error
=
e
),
category
=
"error"
)
db
.
session
.
commit
()
calibre_
db
.
session
.
commit
()
if
config
.
config_use_google_drive
:
gdriveutils
.
updateGdriveCalibreFromLocal
()
if
error
:
...
...
@@ -846,7 +847,7 @@ def upload():
resp
=
{
"location"
:
url_for
(
'web.show_book'
,
book_id
=
db_book
.
id
)}
return
Response
(
json
.
dumps
(
resp
),
mimetype
=
'application/json'
)
except
OperationalError
as
e
:
db
.
session
.
rollback
()
calibre_
db
.
session
.
rollback
()
log
.
error
(
"Database error:
%
s"
,
e
)
flash
(
_
(
u"Database error:
%(error)
s."
,
error
=
e
),
category
=
"error"
)
return
Response
(
json
.
dumps
({
"location"
:
url_for
(
"web.index"
)}),
mimetype
=
'application/json'
)
...
...
cps/helper.py
View file @
1a458fe3
...
...
@@ -23,7 +23,6 @@ import os
import
io
import
json
import
mimetypes
import
random
import
re
import
shutil
import
time
...
...
@@ -42,6 +41,7 @@ from flask_login import current_user
from
sqlalchemy.sql.expression
import
true
,
false
,
and_
,
or_
,
text
,
func
from
werkzeug.datastructures
import
Headers
from
werkzeug.security
import
generate_password_hash
from
.
import
calibre_db
try
:
from
urllib.parse
import
quote
...
...
@@ -74,8 +74,8 @@ log = logger.create()
# 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
):
book
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book_id
)
.
first
()
data
=
db
.
session
.
query
(
db
.
Data
)
.
filter
(
db
.
Data
.
book
==
book
.
id
)
.
filter
(
db
.
Data
.
format
==
old_book_format
)
.
first
()
book
=
calibre_
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book_id
)
.
first
()
data
=
calibre_
db
.
session
.
query
(
db
.
Data
)
.
filter
(
db
.
Data
.
book
==
book
.
id
)
.
filter
(
db
.
Data
.
format
==
old_book_format
)
.
first
()
if
not
data
:
error_message
=
_
(
u"
%(format)
s format not found for book id:
%(book)
d"
,
format
=
old_book_format
,
book
=
book_id
)
log
.
error
(
"convert_book_format:
%
s"
,
error_message
)
...
...
@@ -212,7 +212,7 @@ def check_read_formats(entry):
# 3: If Pdf file is existing, it's directly send to kindle email
def
send_mail
(
book_id
,
book_format
,
convert
,
kindle_mail
,
calibrepath
,
user_id
):
"""Send email with attachments"""
book
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book_id
)
.
first
()
book
=
calibre_
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book_id
)
.
first
()
if
convert
==
1
:
# returns None if success, otherwise errormessage
...
...
@@ -324,7 +324,7 @@ def delete_book_file(book, calibrepath, book_format=None):
def
update_dir_structure_file
(
book_id
,
calibrepath
,
first_author
):
localbook
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book_id
)
.
first
()
localbook
=
calibre_
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book_id
)
.
first
()
path
=
os
.
path
.
join
(
calibrepath
,
localbook
.
path
)
authordir
=
localbook
.
path
.
split
(
'/'
)[
0
]
...
...
@@ -383,7 +383,7 @@ def update_dir_structure_file(book_id, calibrepath, first_author):
def
update_dir_structure_gdrive
(
book_id
,
first_author
):
error
=
False
book
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book_id
)
.
first
()
book
=
calibre_
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book_id
)
.
first
()
path
=
book
.
path
authordir
=
book
.
path
.
split
(
'/'
)[
0
]
...
...
@@ -494,13 +494,13 @@ def get_cover_on_failure(use_generic_cover):
def
get_book_cover
(
book_id
):
book
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book_id
)
.
filter
(
common_filters
(
allow_show_archived
=
True
))
.
first
()
book
=
calibre_
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book_id
)
.
filter
(
common_filters
(
allow_show_archived
=
True
))
.
first
()
return
get_book_cover_internal
(
book
,
use_generic_cover_on_failure
=
True
)
def
get_book_cover_with_uuid
(
book_uuid
,
use_generic_cover_on_failure
=
True
):
book
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
uuid
==
book_uuid
)
.
first
()
book
=
calibre_
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
uuid
==
book_uuid
)
.
first
()
return
get_book_cover_internal
(
book
,
use_generic_cover_on_failure
)
...
...
@@ -775,7 +775,7 @@ def tags_filters():
# Creates for all stored languages a translated speaking name in the array for the UI
def
speaking_language
(
languages
=
None
):
if
not
languages
:
languages
=
db
.
session
.
query
(
db
.
Languages
)
.
join
(
db
.
books_languages_link
)
.
join
(
db
.
Books
)
\
languages
=
calibre_
db
.
session
.
query
(
db
.
Languages
)
.
join
(
db
.
books_languages_link
)
.
join
(
db
.
Books
)
\
.
filter
(
common_filters
())
\
.
group_by
(
text
(
'books_languages_link.lang_code'
))
.
all
()
for
lang
in
languages
:
...
...
@@ -808,7 +808,7 @@ def order_authors(entry):
error
=
False
for
auth
in
sort_authors
:
# ToDo: How to handle not found authorname
result
=
db
.
session
.
query
(
db
.
Authors
)
.
filter
(
db
.
Authors
.
sort
==
auth
.
lstrip
()
.
strip
())
.
first
()
result
=
calibre_
db
.
session
.
query
(
db
.
Authors
)
.
filter
(
db
.
Authors
.
sort
==
auth
.
lstrip
()
.
strip
())
.
first
()
if
not
result
:
error
=
True
break
...
...
@@ -825,12 +825,12 @@ def fill_indexpage(page, database, db_filter, order, *join):
def
fill_indexpage_with_archived_books
(
page
,
database
,
db_filter
,
order
,
allow_show_archived
,
*
join
):
if
current_user
.
show_detail_random
():
randm
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
common_filters
(
allow_show_archived
))
\
randm
=
calibre_
db
.
session
.
query
(
db
.
Books
)
.
filter
(
common_filters
(
allow_show_archived
))
\
.
order_by
(
func
.
random
())
.
limit
(
config
.
config_random_books
)
else
:
randm
=
false
()
off
=
int
(
int
(
config
.
config_books_per_page
)
*
(
page
-
1
))
query
=
db
.
session
.
query
(
database
)
.
join
(
*
join
,
isouter
=
True
)
.
\
query
=
calibre_
db
.
session
.
query
(
database
)
.
join
(
*
join
,
isouter
=
True
)
.
\
filter
(
db_filter
)
.
\
filter
(
common_filters
(
allow_show_archived
))
pagination
=
Pagination
(
page
,
config
.
config_books_per_page
,
...
...
@@ -843,8 +843,8 @@ def fill_indexpage_with_archived_books(page, database, db_filter, order, allow_s
def
get_typeahead
(
database
,
query
,
replace
=
(
''
,
''
),
tag_filter
=
true
()):
query
=
query
or
''
db
.
session
.
connection
()
.
connection
.
connection
.
create_function
(
"lower"
,
1
,
lcase
)
entries
=
db
.
session
.
query
(
database
)
.
filter
(
tag_filter
)
.
\
calibre_
db
.
session
.
connection
()
.
connection
.
connection
.
create_function
(
"lower"
,
1
,
lcase
)
entries
=
calibre_
db
.
session
.
query
(
database
)
.
filter
(
tag_filter
)
.
\
filter
(
func
.
lower
(
database
.
name
)
.
ilike
(
"
%
"
+
query
+
"
%
"
))
.
all
()
json_dumps
=
json
.
dumps
([
dict
(
name
=
r
.
name
.
replace
(
*
replace
))
for
r
in
entries
])
return
json_dumps
...
...
@@ -852,7 +852,7 @@ def get_typeahead(database, query, replace=('', ''), tag_filter=true()):
# read search results from calibre-database and return it (function is used for feed and simple search
def
get_search_results
(
term
):
db
.
session
.
connection
()
.
connection
.
connection
.
create_function
(
"lower"
,
1
,
lcase
)
calibre_
db
.
session
.
connection
()
.
connection
.
connection
.
create_function
(
"lower"
,
1
,
lcase
)
q
=
list
()
authorterms
=
re
.
split
(
"[, ]+"
,
term
)
for
authorterm
in
authorterms
:
...
...
@@ -860,7 +860,7 @@ def get_search_results(term):
db
.
Books
.
authors
.
any
(
func
.
lower
(
db
.
Authors
.
name
)
.
ilike
(
"
%
"
+
term
+
"
%
"
))
return
db
.
session
.
query
(
db
.
Books
)
.
filter
(
common_filters
())
.
filter
(
return
calibre_
db
.
session
.
query
(
db
.
Books
)
.
filter
(
common_filters
())
.
filter
(
or_
(
db
.
Books
.
tags
.
any
(
func
.
lower
(
db
.
Tags
.
name
)
.
ilike
(
"
%
"
+
term
+
"
%
"
)),
db
.
Books
.
series
.
any
(
func
.
lower
(
db
.
Series
.
name
)
.
ilike
(
"
%
"
+
term
+
"
%
"
)),
db
.
Books
.
authors
.
any
(
and_
(
*
q
)),
...
...
@@ -870,7 +870,7 @@ def get_search_results(term):
def
get_cc_columns
(
filter_config_custom_read
=
False
):
tmpcc
=
db
.
session
.
query
(
db
.
Custom_Columns
)
.
filter
(
db
.
Custom_Columns
.
datatype
.
notin_
(
db
.
cc_exceptions
))
.
all
()
tmpcc
=
calibre_
db
.
session
.
query
(
db
.
Custom_Columns
)
.
filter
(
db
.
Custom_Columns
.
datatype
.
notin_
(
db
.
cc_exceptions
))
.
all
()
cc
=
[]
r
=
None
if
config
.
config_columns_to_ignore
:
...
...
@@ -887,9 +887,9 @@ def get_cc_columns(filter_config_custom_read=False):
def
get_download_link
(
book_id
,
book_format
,
client
):
book_format
=
book_format
.
split
(
"."
)[
0
]
book
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book_id
)
.
filter
(
common_filters
())
.
first
()
book
=
calibre_
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book_id
)
.
filter
(
common_filters
())
.
first
()
if
book
:
data1
=
db
.
session
.
query
(
db
.
Data
)
.
filter
(
db
.
Data
.
book
==
book
.
id
)
\
data1
=
calibre_
db
.
session
.
query
(
db
.
Data
)
.
filter
(
db
.
Data
.
book
==
book
.
id
)
\
.
filter
(
db
.
Data
.
format
==
book_format
.
upper
())
.
first
()
else
:
abort
(
404
)
...
...
@@ -911,13 +911,13 @@ def get_download_link(book_id, book_format, client):
def
check_exists_book
(
authr
,
title
):
db
.
session
.
connection
()
.
connection
.
connection
.
create_function
(
"lower"
,
1
,
lcase
)
calibre_
db
.
session
.
connection
()
.
connection
.
connection
.
create_function
(
"lower"
,
1
,
lcase
)
q
=
list
()
authorterms
=
re
.
split
(
r'\s*&\s*'
,
authr
)
for
authorterm
in
authorterms
:
q
.
append
(
db
.
Books
.
authors
.
any
(
func
.
lower
(
db
.
Authors
.
name
)
.
ilike
(
"
%
"
+
authorterm
+
"
%
"
)))
return
db
.
session
.
query
(
db
.
Books
)
.
filter
(
return
calibre_
db
.
session
.
query
(
db
.
Books
)
.
filter
(
and_
(
db
.
Books
.
authors
.
any
(
and_
(
*
q
)),
func
.
lower
(
db
.
Books
.
title
)
.
ilike
(
"
%
"
+
title
+
"
%
"
)
))
.
first
()
...
...
cps/kobo.py
View file @
1a458fe3
...
...
@@ -48,7 +48,7 @@ from sqlalchemy.sql.expression import and_, or_
from
sqlalchemy.exc
import
StatementError
import
requests
from
.
import
config
,
logger
,
kobo_auth
,
db
,
helper
,
shelf
as
shelf_lib
,
ub
from
.
import
config
,
logger
,
kobo_auth
,
db
,
calibre_db
,
helper
,
shelf
as
shelf_lib
,
ub
from
.services
import
SyncToken
as
SyncToken
from
.web
import
download_required
from
.kobo_auth
import
requires_kobo_auth
...
...
@@ -170,7 +170,7 @@ def HandleSyncRequest():
# It looks like it's treating the db.Books.last_modified field as a string and may fail
# the comparison because of the +00:00 suffix.
changed_entries
=
(
db
.
session
.
query
(
db
.
Books
)
calibre_
db
.
session
.
query
(
db
.
Books
)
.
join
(
db
.
Data
)
.
filter
(
or_
(
func
.
datetime
(
db
.
Books
.
last_modified
)
>
sync_token
.
books_last_modified
,
db
.
Books
.
id
.
in_
(
recently_restored_or_archived_books
)))
...
...
@@ -207,7 +207,7 @@ def HandleSyncRequest():
ub
.
KoboReadingState
.
user_id
==
current_user
.
id
,
ub
.
KoboReadingState
.
book_id
.
notin_
(
reading_states_in_new_entitlements
))))
for
kobo_reading_state
in
changed_reading_states
.
all
():
book
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
kobo_reading_state
.
book_id
)
.
one_or_none
()
book
=
calibre_
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
kobo_reading_state
.
book_id
)
.
one_or_none
()
if
book
:
sync_results
.
append
({
"ChangedReadingState"
:
{
...
...
@@ -256,7 +256,7 @@ def HandleMetadataRequest(book_uuid):
if
not
current_app
.
wsgi_app
.
is_proxied
:
log
.
debug
(
'Kobo: Received unproxied request, changed request port to server port'
)
log
.
info
(
"Kobo library metadata request received for book
%
s"
%
book_uuid
)
book
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
uuid
==
book_uuid
)
.
first
()
book
=
calibre_
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
uuid
==
book_uuid
)
.
first
()
if
not
book
or
not
book
.
data
:
log
.
info
(
u"Book
%
s not found in database"
,
book_uuid
)
return
redirect_or_proxy_request
()
...
...
@@ -474,7 +474,7 @@ def add_items_to_shelf(items, shelf):
items_unknown_to_calibre
.
append
(
item
)
continue
book
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
uuid
==
item
[
"RevisionId"
])
.
one_or_none
()
book
=
calibre_
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
uuid
==
item
[
"RevisionId"
])
.
one_or_none
()
if
not
book
:
items_unknown_to_calibre
.
append
(
item
)
continue
...
...
@@ -545,7 +545,7 @@ def HandleTagRemoveItem(tag_id):
items_unknown_to_calibre
.
append
(
item
)
continue
book
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
uuid
==
item
[
"RevisionId"
])
.
one_or_none
()
book
=
calibre_
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
uuid
==
item
[
"RevisionId"
])
.
one_or_none
()
if
not
book
:
items_unknown_to_calibre
.
append
(
item
)
continue
...
...
@@ -613,7 +613,7 @@ def create_kobo_tag(shelf):
"Type"
:
"UserTag"
}
for
book_shelf
in
shelf
.
books
:
book
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book_shelf
.
book_id
)
.
one_or_none
()
book
=
calibre_
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book_shelf
.
book_id
)
.
one_or_none
()
if
not
book
:
log
.
info
(
u"Book (id:
%
s) in BookShelf (id:
%
s) not found in book database"
,
book_shelf
.
book_id
,
shelf
.
id
)
continue
...
...
@@ -629,7 +629,7 @@ def create_kobo_tag(shelf):
@
kobo
.
route
(
"/v1/library/<book_uuid>/state"
,
methods
=
[
"GET"
,
"PUT"
])
@
login_required
def
HandleStateRequest
(
book_uuid
):
book
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
uuid
==
book_uuid
)
.
first
()
book
=
calibre_
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
uuid
==
book_uuid
)
.
first
()
if
not
book
or
not
book
.
data
:
log
.
info
(
u"Book
%
s not found in database"
,
book_uuid
)
return
redirect_or_proxy_request
()
...
...
@@ -804,7 +804,7 @@ def TopLevelEndpoint():
@
login_required
def
HandleBookDeletionRequest
(
book_uuid
):
log
.
info
(
"Kobo book deletion request received for book
%
s"
%
book_uuid
)
book
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
uuid
==
book_uuid
)
.
first
()
book
=
calibre_
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
uuid
==
book_uuid
)
.
first
()
if
not
book
:
log
.
info
(
u"Book
%
s not found in database"
,
book_uuid
)
return
redirect_or_proxy_request
()
...
...
cps/opds.py
View file @
1a458fe3
...
...
@@ -30,7 +30,7 @@ from flask_login import current_user
from
sqlalchemy.sql.expression
import
func
,
text
,
or_
,
and_
from
werkzeug.security
import
check_password_hash
from
.
import
constants
,
logger
,
config
,
db
,
ub
,
services
,
get_locale
,
isoLanguages
from
.
import
constants
,
logger
,
config
,
db
,
calibre_db
,
ub
,
services
,
get_locale
,
isoLanguages
from
.helper
import
fill_indexpage
,
get_download_link
,
get_book_cover
,
speaking_language
from
.pagination
import
Pagination
from
.web
import
common_filters
,
get_search_results
,
render_read_books
,
download_required
...
...
@@ -108,7 +108,7 @@ def feed_new():
@
opds
.
route
(
"/opds/discover"
)
@
requires_basic_auth_if_no_ano
def
feed_discover
():
entries
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
common_filters
())
.
order_by
(
func
.
random
())
\
entries
=
calibre_
db
.
session
.
query
(
db
.
Books
)
.
filter
(
common_filters
())
.
order_by
(
func
.
random
())
\
.
limit
(
config
.
config_books_per_page
)
pagination
=
Pagination
(
1
,
config
.
config_books_per_page
,
int
(
config
.
config_books_per_page
))
return
render_xml_template
(
'feed.xml'
,
entries
=
entries
,
pagination
=
pagination
)
...
...
@@ -133,10 +133,10 @@ def feed_hot():
hot_books
=
all_books
.
offset
(
off
)
.
limit
(
config
.
config_books_per_page
)
entries
=
list
()
for
book
in
hot_books
:
downloadBook
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book
.
Downloads
.
book_id
)
.
first
()
downloadBook
=
calibre_
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book
.
Downloads
.
book_id
)
.
first
()
if
downloadBook
:
entries
.
append
(
db
.
session
.
query
(
db
.
Books
)
.
filter
(
common_filters
())
calibre_
db
.
session
.
query
(
db
.
Books
)
.
filter
(
common_filters
())
.
filter
(
db
.
Books
.
id
==
book
.
Downloads
.
book_id
)
.
first
()
)
else
:
...
...
@@ -153,11 +153,11 @@ def feed_hot():
@
requires_basic_auth_if_no_ano
def
feed_authorindex
():
off
=
request
.
args
.
get
(
"offset"
)
or
0
entries
=
db
.
session
.
query
(
db
.
Authors
)
.
join
(
db
.
books_authors_link
)
.
join
(
db
.
Books
)
.
filter
(
common_filters
())
\
entries
=
calibre_
db
.
session
.
query
(
db
.
Authors
)
.
join
(
db
.
books_authors_link
)
.
join
(
db
.
Books
)
.
filter
(
common_filters
())
\
.
group_by
(
text
(
'books_authors_link.author'
))
.
order_by
(
db
.
Authors
.
sort
)
.
limit
(
config
.
config_books_per_page
)
\
.
offset
(
off
)
pagination
=
Pagination
((
int
(
off
)
/
(
int
(
config
.
config_books_per_page
))
+
1
),
config
.
config_books_per_page
,
len
(
db
.
session
.
query
(
db
.
Authors
)
.
all
()))
len
(
calibre_
db
.
session
.
query
(
db
.
Authors
)
.
all
()))
return
render_xml_template
(
'feed.xml'
,
listelements
=
entries
,
folder
=
'opds.feed_author'
,
pagination
=
pagination
)
...
...
@@ -176,11 +176,11 @@ def feed_author(book_id):
@
requires_basic_auth_if_no_ano
def
feed_publisherindex
():
off
=
request
.
args
.
get
(
"offset"
)
or
0
entries
=
db
.
session
.
query
(
db
.
Publishers
)
.
join
(
db
.
books_publishers_link
)
.
join
(
db
.
Books
)
.
filter
(
common_filters
())
\
entries
=
calibre_
db
.
session
.
query
(
db
.
Publishers
)
.
join
(
db
.
books_publishers_link
)
.
join
(
db
.
Books
)
.
filter
(
common_filters
())
\
.
group_by
(
text
(
'books_publishers_link.publisher'
))
.
order_by
(
db
.
Publishers
.
sort
)
\
.
limit
(
config
.
config_books_per_page
)
.
offset
(
off
)
pagination
=
Pagination
((
int
(
off
)
/
(
int
(
config
.
config_books_per_page
))
+
1
),
config
.
config_books_per_page
,
len
(
db
.
session
.
query
(
db
.
Publishers
)
.
all
()))
len
(
calibre_
db
.
session
.
query
(
db
.
Publishers
)
.
all
()))
return
render_xml_template
(
'feed.xml'
,
listelements
=
entries
,
folder
=
'opds.feed_publisher'
,
pagination
=
pagination
)
...
...
@@ -199,10 +199,10 @@ def feed_publisher(book_id):
@
requires_basic_auth_if_no_ano
def
feed_categoryindex
():
off
=
request
.
args
.
get
(
"offset"
)
or
0
entries
=
db
.
session
.
query
(
db
.
Tags
)
.
join
(
db
.
books_tags_link
)
.
join
(
db
.
Books
)
.
filter
(
common_filters
())
\
entries
=
calibre_
db
.
session
.
query
(
db
.
Tags
)
.
join
(
db
.
books_tags_link
)
.
join
(
db
.
Books
)
.
filter
(
common_filters
())
\
.
group_by
(
text
(
'books_tags_link.tag'
))
.
order_by
(
db
.
Tags
.
name
)
.
offset
(
off
)
.
limit
(
config
.
config_books_per_page
)
pagination
=
Pagination
((
int
(
off
)
/
(
int
(
config
.
config_books_per_page
))
+
1
),
config
.
config_books_per_page
,
len
(
db
.
session
.
query
(
db
.
Tags
)
.
all
()))
len
(
calibre_
db
.
session
.
query
(
db
.
Tags
)
.
all
()))
return
render_xml_template
(
'feed.xml'
,
listelements
=
entries
,
folder
=
'opds.feed_category'
,
pagination
=
pagination
)
...
...
@@ -221,10 +221,10 @@ def feed_category(book_id):
@
requires_basic_auth_if_no_ano
def
feed_seriesindex
():
off
=
request
.
args
.
get
(
"offset"
)
or
0
entries
=
db
.
session
.
query
(
db
.
Series
)
.
join
(
db
.
books_series_link
)
.
join
(
db
.
Books
)
.
filter
(
common_filters
())
\
entries
=
calibre_
db
.
session
.
query
(
db
.
Series
)
.
join
(
db
.
books_series_link
)
.
join
(
db
.
Books
)
.
filter
(
common_filters
())
\
.
group_by
(
text
(
'books_series_link.series'
))
.
order_by
(
db
.
Series
.
sort
)
.
offset
(
off
)
.
all
()
pagination
=
Pagination
((
int
(
off
)
/
(
int
(
config
.
config_books_per_page
))
+
1
),
config
.
config_books_per_page
,
len
(
db
.
session
.
query
(
db
.
Series
)
.
all
()))
len
(
calibre_
db
.
session
.
query
(
db
.
Series
)
.
all
()))
return
render_xml_template
(
'feed.xml'
,
listelements
=
entries
,
folder
=
'opds.feed_series'
,
pagination
=
pagination
)
...
...
@@ -243,7 +243,7 @@ def feed_series(book_id):
@
requires_basic_auth_if_no_ano
def
feed_ratingindex
():
off
=
request
.
args
.
get
(
"offset"
)
or
0
entries
=
db
.
session
.
query
(
db
.
Ratings
,
func
.
count
(
'books_ratings_link.book'
)
.
label
(
'count'
),
entries
=
calibre_
db
.
session
.
query
(
db
.
Ratings
,
func
.
count
(
'books_ratings_link.book'
)
.
label
(
'count'
),
(
db
.
Ratings
.
rating
/
2
)
.
label
(
'name'
))
\
.
join
(
db
.
books_ratings_link
)
.
join
(
db
.
Books
)
.
filter
(
common_filters
())
\
.
group_by
(
text
(
'books_ratings_link.rating'
))
.
order_by
(
db
.
Ratings
.
rating
)
.
all
()
...
...
@@ -271,7 +271,7 @@ def feed_ratings(book_id):
@
requires_basic_auth_if_no_ano
def
feed_formatindex
():
off
=
request
.
args
.
get
(
"offset"
)
or
0
entries
=
db
.
session
.
query
(
db
.
Data
)
.
join
(
db
.
Books
)
.
filter
(
common_filters
())
\
entries
=
calibre_
db
.
session
.
query
(
db
.
Data
)
.
join
(
db
.
Books
)
.
filter
(
common_filters
())
\
.
group_by
(
db
.
Data
.
format
)
.
order_by
(
db
.
Data
.
format
)
.
all
()
pagination
=
Pagination
((
int
(
off
)
/
(
int
(
config
.
config_books_per_page
))
+
1
),
config
.
config_books_per_page
,
len
(
entries
))
...
...
@@ -305,7 +305,7 @@ def feed_languagesindex():
cur_l
=
LC
.
parse
(
current_user
.
filter_language
())
except
UnknownLocaleError
:
cur_l
=
None
languages
=
db
.
session
.
query
(
db
.
Languages
)
.
filter
(
languages
=
calibre_
db
.
session
.
query
(
db
.
Languages
)
.
filter
(
db
.
Languages
.
lang_code
==
current_user
.
filter_language
())
.
all
()
if
cur_l
:
languages
[
0
]
.
name
=
cur_l
.
get_language_name
(
get_locale
())
...
...
@@ -356,7 +356,7 @@ def feed_shelf(book_id):
books_in_shelf
=
ub
.
session
.
query
(
ub
.
BookShelf
)
.
filter
(
ub
.
BookShelf
.
shelf
==
book_id
)
.
order_by
(
ub
.
BookShelf
.
order
.
asc
())
.
all
()
for
book
in
books_in_shelf
:
cur_book
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book
.
book_id
)
.
first
()
cur_book
=
calibre_
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book
.
book_id
)
.
first
()
result
.
append
(
cur_book
)
pagination
=
Pagination
((
int
(
off
)
/
(
int
(
config
.
config_books_per_page
))
+
1
),
config
.
config_books_per_page
,
len
(
result
))
...
...
@@ -378,7 +378,7 @@ def opds_download_link(book_id, book_format):
@
opds
.
route
(
"/ajax/book/<string:uuid>"
,
defaults
=
{
'library'
:
""
})
@
requires_basic_auth_if_no_ano
def
get_metadata_calibre_companion
(
uuid
,
library
):
entry
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
uuid
.
like
(
"
%
"
+
uuid
+
"
%
"
))
.
first
()
entry
=
calibre_
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
uuid
.
like
(
"
%
"
+
uuid
+
"
%
"
))
.
first
()
if
entry
is
not
None
:
js
=
render_template
(
'json.txt'
,
entry
=
entry
)
response
=
make_response
(
js
)
...
...
cps/server.py
View file @
1a458fe3
...
...
@@ -196,6 +196,9 @@ class WebServer(object):
def
stop
(
self
,
restart
=
False
):
from
.
import
updater_thread
updater_thread
.
stop
()
from
.
import
calibre_db
calibre_db
.
stop
()
log
.
info
(
"webserver stop (restart=
%
s)"
,
restart
)
self
.
restart
=
restart
...
...
cps/shelf.py
View file @
1a458fe3
...
...
@@ -28,7 +28,7 @@ from flask_babel import gettext as _
from
flask_login
import
login_required
,
current_user
from
sqlalchemy.sql.expression
import
func
from
.
import
logger
,
ub
,
searched_ids
,
db
from
.
import
logger
,
ub
,
searched_ids
,
db
,
calibre_db
from
.web
import
render_title_template
from
.helper
import
common_filters
...
...
@@ -320,11 +320,11 @@ def show_shelf(shelf_type, shelf_id):
books_in_shelf
=
ub
.
session
.
query
(
ub
.
BookShelf
)
.
filter
(
ub
.
BookShelf
.
shelf
==
shelf_id
)
\
.
order_by
(
ub
.
BookShelf
.
order
.
asc
())
.
all
()
for
book
in
books_in_shelf
:
cur_book
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book
.
book_id
)
.
filter
(
common_filters
())
.
first
()
cur_book
=
calibre_
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book
.
book_id
)
.
filter
(
common_filters
())
.
first
()
if
cur_book
:
result
.
append
(
cur_book
)
else
:
cur_book
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book
.
book_id
)
.
first
()
cur_book
=
calibre_
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book
.
book_id
)
.
first
()
if
not
cur_book
:
log
.
info
(
'Not existing book
%
s in
%
s deleted'
,
book
.
book_id
,
shelf
)
ub
.
session
.
query
(
ub
.
BookShelf
)
.
filter
(
ub
.
BookShelf
.
book_id
==
book
.
book_id
)
.
delete
()
...
...
@@ -356,7 +356,7 @@ def order_shelf(shelf_id):
books_in_shelf2
=
ub
.
session
.
query
(
ub
.
BookShelf
)
.
filter
(
ub
.
BookShelf
.
shelf
==
shelf_id
)
\
.
order_by
(
ub
.
BookShelf
.
order
.
asc
())
.
all
()
for
book
in
books_in_shelf2
:
cur_book
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book
.
book_id
)
.
filter
(
common_filters
())
.
first
()
cur_book
=
calibre_
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book
.
book_id
)
.
filter
(
common_filters
())
.
first
()
if
cur_book
:
result
.
append
({
'title'
:
cur_book
.
title
,
'id'
:
cur_book
.
id
,
...
...
@@ -364,7 +364,7 @@ def order_shelf(shelf_id):
'series'
:
cur_book
.
series
,
'series_index'
:
cur_book
.
series_index
})
else
:
cur_book
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book
.
book_id
)
.
first
()
cur_book
=
calibre_
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book
.
book_id
)
.
first
()
result
.
append
({
'title'
:
_
(
'Hidden Book'
),
'id'
:
cur_book
.
id
,
'author'
:
[],
...
...
cps/web.py
View file @
1a458fe3
...
...
@@ -50,6 +50,7 @@ from werkzeug.security import generate_password_hash, check_password_hash
from
.
import
constants
,
logger
,
isoLanguages
,
services
,
worker
from
.
import
searched_ids
,
lm
,
babel
,
db
,
ub
,
config
,
get_locale
,
app
from
.
import
calibre_db
from
.gdriveutils
import
getFileFromEbooksFolder
,
do_gdrive_download
from
.helper
import
common_filters
,
get_search_results
,
fill_indexpage
,
fill_indexpage_with_archived_books
,
\
speaking_language
,
check_valid_domain
,
order_authors
,
get_typeahead
,
render_task_status
,
json_serial
,
\
...
...
@@ -438,21 +439,21 @@ def toggle_read(book_id):
ub
.
session
.
commit
()
else
:
try
:
db
.
update_title_sort
(
config
)
book
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book_id
)
.
filter
(
common_filters
())
.
first
()
calibre_
db
.
update_title_sort
(
config
)
book
=
calibre_
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book_id
)
.
filter
(
common_filters
())
.
first
()
read_status
=
getattr
(
book
,
'custom_column_'
+
str
(
config
.
config_read_column
))
if
len
(
read_status
):
read_status
[
0
]
.
value
=
not
read_status
[
0
]
.
value
db
.
session
.
commit
()
calibre_
db
.
session
.
commit
()
else
:
cc_class
=
db
.
cc_classes
[
config
.
config_read_column
]
new_cc
=
cc_class
(
value
=
1
,
book
=
book_id
)
db
.
session
.
add
(
new_cc
)
db
.
session
.
commit
()
calibre_
db
.
session
.
add
(
new_cc
)
calibre_
db
.
session
.
commit
()
except
KeyError
:
log
.
error
(
u"Custom Column No.
%
d is not exisiting in calibre database"
,
config
.
config_read_column
)
except
OperationalError
as
e
:
db
.
session
.
rollback
()
calibre_
db
.
session
.
rollback
()
log
.
error
(
u"Read status could not set:
%
e"
,
e
)
return
""
...
...
@@ -496,7 +497,7 @@ def update_view():
@web.route("/ajax/getcomic/<int:book_id>/<book_format>/<int:page>")
@login_required
def get_comic_book(book_id, book_format, page):
book = db.session.query(db.Books).filter(db.Books.id == book_id).first()
book =
calibre_
db.session.query(db.Books).filter(db.Books.id == book_id).first()
if not book:
return "", 204
else:
...
...
@@ -589,8 +590,8 @@ def get_languages_json():
@
login_required_if_no_ano
def
get_matching_tags
():
tag_dict
=
{
'tags'
:
[]}
q
=
db
.
session
.
query
(
db
.
Books
)
db
.
session
.
connection
()
.
connection
.
connection
.
create_function
(
"lower"
,
1
,
lcase
)
q
=
calibre_
db
.
session
.
query
(
db
.
Books
)
calibre_
db
.
session
.
connection
()
.
connection
.
connection
.
create_function
(
"lower"
,
1
,
lcase
)
author_input
=
request
.
args
.
get
(
'author_name'
)
or
''
title_input
=
request
.
args
.
get
(
'book_title'
)
or
''
include_tag_inputs
=
request
.
args
.
getlist
(
'include_tag'
)
or
''
...
...
@@ -692,7 +693,7 @@ def books_list(data, sort, book_id, page):
def
render_hot_books
(
page
):
if
current_user
.
check_visibility
(
constants
.
SIDEBAR_HOT
):
if
current_user
.
show_detail_random
():
random
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
common_filters
())
\
random
=
calibre_
db
.
session
.
query
(
db
.
Books
)
.
filter
(
common_filters
())
\
.
order_by
(
func
.
random
())
.
limit
(
config
.
config_random_books
)
else
:
random
=
false
()
...
...
@@ -702,7 +703,7 @@ def render_hot_books(page):
hot_books
=
all_books
.
offset
(
off
)
.
limit
(
config
.
config_books_per_page
)
entries
=
list
()
for
book
in
hot_books
:
downloadBook
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
common_filters
())
.
filter
(
downloadBook
=
calibre_
db
.
session
.
query
(
db
.
Books
)
.
filter
(
common_filters
())
.
filter
(
db
.
Books
.
id
==
book
.
Downloads
.
book_id
)
.
first
()
if
downloadBook
:
entries
.
append
(
downloadBook
)
...
...
@@ -727,7 +728,7 @@ def render_author_books(page, author_id, order):
category
=
"error"
)
return
redirect
(
url_for
(
"web.index"
))
author
=
db
.
session
.
query
(
db
.
Authors
)
.
get
(
author_id
)
author
=
calibre_
db
.
session
.
query
(
db
.
Authors
)
.
get
(
author_id
)
author_name
=
author
.
name
.
replace
(
'|'
,
','
)
author_info
=
None
...
...
@@ -742,7 +743,7 @@ def render_author_books(page, author_id, order):
def
render_publisher_books
(
page
,
book_id
,
order
):
publisher
=
db
.
session
.
query
(
db
.
Publishers
)
.
filter
(
db
.
Publishers
.
id
==
book_id
)
.
first
()
publisher
=
calibre_
db
.
session
.
query
(
db
.
Publishers
)
.
filter
(
db
.
Publishers
.
id
==
book_id
)
.
first
()
if
publisher
:
entries
,
random
,
pagination
=
fill_indexpage
(
page
,
db
.
Books
,
db
.
Books
.
publishers
.
any
(
db
.
Publishers
.
id
==
book_id
),
...
...
@@ -755,7 +756,7 @@ def render_publisher_books(page, book_id, order):
def
render_series_books
(
page
,
book_id
,
order
):
name
=
db
.
session
.
query
(
db
.
Series
)
.
filter
(
db
.
Series
.
id
==
book_id
)
.
first
()
name
=
calibre_
db
.
session
.
query
(
db
.
Series
)
.
filter
(
db
.
Series
.
id
==
book_id
)
.
first
()
if
name
:
entries
,
random
,
pagination
=
fill_indexpage
(
page
,
db
.
Books
,
db
.
Books
.
series
.
any
(
db
.
Series
.
id
==
book_id
),
[
db
.
Books
.
series_index
,
order
[
0
]])
...
...
@@ -766,7 +767,7 @@ def render_series_books(page, book_id, order):
def
render_ratings_books
(
page
,
book_id
,
order
):
name
=
db
.
session
.
query
(
db
.
Ratings
)
.
filter
(
db
.
Ratings
.
id
==
book_id
)
.
first
()
name
=
calibre_
db
.
session
.
query
(
db
.
Ratings
)
.
filter
(
db
.
Ratings
.
id
==
book_id
)
.
first
()
entries
,
random
,
pagination
=
fill_indexpage
(
page
,
db
.
Books
,
db
.
Books
.
ratings
.
any
(
db
.
Ratings
.
id
==
book_id
),
[
db
.
Books
.
timestamp
.
desc
(),
order
[
0
]])
if
name
and
name
.
rating
<=
10
:
...
...
@@ -777,7 +778,7 @@ def render_ratings_books(page, book_id, order):
def
render_formats_books
(
page
,
book_id
,
order
):
name
=
db
.
session
.
query
(
db
.
Data
)
.
filter
(
db
.
Data
.
format
==
book_id
.
upper
())
.
first
()
name
=
calibre_
db
.
session
.
query
(
db
.
Data
)
.
filter
(
db
.
Data
.
format
==
book_id
.
upper
())
.
first
()
if
name
:
entries
,
random
,
pagination
=
fill_indexpage
(
page
,
db
.
Books
,
db
.
Books
.
data
.
any
(
db
.
Data
.
format
==
book_id
.
upper
()),
...
...
@@ -789,7 +790,7 @@ def render_formats_books(page, book_id, order):
def
render_category_books
(
page
,
book_id
,
order
):
name
=
db
.
session
.
query
(
db
.
Tags
)
.
filter
(
db
.
Tags
.
id
==
book_id
)
.
first
()
name
=
calibre_
db
.
session
.
query
(
db
.
Tags
)
.
filter
(
db
.
Tags
.
id
==
book_id
)
.
first
()
if
name
:
entries
,
random
,
pagination
=
fill_indexpage
(
page
,
db
.
Books
,
db
.
Books
.
tags
.
any
(
db
.
Tags
.
id
==
book_id
),
[
order
[
0
],
db
.
Series
.
name
,
db
.
Books
.
series_index
],
...
...
@@ -825,10 +826,10 @@ def books_table():
@
login_required_if_no_ano
def
author_list
():
if
current_user
.
check_visibility
(
constants
.
SIDEBAR_AUTHOR
):
entries
=
db
.
session
.
query
(
db
.
Authors
,
func
.
count
(
'books_authors_link.book'
)
.
label
(
'count'
))
\
entries
=
calibre_
db
.
session
.
query
(
db
.
Authors
,
func
.
count
(
'books_authors_link.book'
)
.
label
(
'count'
))
\
.
join
(
db
.
books_authors_link
)
.
join
(
db
.
Books
)
.
filter
(
common_filters
())
\
.
group_by
(
text
(
'books_authors_link.author'
))
.
order_by
(
db
.
Authors
.
sort
)
.
all
()
charlist
=
db
.
session
.
query
(
func
.
upper
(
func
.
substr
(
db
.
Authors
.
sort
,
1
,
1
))
.
label
(
'char'
))
\
charlist
=
calibre_
db
.
session
.
query
(
func
.
upper
(
func
.
substr
(
db
.
Authors
.
sort
,
1
,
1
))
.
label
(
'char'
))
\
.
join
(
db
.
books_authors_link
)
.
join
(
db
.
Books
)
.
filter
(
common_filters
())
\
.
group_by
(
func
.
upper
(
func
.
substr
(
db
.
Authors
.
sort
,
1
,
1
)))
.
all
()
for
entry
in
entries
:
...
...
@@ -843,10 +844,10 @@ def author_list():
@
login_required_if_no_ano
def
publisher_list
():
if
current_user
.
check_visibility
(
constants
.
SIDEBAR_PUBLISHER
):
entries
=
db
.
session
.
query
(
db
.
Publishers
,
func
.
count
(
'books_publishers_link.book'
)
.
label
(
'count'
))
\
entries
=
calibre_
db
.
session
.
query
(
db
.
Publishers
,
func
.
count
(
'books_publishers_link.book'
)
.
label
(
'count'
))
\
.
join
(
db
.
books_publishers_link
)
.
join
(
db
.
Books
)
.
filter
(
common_filters
())
\
.
group_by
(
text
(
'books_publishers_link.publisher'
))
.
order_by
(
db
.
Publishers
.
name
)
.
all
()
charlist
=
db
.
session
.
query
(
func
.
upper
(
func
.
substr
(
db
.
Publishers
.
name
,
1
,
1
))
.
label
(
'char'
))
\
charlist
=
calibre_
db
.
session
.
query
(
func
.
upper
(
func
.
substr
(
db
.
Publishers
.
name
,
1
,
1
))
.
label
(
'char'
))
\
.
join
(
db
.
books_publishers_link
)
.
join
(
db
.
Books
)
.
filter
(
common_filters
())
\
.
group_by
(
func
.
upper
(
func
.
substr
(
db
.
Publishers
.
name
,
1
,
1
)))
.
all
()
return
render_title_template
(
'list.html'
,
entries
=
entries
,
folder
=
'web.books_list'
,
charlist
=
charlist
,
...
...
@@ -860,19 +861,19 @@ def publisher_list():
def
series_list
():
if
current_user
.
check_visibility
(
constants
.
SIDEBAR_SERIES
):
if
current_user
.
series_view
==
'list'
:
entries
=
db
.
session
.
query
(
db
.
Series
,
func
.
count
(
'books_series_link.book'
)
.
label
(
'count'
))
\
entries
=
calibre_
db
.
session
.
query
(
db
.
Series
,
func
.
count
(
'books_series_link.book'
)
.
label
(
'count'
))
\
.
join
(
db
.
books_series_link
)
.
join
(
db
.
Books
)
.
filter
(
common_filters
())
\
.
group_by
(
text
(
'books_series_link.series'
))
.
order_by
(
db
.
Series
.
sort
)
.
all
()
charlist
=
db
.
session
.
query
(
func
.
upper
(
func
.
substr
(
db
.
Series
.
sort
,
1
,
1
))
.
label
(
'char'
))
\
charlist
=
calibre_
db
.
session
.
query
(
func
.
upper
(
func
.
substr
(
db
.
Series
.
sort
,
1
,
1
))
.
label
(
'char'
))
\
.
join
(
db
.
books_series_link
)
.
join
(
db
.
Books
)
.
filter
(
common_filters
())
\
.
group_by
(
func
.
upper
(
func
.
substr
(
db
.
Series
.
sort
,
1
,
1
)))
.
all
()
return
render_title_template
(
'list.html'
,
entries
=
entries
,
folder
=
'web.books_list'
,
charlist
=
charlist
,
title
=
_
(
u"Series"
),
page
=
"serieslist"
,
data
=
"series"
)
else
:
entries
=
db
.
session
.
query
(
db
.
Books
,
func
.
count
(
'books_series_link'
)
.
label
(
'count'
))
\
entries
=
calibre_
db
.
session
.
query
(
db
.
Books
,
func
.
count
(
'books_series_link'
)
.
label
(
'count'
))
\
.
join
(
db
.
books_series_link
)
.
join
(
db
.
Series
)
.
filter
(
common_filters
())
\
.
group_by
(
text
(
'books_series_link.series'
))
.
order_by
(
db
.
Series
.
sort
)
.
all
()
charlist
=
db
.
session
.
query
(
func
.
upper
(
func
.
substr
(
db
.
Series
.
sort
,
1
,
1
))
.
label
(
'char'
))
\
charlist
=
calibre_
db
.
session
.
query
(
func
.
upper
(
func
.
substr
(
db
.
Series
.
sort
,
1
,
1
))
.
label
(
'char'
))
\
.
join
(
db
.
books_series_link
)
.
join
(
db
.
Books
)
.
filter
(
common_filters
())
\
.
group_by
(
func
.
upper
(
func
.
substr
(
db
.
Series
.
sort
,
1
,
1
)))
.
all
()
...
...
@@ -886,9 +887,9 @@ def series_list():
@
login_required_if_no_ano
def
ratings_list
():
if
current_user
.
check_visibility
(
constants
.
SIDEBAR_RATING
):
entries
=
db
.
session
.
query
(
db
.
Ratings
,
func
.
count
(
'books_ratings_link.book'
)
.
label
(
'count'
),
entries
=
calibre_
db
.
session
.
query
(
db
.
Ratings
,
func
.
count
(
'books_ratings_link.book'
)
.
label
(
'count'
),
(
db
.
Ratings
.
rating
/
2
)
.
label
(
'name'
))
\
.
join
(
db
.
books_ratings_link
)
.
join
(
db
.
Books
)
.
filter
(
common_filters
())
\
.
join
(
calibre_
db
.
books_ratings_link
)
.
join
(
db
.
Books
)
.
filter
(
common_filters
())
\
.
group_by
(
text
(
'books_ratings_link.rating'
))
.
order_by
(
db
.
Ratings
.
rating
)
.
all
()
return
render_title_template
(
'list.html'
,
entries
=
entries
,
folder
=
'web.books_list'
,
charlist
=
list
(),
title
=
_
(
u"Ratings list"
),
page
=
"ratingslist"
,
data
=
"ratings"
)
...
...
@@ -900,7 +901,7 @@ def ratings_list():
@
login_required_if_no_ano
def
formats_list
():
if
current_user
.
check_visibility
(
constants
.
SIDEBAR_FORMAT
):
entries
=
db
.
session
.
query
(
db
.
Data
,
func
.
count
(
'data.book'
)
.
label
(
'count'
),
db
.
Data
.
format
.
label
(
'format'
))
\
entries
=
calibre_
db
.
session
.
query
(
db
.
Data
,
func
.
count
(
'data.book'
)
.
label
(
'count'
),
db
.
Data
.
format
.
label
(
'format'
))
\
.
join
(
db
.
Books
)
.
filter
(
common_filters
())
\
.
group_by
(
db
.
Data
.
format
)
.
order_by
(
db
.
Data
.
format
)
.
all
()
return
render_title_template
(
'list.html'
,
entries
=
entries
,
folder
=
'web.books_list'
,
charlist
=
list
(),
...
...
@@ -922,13 +923,13 @@ def language_overview():
cur_l
=
LC
.
parse
(
current_user
.
filter_language
())
except
UnknownLocaleError
:
cur_l
=
None
languages
=
db
.
session
.
query
(
db
.
Languages
)
.
filter
(
languages
=
calibre_
db
.
session
.
query
(
db
.
Languages
)
.
filter
(
db
.
Languages
.
lang_code
==
current_user
.
filter_language
())
.
all
()
if
cur_l
:
languages
[
0
]
.
name
=
cur_l
.
get_language_name
(
get_locale
())
else
:
languages
[
0
]
.
name
=
_
(
isoLanguages
.
get
(
part3
=
languages
[
0
]
.
lang_code
)
.
name
)
lang_counter
=
db
.
session
.
query
(
db
.
books_languages_link
,
lang_counter
=
calibre_
db
.
session
.
query
(
db
.
books_languages_link
,
func
.
count
(
'books_languages_link.book'
)
.
label
(
'bookcount'
))
.
group_by
(
text
(
'books_languages_link.lang_code'
))
.
all
()
return
render_title_template
(
'languages.html'
,
languages
=
languages
,
lang_counter
=
lang_counter
,
...
...
@@ -942,10 +943,10 @@ def language_overview():
@
login_required_if_no_ano
def
category_list
():
if
current_user
.
check_visibility
(
constants
.
SIDEBAR_CATEGORY
):
entries
=
db
.
session
.
query
(
db
.
Tags
,
func
.
count
(
'books_tags_link.book'
)
.
label
(
'count'
))
\
entries
=
calibre_
db
.
session
.
query
(
db
.
Tags
,
func
.
count
(
'books_tags_link.book'
)
.
label
(
'count'
))
\
.
join
(
db
.
books_tags_link
)
.
join
(
db
.
Books
)
.
order_by
(
db
.
Tags
.
name
)
.
filter
(
common_filters
())
\
.
group_by
(
text
(
'books_tags_link.tag'
))
.
all
()
charlist
=
db
.
session
.
query
(
func
.
upper
(
func
.
substr
(
db
.
Tags
.
name
,
1
,
1
))
.
label
(
'char'
))
\
charlist
=
calibre_
db
.
session
.
query
(
func
.
upper
(
func
.
substr
(
db
.
Tags
.
name
,
1
,
1
))
.
label
(
'char'
))
\
.
join
(
db
.
books_tags_link
)
.
join
(
db
.
Books
)
.
filter
(
common_filters
())
\
.
group_by
(
func
.
upper
(
func
.
substr
(
db
.
Tags
.
name
,
1
,
1
)))
.
all
()
return
render_title_template
(
'list.html'
,
entries
=
entries
,
folder
=
'web.books_list'
,
charlist
=
charlist
,
...
...
@@ -1003,8 +1004,8 @@ def search():
def
advanced_search
():
# Build custom columns names
cc
=
get_cc_columns
()
db
.
session
.
connection
()
.
connection
.
connection
.
create_function
(
"lower"
,
1
,
lcase
)
q
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
common_filters
())
.
order_by
(
db
.
Books
.
sort
)
calibre_
db
.
session
.
connection
()
.
connection
.
connection
.
create_function
(
"lower"
,
1
,
lcase
)
q
=
calibre_
db
.
session
.
query
(
db
.
Books
)
.
filter
(
common_filters
())
.
order_by
(
db
.
Books
.
sort
)
include_tag_inputs
=
request
.
args
.
getlist
(
'include_tag'
)
exclude_tag_inputs
=
request
.
args
.
getlist
(
'exclude_tag'
)
...
...
@@ -1057,11 +1058,11 @@ def advanced_search():
format
=
'medium'
,
locale
=
get_locale
())])
except
ValueError
:
pub_start
=
u""
tag_names
=
db
.
session
.
query
(
db
.
Tags
)
.
filter
(
db
.
Tags
.
id
.
in_
(
include_tag_inputs
))
.
all
()
tag_names
=
calibre_
db
.
session
.
query
(
db
.
Tags
)
.
filter
(
db
.
Tags
.
id
.
in_
(
include_tag_inputs
))
.
all
()
searchterm
.
extend
(
tag
.
name
for
tag
in
tag_names
)
serie_names
=
db
.
session
.
query
(
db
.
Series
)
.
filter
(
db
.
Series
.
id
.
in_
(
include_series_inputs
))
.
all
()
serie_names
=
calibre_
db
.
session
.
query
(
db
.
Series
)
.
filter
(
db
.
Series
.
id
.
in_
(
include_series_inputs
))
.
all
()
searchterm
.
extend
(
serie
.
name
for
serie
in
serie_names
)
language_names
=
db
.
session
.
query
(
db
.
Languages
)
.
filter
(
db
.
Languages
.
id
.
in_
(
include_languages_inputs
))
.
all
()
language_names
=
calibre_
db
.
session
.
query
(
db
.
Languages
)
.
filter
(
db
.
Languages
.
id
.
in_
(
include_languages_inputs
))
.
all
()
if
language_names
:
language_names
=
speaking_language
(
language_names
)
searchterm
.
extend
(
language
.
name
for
language
in
language_names
)
...
...
@@ -1136,11 +1137,11 @@ def advanced_search():
return
render_title_template
(
'search.html'
,
adv_searchterm
=
searchterm
,
entries
=
q
,
title
=
_
(
u"search"
),
page
=
"search"
)
# prepare data for search-form
tags
=
db
.
session
.
query
(
db
.
Tags
)
.
join
(
db
.
books_tags_link
)
.
join
(
db
.
Books
)
.
filter
(
common_filters
())
\
tags
=
calibre_
db
.
session
.
query
(
db
.
Tags
)
.
join
(
db
.
books_tags_link
)
.
join
(
db
.
Books
)
.
filter
(
common_filters
())
\
.
group_by
(
text
(
'books_tags_link.tag'
))
.
order_by
(
db
.
Tags
.
name
)
.
all
()
series
=
db
.
session
.
query
(
db
.
Series
)
.
join
(
db
.
books_series_link
)
.
join
(
db
.
Books
)
.
filter
(
common_filters
())
\
series
=
calibre_
db
.
session
.
query
(
db
.
Series
)
.
join
(
db
.
books_series_link
)
.
join
(
db
.
Books
)
.
filter
(
common_filters
())
\
.
group_by
(
text
(
'books_series_link.series'
))
.
order_by
(
db
.
Series
.
name
)
.
filter
(
common_filters
())
.
all
()
extensions
=
db
.
session
.
query
(
db
.
Data
)
.
join
(
db
.
Books
)
.
filter
(
common_filters
())
\
extensions
=
calibre_
db
.
session
.
query
(
db
.
Data
)
.
join
(
db
.
Books
)
.
filter
(
common_filters
())
\
.
group_by
(
db
.
Data
.
format
)
.
order_by
(
db
.
Data
.
format
)
.
all
()
if
current_user
.
filter_language
()
==
u"all"
:
...
...
@@ -1229,8 +1230,8 @@ def get_cover(book_id):
@
viewer_required
def
serve_book
(
book_id
,
book_format
,
anyname
):
book_format
=
book_format
.
split
(
"."
)[
0
]
book
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book_id
)
.
first
()
data
=
db
.
session
.
query
(
db
.
Data
)
.
filter
(
db
.
Data
.
book
==
book
.
id
)
.
filter
(
db
.
Data
.
format
==
book_format
.
upper
())
\
book
=
calibre_
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book_id
)
.
first
()
data
=
calibre_
db
.
session
.
query
(
db
.
Data
)
.
filter
(
db
.
Data
.
book
==
book
.
id
)
.
filter
(
db
.
Data
.
format
==
book_format
.
upper
())
\
.
first
()
log
.
info
(
'Serving book:
%
s'
,
data
.
name
)
if
config
.
config_use_google_drive
:
...
...
@@ -1522,9 +1523,9 @@ def profile():
oauth_status
=
None
for
book
in
current_user
.
downloads
:
downloadBook
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book
.
book_id
)
.
first
()
downloadBook
=
calibre_
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book
.
book_id
)
.
first
()
if
downloadBook
:
downloads
.
append
(
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book
.
book_id
)
.
first
())
downloads
.
append
(
calibre_
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book
.
book_id
)
.
first
())
else
:
ub
.
delete_download
(
book
.
book_id
)
if
request
.
method
==
"POST"
:
...
...
@@ -1603,7 +1604,7 @@ def profile():
@
login_required_if_no_ano
@
viewer_required
def
read_book
(
book_id
,
book_format
):
book
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book_id
)
.
filter
(
common_filters
())
.
first
()
book
=
calibre_
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book_id
)
.
filter
(
common_filters
())
.
first
()
if
not
book
:
flash
(
_
(
u"Error opening eBook. File does not exist or file is not accessible:"
),
category
=
"error"
)
log
.
debug
(
u"Error opening eBook. File does not exist or file is not accessible:"
)
...
...
@@ -1627,7 +1628,7 @@ def read_book(book_id, book_format):
else
:
for
fileExt
in
constants
.
EXTENSIONS_AUDIO
:
if
book_format
.
lower
()
==
fileExt
:
entries
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book_id
)
.
filter
(
common_filters
())
.
first
()
entries
=
calibre_
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book_id
)
.
filter
(
common_filters
())
.
first
()
log
.
debug
(
u"Start mp3 listening for
%
d"
,
book_id
)
return
render_title_template
(
'listenmp3.html'
,
mp3file
=
book_id
,
audioformat
=
book_format
.
lower
(),
title
=
_
(
u"Read a Book"
),
entry
=
entries
,
bookmark
=
bookmark
)
...
...
@@ -1653,7 +1654,7 @@ def read_book(book_id, book_format):
@
web
.
route
(
"/book/<int:book_id>"
)
@
login_required_if_no_ano
def
show_book
(
book_id
):
entries
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
and_
(
db
.
Books
.
id
==
book_id
,
entries
=
calibre_
db
.
session
.
query
(
db
.
Books
)
.
filter
(
and_
(
db
.
Books
.
id
==
book_id
,
common_filters
(
allow_show_archived
=
True
)))
.
first
()
if
entries
:
for
index
in
range
(
0
,
len
(
entries
.
languages
)):
...
...
cps/worker.py
View file @
1a458fe3
...
...
@@ -24,10 +24,10 @@ import smtplib
import
socket
import
time
import
threading
import
queue
from
glob
import
glob
from
shutil
import
copyfile
from
datetime
import
datetime
from
sqlalchemy.exc
import
OperationalError
try
:
from
StringIO
import
StringIO
...
...
@@ -46,7 +46,8 @@ from email.utils import make_msgid
from
email.generator
import
Generator
from
flask_babel
import
gettext
as
_
from
.
import
db
,
logger
,
config
from
.
import
calibre_db
,
db
from
.
import
logger
,
config
from
.subproc_wrapper
import
process_open
from
.
import
gdriveutils
...
...
@@ -190,6 +191,8 @@ class WorkerThread(threading.Thread):
self
.
UIqueue
=
list
()
self
.
asyncSMTP
=
None
self
.
id
=
0
self
.
db_queue
=
queue
.
Queue
()
calibre_db
.
add_queue
(
self
.
db_queue
)
self
.
doLock
=
threading
.
Lock
()
# Main thread loop starting the different tasks
...
...
@@ -275,6 +278,18 @@ class WorkerThread(threading.Thread):
self
.
doLock
.
acquire
()
index
=
self
.
current
self
.
doLock
.
release
()
'''dbpath = os.path.join(config.config_calibre_dir, "metadata.db")
engine = create_engine('sqlite://',
echo=False,
isolation_level="SERIALIZABLE",
connect_args={'check_same_thread': True})
engine.execute("attach database '{}' as calibre;".format(dbpath))
conn = engine.connect()
Session = scoped_session(sessionmaker(autocommit=False,
autoflush=False,
bind=engine))
w_session = Session()
engine.execute("attach database '{}' as calibre;".format(dbpath))'''
file_path
=
self
.
queue
[
index
][
'file_path'
]
bookid
=
self
.
queue
[
index
][
'bookid'
]
format_old_ext
=
u'.'
+
self
.
queue
[
index
][
'settings'
][
'old_book_format'
]
.
lower
()
...
...
@@ -285,7 +300,7 @@ class WorkerThread(threading.Thread):
# this will allow send to kindle workflow to continue to work
if
os
.
path
.
isfile
(
file_path
+
format_new_ext
):
log
.
info
(
"Book id
%
d already converted to
%
s"
,
bookid
,
format_new_ext
)
cur_book
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
bookid
)
.
first
()
cur_book
=
calibre_
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
bookid
)
.
first
()
self
.
queue
[
index
][
'path'
]
=
file_path
self
.
queue
[
index
][
'title'
]
=
cur_book
.
title
self
.
_handleSuccess
()
...
...
@@ -309,19 +324,26 @@ class WorkerThread(threading.Thread):
check
,
error_message
=
self
.
_convert_calibre
(
file_path
,
format_old_ext
,
format_new_ext
,
index
)
if
check
==
0
:
cur_book
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
bookid
)
.
first
()
cur_book
=
calibre_
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
bookid
)
.
first
()
if
os
.
path
.
isfile
(
file_path
+
format_new_ext
):
# self.db_queue.join()
new_format
=
db
.
Data
(
name
=
cur_book
.
data
[
0
]
.
name
,
book_format
=
self
.
queue
[
index
][
'settings'
][
'new_book_format'
]
.
upper
(),
book
=
bookid
,
uncompressed_size
=
os
.
path
.
getsize
(
file_path
+
format_new_ext
))
cur_book
.
data
.
append
(
new_format
)
task
=
{
'task'
:
'add_format'
,
'id'
:
bookid
,
'format'
:
new_format
}
self
.
db_queue
.
put
(
task
)
# To Do how to handle error?
print
(
'finished'
)
'''cur_book.data.append(new_format)
try:
db
.
session
.
commit
()
# db.session.merge(cur_book)
calibre_db.session.commit()
except OperationalError as e:
db
.
session
.
rollback
()
calibre_
db.session.rollback()
log.error("Database error:
%
s", e)
self._handleError(_(u"Database error:
%(error)
s.", error=e))
return
return
'''
self
.
queue
[
index
][
'path'
]
=
cur_book
.
path
self
.
queue
[
index
][
'title'
]
=
cur_book
.
title
...
...
@@ -375,6 +397,7 @@ class WorkerThread(threading.Thread):
# process returncode
check
=
p
.
returncode
calibre_traceback
=
p
.
stderr
.
readlines
()
error_message
=
""
for
ele
in
calibre_traceback
:
if
sys
.
version_info
<
(
3
,
0
):
ele
=
ele
.
decode
(
'utf-8'
)
...
...
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