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
1da4efec
Commit
1da4efec
authored
Dec 31, 2019
by
Ozzieisaacs
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' into Develop
parents
1c630eb6
5887f0fe
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
1342 additions
and
2528 deletions
+1342
-2528
admin.py
cps/admin.py
+23
-15
config_sql.py
cps/config_sql.py
+5
-1
constants.py
cps/constants.py
+2
-0
helper.py
cps/helper.py
+9
-3
opds.py
cps/opds.py
+4
-3
server.py
cps/server.py
+1
-1
main.css
cps/static/css/main.css
+0
-1
table.js
cps/static/js/table.js
+36
-8
email_edit.html
cps/templates/email_edit.html
+25
-7
user_edit.html
cps/templates/user_edit.html
+1
-2
ub.py
cps/ub.py
+13
-4
web.py
cps/web.py
+32
-15
worker.py
cps/worker.py
+1
-1
Calibre-Web TestSummary.html
test/Calibre-Web TestSummary.html
+1190
-2467
No files found.
cps/admin.py
View file @
1da4efec
...
...
@@ -197,10 +197,10 @@ def update_view_configuration():
return
view_configuration
()
@
admi
.
route
(
"/ajax/editdomain"
,
methods
=
[
'POST'
])
@
admi
.
route
(
"/ajax/editdomain
/<int:allow>
"
,
methods
=
[
'POST'
])
@
login_required
@
admin_required
def
edit_domain
():
def
edit_domain
(
allow
):
# POST /post
# name: 'username', //name of field (column in db)
# pk: 1 //primary key (record id)
...
...
@@ -213,14 +213,14 @@ def edit_domain():
return
""
@
admi
.
route
(
"/ajax/adddomain"
,
methods
=
[
'POST'
])
@
admi
.
route
(
"/ajax/adddomain
/<int:allow>
"
,
methods
=
[
'POST'
])
@
login_required
@
admin_required
def
add_domain
():
def
add_domain
(
allow
):
domain_name
=
request
.
form
.
to_dict
()[
'domainname'
]
.
replace
(
'*'
,
'
%
'
)
.
replace
(
'?'
,
'_'
)
.
lower
()
check
=
ub
.
session
.
query
(
ub
.
Registration
)
.
filter
(
ub
.
Registration
.
domain
==
domain_name
)
.
first
()
check
=
ub
.
session
.
query
(
ub
.
Registration
)
.
filter
(
ub
.
Registration
.
domain
==
domain_name
)
.
fi
lter
(
ub
.
Registration
.
allow
==
allow
)
.
fi
rst
()
if
not
check
:
new_domain
=
ub
.
Registration
(
domain
=
domain_name
)
new_domain
=
ub
.
Registration
(
domain
=
domain_name
,
allow
=
allow
)
ub
.
session
.
add
(
new_domain
)
ub
.
session
.
commit
()
return
""
...
...
@@ -234,18 +234,18 @@ def delete_domain():
ub
.
session
.
query
(
ub
.
Registration
)
.
filter
(
ub
.
Registration
.
id
==
domain_id
)
.
delete
()
ub
.
session
.
commit
()
# If last domain was deleted, add all domains by default
if
not
ub
.
session
.
query
(
ub
.
Registration
)
.
count
():
new_domain
=
ub
.
Registration
(
domain
=
"
%
.
%
"
)
if
not
ub
.
session
.
query
(
ub
.
Registration
)
.
filter
(
ub
.
Registration
.
allow
==
1
)
.
count
():
new_domain
=
ub
.
Registration
(
domain
=
"
%
.
%
"
,
allow
=
1
)
ub
.
session
.
add
(
new_domain
)
ub
.
session
.
commit
()
return
""
@
admi
.
route
(
"/ajax/domainlist"
)
@
admi
.
route
(
"/ajax/domainlist
/<int:allow>
"
)
@
login_required
@
admin_required
def
list_domain
():
answer
=
ub
.
session
.
query
(
ub
.
Registration
)
.
all
()
def
list_domain
(
allow
):
answer
=
ub
.
session
.
query
(
ub
.
Registration
)
.
filter
(
ub
.
Registration
.
allow
==
allow
)
.
all
()
json_dumps
=
json
.
dumps
([{
"domain"
:
r
.
domain
.
replace
(
'
%
'
,
'*'
)
.
replace
(
'_'
,
'?'
),
"id"
:
r
.
id
}
for
r
in
answer
])
js
=
json
.
dumps
(
json_dumps
.
replace
(
'"'
,
"'"
))
.
lstrip
(
'"'
)
.
strip
(
'"'
)
response
=
make_response
(
js
.
replace
(
"'"
,
'"'
))
...
...
@@ -635,6 +635,7 @@ def edit_user(user_id):
else
:
flash
(
_
(
u"Found an existing account for this e-mail address."
),
category
=
"error"
)
return
render_title_template
(
"user_edit.html"
,
translations
=
translations
,
languages
=
languages
,
mail_configured
=
config
.
get_mail_server_configured
(),
new_user
=
0
,
content
=
content
,
downloads
=
downloads
,
registered_oauth
=
oauth_check
,
title
=
_
(
u"Edit User
%(nick)
s"
,
nick
=
content
.
nickname
),
page
=
"edituser"
)
if
"nickname"
in
to_save
and
to_save
[
"nickname"
]
!=
content
.
nickname
:
...
...
@@ -646,11 +647,11 @@ def edit_user(user_id):
return
render_title_template
(
"user_edit.html"
,
translations
=
translations
,
languages
=
languages
,
mail_configured
=
config
.
get_mail_server_configured
(),
new_user
=
0
,
content
=
content
,
downloads
=
downloads
,
registered_oauth
=
oauth_check
,
title
=
_
(
u"Edit User
%(nick)
s"
,
nick
=
content
.
nickname
),
title
=
_
(
u"Edit User
%(nick)
s"
,
nick
=
content
.
nickname
),
page
=
"edituser"
)
if
"kindle_mail"
in
to_save
and
to_save
[
"kindle_mail"
]
!=
content
.
kindle_mail
:
...
...
@@ -663,21 +664,27 @@ def edit_user(user_id):
flash
(
_
(
u"An unknown error occured."
),
category
=
"error"
)
return
render_title_template
(
"user_edit.html"
,
translations
=
translations
,
languages
=
languages
,
new_user
=
0
,
content
=
content
,
downloads
=
downloads
,
registered_oauth
=
oauth_check
,
mail_configured
=
config
.
get_mail_server_configured
(),
title
=
_
(
u"Edit User
%(nick)
s"
,
nick
=
content
.
nickname
),
page
=
"edituser"
)
@
admi
.
route
(
"/admin/resetpassword/<int:user_id>"
)
@
login_required
@
admin_required
def
reset_password
(
user_id
):
def
reset_
user_
password
(
user_id
):
if
not
config
.
config_public_reg
:
abort
(
404
)
if
current_user
is
not
None
and
current_user
.
is_authenticated
:
ret
,
message
=
reset_password
(
user_id
)
if
ret
==
1
:
log
.
debug
(
u"Password for user
%(user)
s reset"
,
user
=
message
)
flash
(
_
(
u"Password for user
%(user)
s reset"
,
user
=
message
),
category
=
"success"
)
else
:
elif
ret
==
0
:
log
.
error
(
u"An unknown error occurred. Please try again later."
)
flash
(
_
(
u"An unknown error occurred. Please try again later."
),
category
=
"error"
)
else
:
log
.
error
(
u"Please configure the SMTP mail settings first..."
)
flash
(
_
(
u"Please configure the SMTP mail settings first..."
),
category
=
"error"
)
return
redirect
(
url_for
(
'admin.admin'
))
...
...
@@ -711,6 +718,7 @@ def send_logfile(logtype):
@
admi
.
route
(
"/get_update_status"
,
methods
=
[
'GET'
])
@
login_required_if_no_ano
def
get_update_status
():
log
.
info
(
u"Update status requested"
)
return
updater_thread
.
get_available_updates
(
request
.
method
,
locale
=
get_locale
())
...
...
cps/config_sql.py
View file @
1da4efec
...
...
@@ -38,7 +38,7 @@ class _Settings(_Base):
__tablename__
=
'settings'
id
=
Column
(
Integer
,
primary_key
=
True
)
mail_server
=
Column
(
String
,
default
=
'mail.example.org'
)
mail_server
=
Column
(
String
,
default
=
constants
.
DEFAULT_MAIL_SERVER
)
mail_port
=
Column
(
Integer
,
default
=
25
)
mail_use_ssl
=
Column
(
SmallInteger
,
default
=
0
)
mail_login
=
Column
(
String
,
default
=
'mail@example.com'
)
...
...
@@ -193,6 +193,10 @@ class _ConfigSQL(object):
def
get_mail_settings
(
self
):
return
{
k
:
v
for
k
,
v
in
self
.
__dict__
.
items
()
if
k
.
startswith
(
'mail_'
)}
def
get_mail_server_configured
(
self
):
return
not
bool
(
self
.
mail_server
==
constants
.
DEFAULT_MAIL_SERVER
)
def
set_from_dictionary
(
self
,
dictionary
,
field
,
convertor
=
None
,
default
=
None
):
'''Possibly updates a field of this object.
The new value, if present, is grabbed from the given dictionary, and optionally passed through a convertor.
...
...
cps/constants.py
View file @
1da4efec
...
...
@@ -94,6 +94,7 @@ LOGIN_LDAP = 1
LOGIN_OAUTH
=
2
# LOGIN_OAUTH_GOOGLE = 3
DEFAULT_MAIL_SERVER
=
"mail.example.org"
DEFAULT_PASSWORD
=
"admin123"
DEFAULT_PORT
=
8083
...
...
@@ -105,6 +106,7 @@ except ValueError:
del
env_CALIBRE_PORT
EXTENSIONS_AUDIO
=
{
'mp3'
,
'm4a'
,
'm4b'
}
EXTENSIONS_CONVERT
=
{
'pdf'
,
'epub'
,
'mobi'
,
'azw3'
,
'docx'
,
'rtf'
,
'fb2'
,
'lit'
,
'lrf'
,
'txt'
,
'htmlz'
,
'rtf'
,
'odt'
}
EXTENSIONS_UPLOAD
=
{
'txt'
,
'pdf'
,
'epub'
,
'mobi'
,
'azw'
,
'azw3'
,
'cbr'
,
'cbz'
,
'cbt'
,
'djvu'
,
'prc'
,
'doc'
,
'docx'
,
...
...
cps/helper.py
View file @
1da4efec
...
...
@@ -125,7 +125,7 @@ def send_registration_mail(e_mail, user_name, default_password, resend=False):
if
not
resend
:
text
+=
"Your new account at Calibre-Web has been created. Thanks for joining us!
\r\n
"
text
+=
"Please log in to your account using the following informations:
\r\n
"
text
+=
"User name:
%
s
\n
"
%
user_name
text
+=
"User name:
%
s
\
r\
n
"
%
user_name
text
+=
"Password:
%
s
\r\n
"
%
default_password
text
+=
"Don't forget to change your password after first login.
\r\n
"
text
+=
"Sincerely
\r\n\r\n
"
...
...
@@ -416,6 +416,8 @@ def reset_password(user_id):
existing_user
=
ub
.
session
.
query
(
ub
.
User
)
.
filter
(
ub
.
User
.
id
==
user_id
)
.
first
()
password
=
generate_random_password
()
existing_user
.
password
=
generate_password_hash
(
password
)
if
not
config
.
get_mail_server_configured
():
return
(
2
,
None
)
try
:
ub
.
session
.
commit
()
send_registration_mail
(
existing_user
.
email
,
existing_user
.
nickname
,
password
,
True
)
...
...
@@ -735,9 +737,13 @@ def speaking_language(languages=None):
# from https://code.luasoftware.com/tutorials/flask/execute-raw-sql-in-flask-sqlalchemy/
def
check_valid_domain
(
domain_text
):
domain_text
=
domain_text
.
split
(
'@'
,
1
)[
-
1
]
.
lower
()
sql
=
"SELECT * FROM registration WHERE
:domain LIKE domain
;"
sql
=
"SELECT * FROM registration WHERE
(:domain LIKE domain and allow = 1)
;"
result
=
ub
.
session
.
query
(
ub
.
Registration
)
.
from_statement
(
text
(
sql
))
.
params
(
domain
=
domain_text
)
.
all
()
return
len
(
result
)
if
not
len
(
result
):
return
False
sql
=
"SELECT * FROM registration WHERE (:domain LIKE domain and allow = 0);"
result
=
ub
.
session
.
query
(
ub
.
Registration
)
.
from_statement
(
text
(
sql
))
.
params
(
domain
=
domain_text
)
.
all
()
return
not
len
(
result
)
# Orders all Authors in the list according to authors sort
...
...
cps/opds.py
View file @
1da4efec
...
...
@@ -382,11 +382,12 @@ def feed_get_cover(book_id):
@
requires_basic_auth_if_no_ano
def
feed_read_books
():
off
=
request
.
args
.
get
(
"offset"
)
or
0
re
turn
render_read_books
(
int
(
off
)
/
(
int
(
config
.
config_books_per_page
))
+
1
,
True
,
True
)
re
sult
,
pagination
=
render_read_books
(
int
(
off
)
/
(
int
(
config
.
config_books_per_page
))
+
1
,
True
,
True
)
return
render_xml_template
(
'feed.xml'
,
entries
=
result
,
pagination
=
pagination
)
@
opds
.
route
(
"/opds/unreadbooks"
)
@
requires_basic_auth_if_no_ano
def
feed_unread_books
():
off
=
request
.
args
.
get
(
"offset"
)
or
0
return
render_read_books
(
int
(
off
)
/
(
int
(
config
.
config_books_per_page
))
+
1
,
False
,
True
)
result
,
pagination
=
render_read_books
(
int
(
off
)
/
(
int
(
config
.
config_books_per_page
))
+
1
,
False
,
True
)
return
render_xml_template
(
'feed.xml'
,
entries
=
result
,
pagination
=
pagination
)
cps/server.py
View file @
1da4efec
...
...
@@ -24,7 +24,7 @@ import signal
import
socket
try
:
from
gevent.pywsgi
import
WSGIServer
from
gevent.py
s
wsgi
import
WSGIServer
from
gevent.pool
import
Pool
from
gevent
import
__version__
as
_version
VERSION
=
'Gevent '
+
_version
...
...
cps/static/css/main.css
View file @
1da4efec
...
...
@@ -134,7 +134,6 @@ body {
user-select
:
none
;
padding-top
:
160px
;
padding-bottom
:
160px
;
padding-right
:
80px
;
}
.arrow
:hover
{
...
...
cps/static/js/table.js
View file @
1da4efec
...
...
@@ -19,21 +19,41 @@
$
(
function
()
{
$
(
"#domain_submit"
).
click
(
function
(
event
)
{
$
(
"#domain_
allow_
submit"
).
click
(
function
(
event
)
{
event
.
preventDefault
();
$
(
"#domain_add"
).
ajaxForm
();
$
(
"#domain_add
_allow
"
).
ajaxForm
();
$
(
this
).
closest
(
"form"
).
submit
();
$
.
ajax
({
method
:
"get"
,
url
:
window
.
location
.
pathname
+
"/../../ajax/domainlist"
,
url
:
window
.
location
.
pathname
+
"/../../ajax/domainlist
/1
"
,
async
:
true
,
timeout
:
900
,
success
:
function
(
data
)
{
$
(
"#domain-table"
).
bootstrapTable
(
"load"
,
data
);
$
(
"#domain-
allow-
table"
).
bootstrapTable
(
"load"
,
data
);
}
});
});
$
(
"#domain-table"
).
bootstrapTable
({
$
(
"#domain-allow-table"
).
bootstrapTable
({
formatNoMatches
:
function
()
{
return
""
;
},
striped
:
false
});
$
(
"#domain_deny_submit"
).
click
(
function
(
event
)
{
event
.
preventDefault
();
$
(
"#domain_add_deny"
).
ajaxForm
();
$
(
this
).
closest
(
"form"
).
submit
();
$
.
ajax
({
method
:
"get"
,
url
:
window
.
location
.
pathname
+
"/../../ajax/domainlist/0"
,
async
:
true
,
timeout
:
900
,
success
:
function
(
data
)
{
$
(
"#domain-deny-table"
).
bootstrapTable
(
"load"
,
data
);
}
});
});
$
(
"#domain-deny-table"
).
bootstrapTable
({
formatNoMatches
:
function
()
{
return
""
;
},
...
...
@@ -50,14 +70,22 @@ $(function() {
$
(
"#DeleteDomain"
).
modal
(
"hide"
);
$
.
ajax
({
method
:
"get"
,
url
:
window
.
location
.
pathname
+
"/../../ajax/domainlist"
,
url
:
window
.
location
.
pathname
+
"/../../ajax/domainlist
/1
"
,
async
:
true
,
timeout
:
900
,
success
:
function
(
data
)
{
$
(
"#domain-table"
).
bootstrapTable
(
"load"
,
data
);
$
(
"#domain-allow-table"
).
bootstrapTable
(
"load"
,
data
);
}
});
$
.
ajax
({
method
:
"get"
,
url
:
window
.
location
.
pathname
+
"/../../ajax/domainlist/0"
,
async
:
true
,
timeout
:
900
,
success
:
function
(
data
)
{
$
(
"#domain-deny-table"
).
bootstrapTable
(
"load"
,
data
);
}
});
});
//triggered when modal is about to be shown
$
(
"#DeleteDomain"
).
on
(
"show.bs.modal"
,
function
(
e
)
{
...
...
cps/templates/email_edit.html
View file @
1da4efec
...
...
@@ -41,22 +41,40 @@
</form>
{% if g.allow_registration %}
<h2>
{{_('Allowed domains for registering')}}
</h2>
<table
class=
"table table-no-bordered"
id=
"domain-table"
data-url=
"{{url_for('admin.list_domain')}}"
data-id-field=
"id"
data-show-header=
"false"
data-editable-mode=
"inline"
>
<form
id=
"domain_add_allow"
action=
"{{ url_for('admin.add_domain',allow=1)}}"
method=
"POST"
>
<div
class=
"form-group required"
>
<label
for=
"domainname_allow"
>
{{_('Add Domain')}}
</label>
<input
type=
"text"
class=
"form-control"
name=
"domainname"
id=
"domainname_allow"
>
</div>
<button
id=
"domain_allow_submit"
class=
"btn btn-default"
>
{{_('Add')}}
</button>
</form>
<table
class=
"table table-no-bordered"
id=
"domain-allow-table"
data-url=
"{{url_for('admin.list_domain', allow=1)}}"
data-id-field=
"id"
data-show-header=
"false"
data-editable-mode=
"inline"
>
<thead>
<tr>
<th
data-field=
"domain"
id=
"domain-allow"
data-editable-type=
"text"
data-editable-url=
"{{ url_for('admin.edit_domain', allow = 1)}}"
data-editable=
"true"
data-editable-title=
"{{_('Enter domainname')}}"
></th>
<th
data-field=
"id"
id=
"id-allow"
data-visible=
"false"
></th>
<th
data-align=
"right"
data-formatter=
"TableActions"
></th>
</tr>
</thead>
</table>
<h2>
{{_('Denied domains for registering')}}
</h2>
<table
class=
"table table-no-bordered"
id=
"domain-deny-table"
data-url=
"{{url_for('admin.list_domain', allow=0)}}"
data-id-field=
"id"
data-show-header=
"false"
data-editable-mode=
"inline"
>
<thead>
<tr>
<th
data-field=
"domain"
id=
"domain
"
data-editable-type=
"text"
data-editable-url=
"{{ url_for('admin.edit_domain'
)}}"
data-editable=
"true"
data-editable-title=
"{{_('Enter domainname')}}"
></th>
<th
data-field=
"id"
id=
"id"
data-visible=
"false"
></th>
<th
data-field=
"domain"
id=
"domain
-deny"
data-editable-type=
"text"
data-editable-url=
"{{ url_for('admin.edit_domain', allow = 0
)}}"
data-editable=
"true"
data-editable-title=
"{{_('Enter domainname')}}"
></th>
<th
data-field=
"id"
id=
"id
-deny
"
data-visible=
"false"
></th>
<th
data-align=
"right"
data-formatter=
"TableActions"
></th>
</tr>
</thead>
</table>
<form
id=
"domain_add
"
action=
"{{ url_for('admin.add_domain'
)}}"
method=
"POST"
>
<form
id=
"domain_add
_deny"
action=
"{{ url_for('admin.add_domain',allow=0
)}}"
method=
"POST"
>
<div
class=
"form-group required"
>
<label
for=
"domainname"
>
{{_('Add Domain')}}
</label>
<input
type=
"text"
class=
"form-control"
name=
"domainname"
id=
"domainname"
>
<label
for=
"domainname
_deny
"
>
{{_('Add Domain')}}
</label>
<input
type=
"text"
class=
"form-control"
name=
"domainname"
id=
"domainname
_deny
"
>
</div>
<button
id=
"domain_submit"
class=
"btn btn-default"
>
{{_('Add')}}
</button>
<button
id=
"domain_
deny_
submit"
class=
"btn btn-default"
>
{{_('Add')}}
</button>
</form>
{% endif %}
</div>
{% endblock %}
...
...
cps/templates/user_edit.html
View file @
1da4efec
...
...
@@ -14,7 +14,7 @@
<input
type=
"email"
class=
"form-control"
name=
"email"
id=
"email"
value=
"{{ content.email if content.email != None }}"
autocomplete=
"off"
>
</div>
{% if ( g.user and g.user.role_passwd() or g.user.role_admin() ) and not content.role_anonymous() %}
{% if g.user and g.user.role_admin() and not new_user and not profile and ( mail_configured and content.email if content.email != None
)
%}
{% if g.user and g.user.role_admin() and not new_user and not profile and ( mail_configured and content.email if content.email != None %}
<div
class=
"btn btn-default"
id=
"resend_password"
><a
href=
"{{url_for('admin.reset_user_password', user_id = content.id) }}"
>
{{_('Reset user Password')}}
</a></div>
{% endif %}
<div
class=
"form-group"
>
...
...
@@ -22,7 +22,6 @@
<input
type=
"password"
class=
"form-control"
name=
"password"
id=
"password"
value=
""
autocomplete=
"off"
>
</div>
{% endif %}
{% endif %}
<div
class=
"form-group"
>
<label
for=
"kindle_mail"
>
{{_('Kindle E-Mail')}}
</label>
<input
type=
"email"
class=
"form-control"
name=
"kindle_mail"
id=
"kindle_mail"
value=
"{{ content.kindle_mail if content.kindle_mail != None }}"
>
...
...
cps/ub.py
View file @
1da4efec
...
...
@@ -324,6 +324,7 @@ class Registration(Base):
id
=
Column
(
Integer
,
primary_key
=
True
)
domain
=
Column
(
String
)
allow
=
Column
(
Integer
)
def
__repr__
(
self
):
return
u"<Registration('{0}')>"
.
format
(
self
.
domain
)
...
...
@@ -359,24 +360,32 @@ def migrate_Database(session):
if
not
engine
.
dialect
.
has_table
(
engine
.
connect
(),
"registration"
):
ReadBook
.
__table__
.
create
(
bind
=
engine
)
conn
=
engine
.
connect
()
conn
.
execute
(
"insert into registration (domain) values('
%
.
%
')"
)
conn
.
execute
(
"insert into registration (domain, allow) values('
%
.
%
',1)"
)
session
.
commit
()
try
:
session
.
query
(
exists
()
.
where
(
Registration
.
allow
))
.
scalar
()
session
.
commit
()
except
exc
.
OperationalError
:
# Database is not compatible, some columns are missing
conn
=
engine
.
connect
()
conn
.
execute
(
"ALTER TABLE registration ADD column 'allow' INTEGER"
)
conn
.
execute
(
"update registration set 'allow' = 1"
)
session
.
commit
()
# Handle table exists, but no content
cnt
=
session
.
query
(
Registration
)
.
count
()
if
not
cnt
:
conn
=
engine
.
connect
()
conn
.
execute
(
"insert into registration (domain
) values('
%
.
%
'
)"
)
conn
.
execute
(
"insert into registration (domain
, allow) values('
%
.
%
',1
)"
)
session
.
commit
()
try
:
session
.
query
(
exists
()
.
where
(
BookShelf
.
order
))
.
scalar
()
except
exc
.
OperationalError
:
# Database is not compatible, some
row
s are missing
except
exc
.
OperationalError
:
# Database is not compatible, some
column
s are missing
conn
=
engine
.
connect
()
conn
.
execute
(
"ALTER TABLE book_shelf_link ADD column 'order' INTEGER DEFAULT 1"
)
session
.
commit
()
try
:
create
=
False
session
.
query
(
exists
()
.
where
(
User
.
sidebar_view
))
.
scalar
()
except
exc
.
OperationalError
:
# Database is not compatible, some
row
s are missing
except
exc
.
OperationalError
:
# Database is not compatible, some
column
s are missing
conn
=
engine
.
connect
()
conn
.
execute
(
"ALTER TABLE user ADD column `sidebar_view` Integer DEFAULT 1"
)
session
.
commit
()
...
...
cps/web.py
View file @
1da4efec
This diff is collapsed.
Click to expand it.
cps/worker.py
View file @
1da4efec
...
...
@@ -231,7 +231,7 @@ class WorkerThread(threading.Thread):
self
.
queue
.
pop
(
index
)
self
.
UIqueue
.
pop
(
index
)
# if we are deleting entries before the current index, adjust the index
if
index
<=
self
.
current
and
index
:
if
index
<=
self
.
current
and
self
.
current
:
self
.
current
-=
1
self
.
last
=
len
(
self
.
queue
)
...
...
test/Calibre-Web TestSummary.html
View file @
1da4efec
This diff is collapsed.
Click to expand it.
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