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
24c743d2
Commit
24c743d2
authored
Apr 19, 2020
by
Ozzieisaacs
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Code cosmetics
parent
7bb5afa5
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
262 additions
and
192 deletions
+262
-192
cli.py
cps/cli.py
+1
-1
db.py
cps/db.py
+1
-1
helper.py
cps/helper.py
+81
-55
jinjia.py
cps/jinjia.py
+5
-1
kobo.py
cps/kobo.py
+12
-5
logger.py
cps/logger.py
+1
-1
oauth.py
cps/oauth.py
+2
-2
opds.py
cps/opds.py
+43
-21
server.py
cps/server.py
+2
-2
SyncToken.py
cps/services/SyncToken.py
+7
-5
shelf.py
cps/shelf.py
+32
-27
subproc_wrapper.py
cps/subproc_wrapper.py
+5
-5
list.html
cps/templates/list.html
+6
-6
ub.py
cps/ub.py
+59
-55
updater.py
cps/updater.py
+5
-5
No files found.
cps/cli.py
View file @
24c743d2
cps/db.py
View file @
24c743d2
...
@@ -25,7 +25,7 @@ import ast
...
@@ -25,7 +25,7 @@ import ast
from
sqlalchemy
import
create_engine
from
sqlalchemy
import
create_engine
from
sqlalchemy
import
Table
,
Column
,
ForeignKey
from
sqlalchemy
import
Table
,
Column
,
ForeignKey
from
sqlalchemy
import
String
,
Integer
,
Boolean
,
TIMESTAMP
,
Float
from
sqlalchemy
import
String
,
Integer
,
Boolean
,
TIMESTAMP
,
Float
,
DateTime
from
sqlalchemy.orm
import
relationship
,
sessionmaker
,
scoped_session
from
sqlalchemy.orm
import
relationship
,
sessionmaker
,
scoped_session
from
sqlalchemy.ext.declarative
import
declarative_base
from
sqlalchemy.ext.declarative
import
declarative_base
...
...
cps/helper.py
View file @
24c743d2
This diff is collapsed.
Click to expand it.
cps/jinjia.py
View file @
24c743d2
...
@@ -80,9 +80,13 @@ def formatdate_filter(val):
...
@@ -80,9 +80,13 @@ def formatdate_filter(val):
formatdate
=
datetime
.
datetime
.
strptime
(
conformed_timestamp
[:
15
],
"
%
Y
%
m
%
d
%
H
%
M
%
S"
)
formatdate
=
datetime
.
datetime
.
strptime
(
conformed_timestamp
[:
15
],
"
%
Y
%
m
%
d
%
H
%
M
%
S"
)
return
format_date
(
formatdate
,
format
=
'medium'
,
locale
=
get_locale
())
return
format_date
(
formatdate
,
format
=
'medium'
,
locale
=
get_locale
())
except
AttributeError
as
e
:
except
AttributeError
as
e
:
log
.
error
(
'Babel error:
%
s, Current user locale:
%
s, Current User:
%
s'
,
e
,
current_user
.
locale
,
current_user
.
nickname
)
log
.
error
(
'Babel error:
%
s, Current user locale:
%
s, Current User:
%
s'
,
e
,
current_user
.
locale
,
current_user
.
nickname
)
return
formatdate
return
formatdate
@
jinjia
.
app_template_filter
(
'formatdateinput'
)
@
jinjia
.
app_template_filter
(
'formatdateinput'
)
def
format_date_input
(
val
):
def
format_date_input
(
val
):
conformed_timestamp
=
re
.
sub
(
r"[:]|([-](?!((\d{2}[:]\d{2})|(\d{4}))$))"
,
''
,
val
)
conformed_timestamp
=
re
.
sub
(
r"[:]|([-](?!((\d{2}[:]\d{2})|(\d{4}))$))"
,
''
,
val
)
...
...
cps/kobo.py
View file @
24c743d2
...
@@ -385,7 +385,7 @@ def get_metadata(book):
...
@@ -385,7 +385,7 @@ def get_metadata(book):
name
=
get_series
(
book
)
name
=
get_series
(
book
)
metadata
[
"Series"
]
=
{
metadata
[
"Series"
]
=
{
"Name"
:
get_series
(
book
),
"Name"
:
get_series
(
book
),
"Number"
:
book
.
series_index
,
"Number"
:
book
.
series_index
,
# ToDo Check int() ?
"NumberFloat"
:
float
(
book
.
series_index
),
"NumberFloat"
:
float
(
book
.
series_index
),
# Get a deterministic id based on the series name.
# Get a deterministic id based on the series name.
"Id"
:
uuid
.
uuid3
(
uuid
.
NAMESPACE_DNS
,
name
),
"Id"
:
uuid
.
uuid3
(
uuid
.
NAMESPACE_DNS
,
name
),
...
@@ -407,8 +407,10 @@ def HandleTagCreate():
...
@@ -407,8 +407,10 @@ def HandleTagCreate():
log
.
debug
(
"Received malformed v1/library/tags request."
)
log
.
debug
(
"Received malformed v1/library/tags request."
)
abort
(
400
,
description
=
"Malformed tags POST request. Data is missing 'Name' or 'Items' field"
)
abort
(
400
,
description
=
"Malformed tags POST request. Data is missing 'Name' or 'Items' field"
)
# ToDO: Names are not unique ! -> filter only private shelfs
shelf
=
ub
.
session
.
query
(
ub
.
Shelf
)
.
filter
(
and_
(
ub
.
Shelf
.
name
)
==
name
,
ub
.
Shelf
.
user_id
==
shelf
=
ub
.
session
.
query
(
ub
.
Shelf
)
.
filter
(
and_
(
ub
.
Shelf
.
name
)
==
name
,
ub
.
Shelf
.
user_id
==
current_user
.
id
)
.
one_or_none
()
current_user
.
id
)
.
one_or_none
()
# ToDO: shouldn't it ) at the end
if
shelf
and
not
shelf_lib
.
check_shelf_edit_permissions
(
shelf
):
if
shelf
and
not
shelf_lib
.
check_shelf_edit_permissions
(
shelf
):
abort
(
401
,
description
=
"User is unauthaurized to edit shelf."
)
abort
(
401
,
description
=
"User is unauthaurized to edit shelf."
)
...
@@ -517,6 +519,7 @@ def HandleTagRemoveItem(tag_id):
...
@@ -517,6 +519,7 @@ def HandleTagRemoveItem(tag_id):
log
.
debug
(
"Received malformed v1/library/tags/<tag_id>/items/delete request."
)
log
.
debug
(
"Received malformed v1/library/tags/<tag_id>/items/delete request."
)
abort
(
400
,
description
=
"Malformed tags POST request. Data is missing 'Items' field"
)
abort
(
400
,
description
=
"Malformed tags POST request. Data is missing 'Items' field"
)
# insconsitent to above requests
shelf
=
ub
.
session
.
query
(
ub
.
Shelf
)
.
filter
(
ub
.
Shelf
.
uuid
==
tag_id
,
shelf
=
ub
.
session
.
query
(
ub
.
Shelf
)
.
filter
(
ub
.
Shelf
.
uuid
==
tag_id
,
ub
.
Shelf
.
user_id
==
current_user
.
id
)
.
one_or_none
()
ub
.
Shelf
.
user_id
==
current_user
.
id
)
.
one_or_none
()
if
not
shelf
:
if
not
shelf
:
...
@@ -552,7 +555,8 @@ def HandleTagRemoveItem(tag_id):
...
@@ -552,7 +555,8 @@ def HandleTagRemoveItem(tag_id):
def
sync_shelves
(
sync_token
,
sync_results
):
def
sync_shelves
(
sync_token
,
sync_results
):
new_tags_last_modified
=
sync_token
.
tags_last_modified
new_tags_last_modified
=
sync_token
.
tags_last_modified
for
shelf
in
ub
.
session
.
query
(
ub
.
ShelfArchive
)
.
filter
(
func
.
datetime
(
ub
.
ShelfArchive
.
last_modified
)
>
sync_token
.
tags_last_modified
,
ub
.
ShelfArchive
.
user_id
==
current_user
.
id
):
for
shelf
in
ub
.
session
.
query
(
ub
.
ShelfArchive
)
.
filter
(
func
.
datetime
(
ub
.
ShelfArchive
.
last_modified
)
>
sync_token
.
tags_last_modified
,
ub
.
ShelfArchive
.
user_id
==
current_user
.
id
):
new_tags_last_modified
=
max
(
shelf
.
last_modified
,
new_tags_last_modified
)
new_tags_last_modified
=
max
(
shelf
.
last_modified
,
new_tags_last_modified
)
sync_results
.
append
({
sync_results
.
append
({
...
@@ -564,7 +568,8 @@ def sync_shelves(sync_token, sync_results):
...
@@ -564,7 +568,8 @@ def sync_shelves(sync_token, sync_results):
}
}
})
})
for
shelf
in
ub
.
session
.
query
(
ub
.
Shelf
)
.
filter
(
func
.
datetime
(
ub
.
Shelf
.
last_modified
)
>
sync_token
.
tags_last_modified
,
ub
.
Shelf
.
user_id
==
current_user
.
id
):
for
shelf
in
ub
.
session
.
query
(
ub
.
Shelf
)
.
filter
(
func
.
datetime
(
ub
.
Shelf
.
last_modified
)
>
sync_token
.
tags_last_modified
,
ub
.
Shelf
.
user_id
==
current_user
.
id
):
if
not
shelf_lib
.
check_shelf_view_permissions
(
shelf
):
if
not
shelf_lib
.
check_shelf_view_permissions
(
shelf
):
continue
continue
...
@@ -600,6 +605,7 @@ def create_kobo_tag(shelf):
...
@@ -600,6 +605,7 @@ def create_kobo_tag(shelf):
book
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book_shelf
.
book_id
)
.
one_or_none
()
book
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book_shelf
.
book_id
)
.
one_or_none
()
if
not
book
:
if
not
book
:
log
.
info
(
u"Book (id:
%
s) in BookShelf (id:
%
s) not found in book database"
,
book_shelf
.
book_id
,
shelf
.
id
)
log
.
info
(
u"Book (id:
%
s) in BookShelf (id:
%
s) not found in book database"
,
book_shelf
.
book_id
,
shelf
.
id
)
# ToDo shouldn't it continue?
return
None
return
None
tag
[
"Items"
]
.
append
(
tag
[
"Items"
]
.
append
(
{
{
...
@@ -769,7 +775,8 @@ def HandleCoverImageRequest(book_uuid, width, height,Quality, isGreyscale):
...
@@ -769,7 +775,8 @@ def HandleCoverImageRequest(book_uuid, width, height,Quality, isGreyscale):
height
=
height
),
307
)
height
=
height
),
307
)
else
:
else
:
log
.
debug
(
"Cover for unknown book:
%
s requested"
%
book_uuid
)
log
.
debug
(
"Cover for unknown book:
%
s requested"
%
book_uuid
)
return
redirect_or_proxy_request
()
# additional proxy request make no sense, -> direct return
return
make_response
(
jsonify
({}))
log
.
debug
(
"Cover request received for book
%
s"
%
book_uuid
)
log
.
debug
(
"Cover request received for book
%
s"
%
book_uuid
)
return
book_cover
return
book_cover
...
...
cps/logger.py
View file @
24c743d2
cps/oauth.py
View file @
24c743d2
cps/opds.py
View file @
24c743d2
This diff is collapsed.
Click to expand it.
cps/server.py
View file @
24c743d2
...
@@ -43,7 +43,6 @@ from . import logger
...
@@ -43,7 +43,6 @@ from . import logger
log
=
logger
.
create
()
log
=
logger
.
create
()
def
_readable_listen_address
(
address
,
port
):
def
_readable_listen_address
(
address
,
port
):
if
':'
in
address
:
if
':'
in
address
:
address
=
"["
+
address
+
"]"
address
=
"["
+
address
+
"]"
...
@@ -84,7 +83,8 @@ class WebServer(object):
...
@@ -84,7 +83,8 @@ class WebServer(object):
if
os
.
path
.
isfile
(
certfile_path
)
and
os
.
path
.
isfile
(
keyfile_path
):
if
os
.
path
.
isfile
(
certfile_path
)
and
os
.
path
.
isfile
(
keyfile_path
):
self
.
ssl_args
=
dict
(
certfile
=
certfile_path
,
keyfile
=
keyfile_path
)
self
.
ssl_args
=
dict
(
certfile
=
certfile_path
,
keyfile
=
keyfile_path
)
else
:
else
:
log
.
warning
(
'The specified paths for the ssl certificate file and/or key file seem to be broken. Ignoring ssl.'
)
log
.
warning
(
'The specified paths for the ssl certificate file and/or key file seem to be broken. '
'Ignoring ssl.'
)
log
.
warning
(
'Cert path:
%
s'
,
certfile_path
)
log
.
warning
(
'Cert path:
%
s'
,
certfile_path
)
log
.
warning
(
'Key path:
%
s'
,
keyfile_path
)
log
.
warning
(
'Key path:
%
s'
,
keyfile_path
)
...
...
cps/services/SyncToken.py
View file @
24c743d2
...
@@ -49,10 +49,11 @@ def get_datetime_from_json(json_object, field_name):
...
@@ -49,10 +49,11 @@ def get_datetime_from_json(json_object, field_name):
return
datetime
.
min
return
datetime
.
min
class
SyncToken
()
:
class
SyncToken
:
""" The SyncToken is used to persist state accross requests.
""" The SyncToken is used to persist state accross requests.
When serialized over the response headers, the Kobo device will propagate the token onto following requests to the service.
When serialized over the response headers, the Kobo device will propagate the token onto following
As an example use-case, the SyncToken is used to detect books that have been added to the library since the last time the device synced to the server.
requests to the service. As an example use-case, the SyncToken is used to detect books that have been added
to the library since the last time the device synced to the server.
Attributes:
Attributes:
books_last_created: Datetime representing the newest book that the device knows about.
books_last_created: Datetime representing the newest book that the device knows about.
...
@@ -66,10 +67,11 @@ class SyncToken():
...
@@ -66,10 +67,11 @@ class SyncToken():
token_schema
=
{
token_schema
=
{
"type"
:
"object"
,
"type"
:
"object"
,
"properties"
:
{
"version"
:
{
"type"
:
"string"
},
"data"
:
{
"type"
:
"object"
},},
"properties"
:
{
"version"
:
{
"type"
:
"string"
},
"data"
:
{
"type"
:
"object"
},
},
}
}
# This Schema doesn't contain enough information to detect and propagate book deletions from Calibre to the device.
# This Schema doesn't contain enough information to detect and propagate book deletions from Calibre to the device.
# A potential solution might be to keep a list of all known book uuids in the token, and look for any missing from the db.
# A potential solution might be to keep a list of all known book uuids in the token, and look for any missing
# from the db.
data_schema_v1
=
{
data_schema_v1
=
{
"type"
:
"object"
,
"type"
:
"object"
,
"properties"
:
{
"properties"
:
{
...
...
cps/shelf.py
View file @
24c743d2
...
@@ -25,7 +25,7 @@ from __future__ import division, print_function, unicode_literals
...
@@ -25,7 +25,7 @@ from __future__ import division, print_function, unicode_literals
from
flask
import
Blueprint
,
request
,
flash
,
redirect
,
url_for
from
flask
import
Blueprint
,
request
,
flash
,
redirect
,
url_for
from
flask_babel
import
gettext
as
_
from
flask_babel
import
gettext
as
_
from
flask_login
import
login_required
,
current_user
from
flask_login
import
login_required
,
current_user
from
sqlalchemy.sql.expression
import
func
,
or_
,
and_
from
sqlalchemy.sql.expression
import
func
from
.
import
logger
,
ub
,
searched_ids
,
db
from
.
import
logger
,
ub
,
searched_ids
,
db
from
.web
import
render_title_template
from
.web
import
render_title_template
...
@@ -35,6 +35,7 @@ from .helper import common_filters
...
@@ -35,6 +35,7 @@ from .helper import common_filters
shelf
=
Blueprint
(
'shelf'
,
__name__
)
shelf
=
Blueprint
(
'shelf'
,
__name__
)
log
=
logger
.
create
()
log
=
logger
.
create
()
def
check_shelf_edit_permissions
(
cur_shelf
):
def
check_shelf_edit_permissions
(
cur_shelf
):
if
not
cur_shelf
.
is_public
and
not
cur_shelf
.
user_id
==
int
(
current_user
.
id
):
if
not
cur_shelf
.
is_public
and
not
cur_shelf
.
user_id
==
int
(
current_user
.
id
):
log
.
error
(
"User
%
s not allowed to edit shelf
%
s"
,
current_user
,
cur_shelf
)
log
.
error
(
"User
%
s not allowed to edit shelf
%
s"
,
current_user
,
cur_shelf
)
...
@@ -195,7 +196,6 @@ def remove_from_shelf(shelf_id, book_id):
...
@@ -195,7 +196,6 @@ def remove_from_shelf(shelf_id, book_id):
return
"Sorry you are not allowed to remove a book from this shelf:
%
s"
%
shelf
.
name
,
403
return
"Sorry you are not allowed to remove a book from this shelf:
%
s"
%
shelf
.
name
,
403
@
shelf
.
route
(
"/shelf/create"
,
methods
=
[
"GET"
,
"POST"
])
@
shelf
.
route
(
"/shelf/create"
,
methods
=
[
"GET"
,
"POST"
])
@
login_required
@
login_required
def
create_shelf
():
def
create_shelf
():
...
@@ -214,21 +214,24 @@ def create_shelf():
...
@@ -214,21 +214,24 @@ def create_shelf():
.
first
()
is
None
.
first
()
is
None
if
not
is_shelf_name_unique
:
if
not
is_shelf_name_unique
:
flash
(
_
(
u"A public shelf with the name '
%(title)
s' already exists."
,
title
=
to_save
[
"title"
]),
category
=
"error"
)
flash
(
_
(
u"A public shelf with the name '
%(title)
s' already exists."
,
title
=
to_save
[
"title"
]),
category
=
"error"
)
else
:
else
:
is_shelf_name_unique
=
ub
.
session
.
query
(
ub
.
Shelf
)
\
is_shelf_name_unique
=
ub
.
session
.
query
(
ub
.
Shelf
)
\
.
filter
((
ub
.
Shelf
.
name
==
to_save
[
"title"
])
&
(
ub
.
Shelf
.
is_public
==
0
)
&
(
ub
.
Shelf
.
user_id
==
int
(
current_user
.
id
)))
\
.
filter
((
ub
.
Shelf
.
name
==
to_save
[
"title"
])
&
(
ub
.
Shelf
.
is_public
==
0
)
&
(
ub
.
Shelf
.
user_id
==
int
(
current_user
.
id
)))
\
.
first
()
is
None
.
first
()
is
None
if
not
is_shelf_name_unique
:
if
not
is_shelf_name_unique
:
flash
(
_
(
u"A private shelf with the name '
%(title)
s' already exists."
,
title
=
to_save
[
"title"
]),
category
=
"error"
)
flash
(
_
(
u"A private shelf with the name '
%(title)
s' already exists."
,
title
=
to_save
[
"title"
]),
category
=
"error"
)
if
is_shelf_name_unique
:
if
is_shelf_name_unique
:
try
:
try
:
ub
.
session
.
add
(
shelf
)
ub
.
session
.
add
(
shelf
)
ub
.
session
.
commit
()
ub
.
session
.
commit
()
flash
(
_
(
u"Shelf
%(title)
s created"
,
title
=
to_save
[
"title"
]),
category
=
"success"
)
flash
(
_
(
u"Shelf
%(title)
s created"
,
title
=
to_save
[
"title"
]),
category
=
"success"
)
return
redirect
(
url_for
(
'shelf.show_shelf'
,
shelf_id
=
shelf
.
id
))
return
redirect
(
url_for
(
'shelf.show_shelf'
,
shelf_id
=
shelf
.
id
))
except
Exception
:
except
Exception
:
flash
(
_
(
u"There was an error"
),
category
=
"error"
)
flash
(
_
(
u"There was an error"
),
category
=
"error"
)
return
render_title_template
(
'shelf_edit.html'
,
shelf
=
shelf
,
title
=
_
(
u"Create a Shelf"
),
page
=
"shelfcreate"
)
return
render_title_template
(
'shelf_edit.html'
,
shelf
=
shelf
,
title
=
_
(
u"Create a Shelf"
),
page
=
"shelfcreate"
)
...
@@ -251,15 +254,18 @@ def edit_shelf(shelf_id):
...
@@ -251,15 +254,18 @@ def edit_shelf(shelf_id):
.
first
()
is
None
.
first
()
is
None
if
not
is_shelf_name_unique
:
if
not
is_shelf_name_unique
:
flash
(
_
(
u"A public shelf with the name '
%(title)
s' already exists."
,
title
=
to_save
[
"title"
]),
category
=
"error"
)
flash
(
_
(
u"A public shelf with the name '
%(title)
s' already exists."
,
title
=
to_save
[
"title"
]),
category
=
"error"
)
else
:
else
:
is_shelf_name_unique
=
ub
.
session
.
query
(
ub
.
Shelf
)
\
is_shelf_name_unique
=
ub
.
session
.
query
(
ub
.
Shelf
)
\
.
filter
((
ub
.
Shelf
.
name
==
to_save
[
"title"
])
&
(
ub
.
Shelf
.
is_public
==
0
)
&
(
ub
.
Shelf
.
user_id
==
int
(
current_user
.
id
)))
\
.
filter
((
ub
.
Shelf
.
name
==
to_save
[
"title"
])
&
(
ub
.
Shelf
.
is_public
==
0
)
&
.
filter
(
ub
.
Shelf
.
id
!=
shelf_id
)
\
(
ub
.
Shelf
.
user_id
==
int
(
current_user
.
id
)))
\
.
filter
(
ub
.
Shelf
.
id
!=
shelf_id
)
\
.
first
()
is
None
.
first
()
is
None
if
not
is_shelf_name_unique
:
if
not
is_shelf_name_unique
:
flash
(
_
(
u"A private shelf with the name '
%(title)
s' already exists."
,
title
=
to_save
[
"title"
]),
category
=
"error"
)
flash
(
_
(
u"A private shelf with the name '
%(title)
s' already exists."
,
title
=
to_save
[
"title"
]),
category
=
"error"
)
if
is_shelf_name_unique
:
if
is_shelf_name_unique
:
shelf
.
name
=
to_save
[
"title"
]
shelf
.
name
=
to_save
[
"title"
]
...
@@ -283,7 +289,7 @@ def delete_shelf_helper(cur_shelf):
...
@@ -283,7 +289,7 @@ def delete_shelf_helper(cur_shelf):
shelf_id
=
cur_shelf
.
id
shelf_id
=
cur_shelf
.
id
ub
.
session
.
delete
(
cur_shelf
)
ub
.
session
.
delete
(
cur_shelf
)
ub
.
session
.
query
(
ub
.
BookShelf
)
.
filter
(
ub
.
BookShelf
.
shelf
==
shelf_id
)
.
delete
()
ub
.
session
.
query
(
ub
.
BookShelf
)
.
filter
(
ub
.
BookShelf
.
shelf
==
shelf_id
)
.
delete
()
ub
.
session
.
add
(
ub
.
ShelfArchive
(
uuid
=
cur_shelf
.
uuid
,
user_id
=
cur_shelf
.
uuid
))
ub
.
session
.
add
(
ub
.
ShelfArchive
(
uuid
=
cur_shelf
.
uuid
,
user_id
=
cur_shelf
.
uuid
))
ub
.
session
.
commit
()
ub
.
session
.
commit
()
log
.
info
(
"successfully deleted
%
s"
,
cur_shelf
)
log
.
info
(
"successfully deleted
%
s"
,
cur_shelf
)
...
@@ -295,7 +301,7 @@ def delete_shelf(shelf_id):
...
@@ -295,7 +301,7 @@ def delete_shelf(shelf_id):
delete_shelf_helper
(
cur_shelf
)
delete_shelf_helper
(
cur_shelf
)
return
redirect
(
url_for
(
'web.index'
))
return
redirect
(
url_for
(
'web.index'
))
# @shelf.route("/shelfdown/<int:shelf_id>")
@
shelf
.
route
(
"/shelf/<int:shelf_id>"
,
defaults
=
{
'shelf_type'
:
1
})
@
shelf
.
route
(
"/shelf/<int:shelf_id>"
,
defaults
=
{
'shelf_type'
:
1
})
@
shelf
.
route
(
"/shelf/<int:shelf_id>/<int:shelf_type>"
)
@
shelf
.
route
(
"/shelf/<int:shelf_id>/<int:shelf_type>"
)
def
show_shelf
(
shelf_type
,
shelf_id
):
def
show_shelf
(
shelf_type
,
shelf_id
):
...
@@ -325,7 +331,6 @@ def show_shelf(shelf_type, shelf_id):
...
@@ -325,7 +331,6 @@ def show_shelf(shelf_type, shelf_id):
return
redirect
(
url_for
(
"web.index"
))
return
redirect
(
url_for
(
"web.index"
))
@
shelf
.
route
(
"/shelf/order/<int:shelf_id>"
,
methods
=
[
"GET"
,
"POST"
])
@
shelf
.
route
(
"/shelf/order/<int:shelf_id>"
,
methods
=
[
"GET"
,
"POST"
])
@
login_required
@
login_required
def
order_shelf
(
shelf_id
):
def
order_shelf
(
shelf_id
):
...
@@ -347,17 +352,17 @@ def order_shelf(shelf_id):
...
@@ -347,17 +352,17 @@ def order_shelf(shelf_id):
for
book
in
books_in_shelf2
:
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
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book
.
book_id
)
.
filter
(
common_filters
())
.
first
()
if
cur_book
:
if
cur_book
:
result
.
append
({
'title'
:
cur_book
.
title
,
result
.
append
({
'title'
:
cur_book
.
title
,
'id'
:
cur_book
.
id
,
'id'
:
cur_book
.
id
,
'author'
:
cur_book
.
authors
,
'author'
:
cur_book
.
authors
,
'series'
:
cur_book
.
series
,
'series'
:
cur_book
.
series
,
'series_index'
:
cur_book
.
series_index
})
'series_index'
:
cur_book
.
series_index
})
else
:
else
:
cur_book
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book
.
book_id
)
.
first
()
cur_book
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book
.
book_id
)
.
first
()
result
.
append
({
'title'
:
_
(
'Hidden Book'
),
result
.
append
({
'title'
:
_
(
'Hidden Book'
),
'id'
:
cur_book
.
id
,
'id'
:
cur_book
.
id
,
'author'
:[],
'author'
:
[],
'series'
:[]})
'series'
:
[]})
return
render_title_template
(
'shelf_order.html'
,
entries
=
result
,
return
render_title_template
(
'shelf_order.html'
,
entries
=
result
,
title
=
_
(
u"Change order of Shelf: '
%(name)
s'"
,
name
=
shelf
.
name
),
title
=
_
(
u"Change order of Shelf: '
%(name)
s'"
,
name
=
shelf
.
name
),
shelf
=
shelf
,
page
=
"shelforder"
)
shelf
=
shelf
,
page
=
"shelforder"
)
cps/subproc_wrapper.py
View file @
24c743d2
...
@@ -45,10 +45,10 @@ def process_open(command, quotes=(), env=None, sout=subprocess.PIPE, serr=subpro
...
@@ -45,10 +45,10 @@ def process_open(command, quotes=(), env=None, sout=subprocess.PIPE, serr=subpro
def
process_wait
(
command
,
serr
=
subprocess
.
PIPE
):
def
process_wait
(
command
,
serr
=
subprocess
.
PIPE
):
'''Run command, wait for process to terminate, and return an iterator over lines of its output.'''
# Run command, wait for process to terminate, and return an iterator over lines of its output.
p
=
process_open
(
command
,
serr
=
serr
)
p
=
process_open
(
command
,
serr
=
serr
)
p
.
wait
()
p
.
wait
()
for
l
in
p
.
stdout
.
readlines
():
for
l
ine
in
p
.
stdout
.
readlines
():
if
isinstance
(
l
,
bytes
):
if
isinstance
(
l
ine
,
bytes
):
l
=
l
.
decode
(
'utf-8'
)
l
ine
=
line
.
decode
(
'utf-8'
)
yield
l
yield
l
ine
cps/templates/list.html
View file @
24c743d2
...
@@ -4,18 +4,18 @@
...
@@ -4,18 +4,18 @@
<div
class=
"filterheader hidden-xs hidden-sm"
>
<div
class=
"filterheader hidden-xs hidden-sm"
>
{% if entries.__len__() %}
{% if entries.__len__() %}
{% if
entries[0][0].sort
%}
{% if
data == 'author'
%}
<button
id=
"sort_name"
class=
"btn btn-
success
"
><b>
B,A
<->
A B
</b></button>
<button
id=
"sort_name"
class=
"btn btn-
primary
"
><b>
B,A
<->
A B
</b></button>
{% endif %}
{% endif %}
{% endif %}
{% endif %}
<button
id=
"desc"
class=
"btn btn-
success
"
><span
class=
"glyphicon glyphicon-sort-by-alphabet"
></span></button>
<button
id=
"desc"
class=
"btn btn-
primary
"
><span
class=
"glyphicon glyphicon-sort-by-alphabet"
></span></button>
<button
id=
"asc"
class=
"btn btn-
success
"
><span
class=
"glyphicon glyphicon-sort-by-alphabet-alt"
></span></button>
<button
id=
"asc"
class=
"btn btn-
primary
"
><span
class=
"glyphicon glyphicon-sort-by-alphabet-alt"
></span></button>
{% if charlist|length %}
{% if charlist|length %}
<button
id=
"all"
class=
"btn btn-
success
"
>
{{_('All')}}
</button>
<button
id=
"all"
class=
"btn btn-
primary
"
>
{{_('All')}}
</button>
{% endif %}
{% endif %}
<div
class=
"btn-group character"
role=
"group"
>
<div
class=
"btn-group character"
role=
"group"
>
{% for char in charlist%}
{% for char in charlist%}
<button
class=
"btn btn-
success
char"
>
{{char.char}}
</button>
<button
class=
"btn btn-
primary
char"
>
{{char.char}}
</button>
{% endfor %}
{% endfor %}
</div>
</div>
</div>
</div>
...
...
cps/ub.py
View file @
24c743d2
This diff is collapsed.
Click to expand it.
cps/updater.py
View file @
24c743d2
...
@@ -69,7 +69,7 @@ class Updater(threading.Thread):
...
@@ -69,7 +69,7 @@ class Updater(threading.Thread):
def
get_available_updates
(
self
,
request_method
,
locale
):
def
get_available_updates
(
self
,
request_method
,
locale
):
if
config
.
config_updatechannel
==
constants
.
UPDATE_STABLE
:
if
config
.
config_updatechannel
==
constants
.
UPDATE_STABLE
:
return
self
.
_stable_available_updates
(
request_method
)
return
self
.
_stable_available_updates
(
request_method
)
return
self
.
_nightly_available_updates
(
request_method
,
locale
)
return
self
.
_nightly_available_updates
(
request_method
,
locale
)
def
do_work
(
self
):
def
do_work
(
self
):
try
:
try
:
...
@@ -132,7 +132,7 @@ class Updater(threading.Thread):
...
@@ -132,7 +132,7 @@ class Updater(threading.Thread):
def
pause
(
self
):
def
pause
(
self
):
self
.
can_run
.
clear
()
self
.
can_run
.
clear
()
#should just resume the thread
#
should just resume the thread
def
resume
(
self
):
def
resume
(
self
):
self
.
can_run
.
set
()
self
.
can_run
.
set
()
...
@@ -268,7 +268,7 @@ class Updater(threading.Thread):
...
@@ -268,7 +268,7 @@ class Updater(threading.Thread):
def
is_venv
(
self
):
def
is_venv
(
self
):
if
(
hasattr
(
sys
,
'real_prefix'
))
or
(
hasattr
(
sys
,
'base_prefix'
)
and
sys
.
base_prefix
!=
sys
.
prefix
):
if
(
hasattr
(
sys
,
'real_prefix'
))
or
(
hasattr
(
sys
,
'base_prefix'
)
and
sys
.
base_prefix
!=
sys
.
prefix
):
return
os
.
sep
+
os
.
path
.
relpath
(
sys
.
prefix
,
constants
.
BASE_DIR
)
return
os
.
sep
+
os
.
path
.
relpath
(
sys
.
prefix
,
constants
.
BASE_DIR
)
else
:
else
:
return
False
return
False
...
@@ -436,7 +436,7 @@ class Updater(threading.Thread):
...
@@ -436,7 +436,7 @@ class Updater(threading.Thread):
patch_version_update
>
current_version
[
2
])
or
\
patch_version_update
>
current_version
[
2
])
or
\
minor_version_update
>
current_version
[
1
]:
minor_version_update
>
current_version
[
1
]:
parents
.
append
([
commit
[
i
][
'tag_name'
],
commit
[
i
][
'body'
]
.
replace
(
'
\r\n
'
,
'<p>'
)])
parents
.
append
([
commit
[
i
][
'tag_name'
],
commit
[
i
][
'body'
]
.
replace
(
'
\r\n
'
,
'<p>'
)])
newer
=
True
newer
=
True
i
-=
1
i
-=
1
continue
continue
if
major_version_update
<
current_version
[
0
]:
if
major_version_update
<
current_version
[
0
]:
...
...
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