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
a09a2d9e
Commit
a09a2d9e
authored
Feb 23, 2017
by
idalin
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' into prod
parents
80e6311b
2853ed14
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
81 additions
and
39 deletions
+81
-39
cps.py
cps.py
+2
-2
db.py
cps/db.py
+20
-0
helper.py
cps/helper.py
+13
-11
detail.html
cps/templates/detail.html
+8
-1
search_form.html
cps/templates/search_form.html
+16
-12
web.py
cps/web.py
+22
-13
No files found.
cps.py
View file @
a09a2d9e
...
...
@@ -22,8 +22,8 @@ if __name__ == '__main__':
IOLoop
.
instance
()
.
start
()
if
web
.
helper
.
global_task
==
0
:
print
(
"Performing restart of Calibre-web"
)
web
.
app
.
logger
.
info
(
"Performing restart of Calibre-web"
)
os
.
execl
(
sys
.
executable
,
sys
.
executable
,
*
sys
.
argv
)
else
:
print
(
"Performing shutdown of Calibre-web"
)
web
.
app
.
logger
.
info
(
"Performing shutdown of Calibre-web"
)
sys
.
exit
(
0
)
cps/db.py
View file @
a09a2d9e
...
...
@@ -56,6 +56,10 @@ books_languages_link = Table('books_languages_link', Base.metadata,
Column
(
'lang_code'
,
Integer
,
ForeignKey
(
'languages.id'
),
primary_key
=
True
)
)
books_publishers_link
=
Table
(
'books_publishers_link'
,
Base
.
metadata
,
Column
(
'book'
,
Integer
,
ForeignKey
(
'books.id'
),
primary_key
=
True
),
Column
(
'publisher'
,
Integer
,
ForeignKey
(
'publishers.id'
),
primary_key
=
True
)
)
class
Identifiers
(
Base
):
__tablename__
=
'identifiers'
...
...
@@ -182,6 +186,21 @@ class Languages(Base):
def
__repr__
(
self
):
return
u"<Languages('{0}')>"
.
format
(
self
.
lang_code
)
class
Publishers
(
Base
):
__tablename__
=
'publishers'
id
=
Column
(
Integer
,
primary_key
=
True
)
name
=
Column
(
String
)
sort
=
Column
(
String
)
def
__init__
(
self
,
name
,
sort
):
self
.
name
=
name
self
.
sort
=
sort
def
__repr__
(
self
):
return
u"<Publishers('{0},{1}')>"
.
format
(
self
.
name
,
self
.
sort
)
class
Data
(
Base
):
__tablename__
=
'data'
...
...
@@ -224,6 +243,7 @@ class Books(Base):
series
=
relationship
(
'Series'
,
secondary
=
books_series_link
,
backref
=
'books'
)
ratings
=
relationship
(
'Ratings'
,
secondary
=
books_ratings_link
,
backref
=
'books'
)
languages
=
relationship
(
'Languages'
,
secondary
=
books_languages_link
,
backref
=
'books'
)
publishers
=
relationship
(
'Publishers'
,
secondary
=
books_publishers_link
,
backref
=
'books'
)
identifiers
=
relationship
(
'Identifiers'
,
backref
=
'books'
)
def
__init__
(
self
,
title
,
sort
,
author_sort
,
timestamp
,
pubdate
,
series_index
,
last_modified
,
path
,
has_cover
,
...
...
cps/helper.py
View file @
a09a2d9e
...
...
@@ -338,7 +338,7 @@ class Updater(threading.Thread):
def
reduce_files
(
self
,
remove_items
,
exclude_items
):
rf
=
[]
for
item
in
remove_items
:
if
not
item
in
exclude_items
:
if
not
item
.
startswith
(
exclude_items
)
:
rf
.
append
(
item
)
return
rf
...
...
@@ -347,15 +347,14 @@ class Updater(threading.Thread):
if
sys
.
platform
==
"win32"
or
sys
.
platform
==
"darwin"
:
change_permissions
=
False
else
:
app
.
logger
.
debug
(
'Update on OS-System : '
+
sys
.
platform
)
# print('OS-System: '+sys.platform )
logging
.
getLogger
(
'cps.web'
)
.
debug
(
'Update on OS-System : '
+
sys
.
platform
)
new_permissions
=
os
.
stat
(
root_dst_dir
)
# print new_permissions
for
src_dir
,
dirs
,
files
in
os
.
walk
(
root_src_dir
):
dst_dir
=
src_dir
.
replace
(
root_src_dir
,
root_dst_dir
,
1
)
if
not
os
.
path
.
exists
(
dst_dir
):
os
.
makedirs
(
dst_dir
)
# print
('Create-Dir: '+dst_dir)
logging
.
getLogger
(
'cps.web'
)
.
debug
(
'Create-Dir: '
+
dst_dir
)
if
change_permissions
:
# print('Permissions: User '+str(new_permissions.st_uid)+' Group '+str(new_permissions.st_uid))
os
.
chown
(
dst_dir
,
new_permissions
.
st_uid
,
new_permissions
.
st_gid
)
...
...
@@ -365,27 +364,28 @@ class Updater(threading.Thread):
if
os
.
path
.
exists
(
dst_file
):
if
change_permissions
:
permission
=
os
.
stat
(
dst_file
)
# print
('Remove file before copy: '+dst_file)
logging
.
getLogger
(
'cps.web'
)
.
debug
(
'Remove file before copy: '
+
dst_file
)
os
.
remove
(
dst_file
)
else
:
if
change_permissions
:
permission
=
new_permissions
shutil
.
move
(
src_file
,
dst_dir
)
# print
('Move File '+src_file+' to '+dst_dir)
logging
.
getLogger
(
'cps.web'
)
.
debug
(
'Move File '
+
src_file
+
' to '
+
dst_dir
)
if
change_permissions
:
try
:
os
.
chown
(
dst_file
,
permission
.
st_uid
,
permission
.
st_uid
)
# print('Permissions: User '+str(new_permissions.st_uid)+' Group '+str(new_permissions.st_uid))
except
:
e
=
sys
.
exc_info
()
# print
('Fail '+str(dst_file)+' error: '+str(e))
logging
.
getLogger
(
'cps.web'
)
.
debug
(
'Fail '
+
str
(
dst_file
)
+
' error: '
+
str
(
e
))
return
def
update_source
(
self
,
source
,
destination
):
# destination files
old_list
=
list
()
exclude
=
(
[
'vendor'
+
os
.
sep
+
'kindlegen.exe'
,
'vendor'
+
os
.
sep
+
'kindlegen'
,
'/app.db'
,
'vendor'
,
'/update.py'
])
'vendor'
+
os
.
sep
+
'kindlegen.exe'
,
'vendor'
+
os
.
sep
+
'kindlegen'
,
os
.
sep
+
'app.db'
,
os
.
sep
+
'vendor'
,
os
.
sep
+
'calibre-web.log'
)
for
root
,
dirs
,
files
in
os
.
walk
(
destination
,
topdown
=
True
):
for
name
in
files
:
old_list
.
append
(
os
.
path
.
join
(
root
,
name
)
.
replace
(
destination
,
''
))
...
...
@@ -410,12 +410,14 @@ class Updater(threading.Thread):
for
item
in
remove_items
:
item_path
=
os
.
path
.
join
(
destination
,
item
[
1
:])
if
os
.
path
.
isdir
(
item_path
):
app
.
logger
.
debug
(
"Delete dir "
+
item_path
)
logging
.
getLogger
(
'cps.web'
)
.
debug
(
"Delete dir "
+
item_path
)
shutil
.
rmtree
(
item_path
)
else
:
try
:
app
.
logger
.
debug
(
"Delete file "
+
item_path
)
logging
.
getLogger
(
'cps.web'
)
.
debug
(
"Delete file "
+
item_path
)
log_from_thread
(
"Delete file "
+
item_path
)
os
.
remove
(
item_path
)
except
:
app
.
logger
.
debug
(
"Could not remove:"
+
item_path
)
logging
.
getLogger
(
'cps.web'
)
.
debug
(
"Could not remove:"
+
item_path
)
shutil
.
rmtree
(
source
,
ignore_errors
=
True
)
cps/templates/detail.html
View file @
a09a2d9e
...
...
@@ -50,6 +50,7 @@
{% if entry.identifiers|length > 0 %}
<div
class=
"identifiers"
>
<p>
<span
class=
"glyphicon glyphicon-link"
></span>
{% for identifier in entry.identifiers %}
<a
href=
"{{identifier}}"
target=
"_blank"
class=
"btn btn-xs btn-success"
role=
"button"
>
{{identifier.formatType()}}
</a>
...
...
@@ -66,10 +67,16 @@
{% for tag in entry.tags %}
<a
href=
"{{ url_for('category', id=tag.id) }}"
class=
"btn btn-xs btn-info"
role=
"button"
>
{{tag.name}}
</a>
{%endfor%}
</div>
</p>
{% endif %}
{% if entry.publishers|length > 0 %}
<div
class=
"publishers"
>
<p>
<span>
{{_('Publisher')}}:{% for publisher in entry.publishers %} {{publisher.name}}{% if not loop.last %},{% endif %}{% endfor %}
</span>
</p>
</div>
{% endif %}
{% if entry.pubdate[:10] != '0101-01-01' %}
<p>
{{_('Publishing date')}}: {{entry.pubdate|formatdate}}
</p>
{% endif %}
...
...
cps/templates/search_form.html
View file @
a09a2d9e
...
...
@@ -10,63 +10,67 @@
<label
for=
"bookAuthor"
>
{{_('Author')}}
</label>
<input
type=
"text"
class=
"form-control typeahead"
name=
"author_name"
id=
"bookAuthor"
value=
""
autocomplete=
"off"
>
</div>
<label
for=
"Tags"
>
{{_('Tags')}}
</label>
<div
class=
"form-group"
>
<label
for=
"Publisher"
>
{{_('Publisher')}}
</label>
<input
type=
"text"
class=
"form-control"
name=
"publisher"
id=
"publisher"
value=
""
>
</div>
<label
for=
"include_tag"
>
{{_('Tags')}}
</label>
<div
class=
"form-group"
id=
"test"
>
<div
class=
"btn-toolbar btn-toolbar-lg"
data-toggle=
"buttons"
>
{% for tag in tags %}
<label
id=
"tag_{{tag.id}}"
class=
"btn btn-primary tags_click"
>
<input
type=
"checkbox"
autocomplete=
"off"
name=
"include_tag"
value=
"{{tag.id}}"
>
{{tag.name}}
</input>
<input
type=
"checkbox"
autocomplete=
"off"
name=
"include_tag"
id=
"include_tag"
value=
"{{tag.id}}"
>
{{tag.name}}
</input>
</label>
{% endfor %}
</div>
</div>
<label
for=
"
Tags
"
>
{{_('Exclude Tags')}}
</label>
<label
for=
"
exclude_tag
"
>
{{_('Exclude Tags')}}
</label>
<div
class=
"form-group"
>
<div
class=
"btn-toolbar btn-toolbar-lg"
data-toggle=
"buttons"
>
{% for tag in tags %}
<label
id=
"tag_{{tag.id}}"
class=
"btn btn-danger tags_click"
>
<input
type=
"checkbox"
autocomplete=
"off"
name=
"exclude_tag"
value=
"{{tag.id}}"
>
{{tag.name}}
</input>
<input
type=
"checkbox"
autocomplete=
"off"
name=
"exclude_tag"
id=
"exclude_tag"
value=
"{{tag.id}}"
>
{{tag.name}}
</input>
</label>
{% endfor %}
</div>
</div>
<label
for=
"
Series
"
>
{{_('Series')}}
</label>
<label
for=
"
include_serie
"
>
{{_('Series')}}
</label>
<div
class=
"form-group"
>
<div
class=
"btn-toolbar btn-toolbar-lg"
data-toggle=
"buttons"
>
{% for serie in series %}
<label
id=
"serie_{{serie.id}}"
class=
"btn btn-primary serie_click"
>
<input
type=
"checkbox"
autocomplete=
"off"
name=
"include_serie"
value=
"{{serie.id}}"
>
{{serie.name}}
</input>
<input
type=
"checkbox"
autocomplete=
"off"
name=
"include_serie"
id=
"include_serie"
value=
"{{serie.id}}"
>
{{serie.name}}
</input>
</label>
{% endfor %}
</div>
</div>
<label
for=
"
Series
"
>
{{_('Exclude Series')}}
</label>
<label
for=
"
exclude_serie
"
>
{{_('Exclude Series')}}
</label>
<div
class=
"form-group"
>
<div
class=
"btn-toolbar btn-toolbar-lg"
data-toggle=
"buttons"
>
{% for serie in series %}
<label
id=
"serie_{{serie.id}}"
class=
"btn btn-danger serie_click"
>
<input
type=
"checkbox"
autocomplete=
"off"
name=
"exclude_serie"
value=
"{{serie.id}}"
>
{{serie.name}}
</input>
<input
type=
"checkbox"
autocomplete=
"off"
name=
"exclude_serie"
id=
"exclude_serie"
value=
"{{serie.id}}"
>
{{serie.name}}
</input>
</label>
{% endfor %}
</div>
</div>
{% if languages %}
<label
for=
"
Languages
"
>
{{_('Languages')}}
</label>
<label
for=
"
include_language
"
>
{{_('Languages')}}
</label>
<div
class=
"form-group"
>
<div
class=
"btn-toolbar btn-toolbar-lg"
data-toggle=
"buttons"
>
{% for language in languages %}
<label
id=
"language_{{language.id}}"
class=
"btn btn-primary serie_click"
>
<input
type=
"checkbox"
autocomplete=
"off"
name=
"include_language"
value=
"{{language.id}}"
>
{{language.name}}
</input>
<input
type=
"checkbox"
autocomplete=
"off"
name=
"include_language"
id=
"include_language"
value=
"{{language.id}}"
>
{{language.name}}
</input>
</label>
{% endfor %}
</div>
</div>
<label
for=
"
Languages
"
>
{{_('Exclude Languages')}}
</label>
<label
for=
"
exclude_language
"
>
{{_('Exclude Languages')}}
</label>
<div
class=
"form-group"
>
<div
class=
"btn-toolbar btn-toolbar-lg"
data-toggle=
"buttons"
>
{% for language in languages %}
<label
id=
"language_{{language.id}}"
class=
"btn btn-danger language_click"
>
<input
type=
"checkbox"
autocomplete=
"off"
name=
"exclude_language"
value=
"{{language.id}}"
>
{{language.name}}
</input>
<input
type=
"checkbox"
autocomplete=
"off"
name=
"exclude_language"
id=
"exclude_language"
value=
"{{language.id}}"
>
{{language.name}}
</input>
</label>
{% endfor %}
</div>
...
...
cps/web.py
View file @
a09a2d9e
...
...
@@ -473,8 +473,10 @@ def feed_search(term):
filter
=
True
if
term
:
entries
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
or_
(
db
.
Books
.
tags
.
any
(
db
.
Tags
.
name
.
like
(
"
%
"
+
term
+
"
%
"
)),
db
.
Books
.
authors
.
any
(
db
.
Authors
.
name
.
like
(
"
%
"
+
term
+
"
%
"
)),
db
.
Books
.
title
.
like
(
"
%
"
+
term
+
"
%
"
)))
.
filter
(
filter
)
.
all
()
db
.
Books
.
series
.
any
(
db
.
Series
.
name
.
like
(
"
%
"
+
term
+
"
%
"
)),
db
.
Books
.
authors
.
any
(
db
.
Authors
.
name
.
like
(
"
%
"
+
term
+
"
%
"
)),
db
.
Books
.
publishers
.
any
(
db
.
Publishers
.
name
.
like
(
"
%
"
+
term
+
"
%
"
)),
db
.
Books
.
title
.
like
(
"
%
"
+
term
+
"
%
"
)))
.
filter
(
filter
)
.
all
()
entriescount
=
len
(
entries
)
if
len
(
entries
)
>
0
else
1
pagination
=
Pagination
(
1
,
entriescount
,
entriescount
)
xml
=
render_title_template
(
'feed.xml'
,
searchterm
=
term
,
entries
=
entries
,
pagination
=
pagination
)
...
...
@@ -744,7 +746,10 @@ def get_updater_status():
helper
.
updater_thread
.
start
()
status
[
'status'
]
=
helper
.
updater_thread
.
get_update_status
()
elif
request
.
method
==
"GET"
:
status
[
'status'
]
=
helper
.
updater_thread
.
get_update_status
()
try
:
status
[
'status'
]
=
helper
.
updater_thread
.
get_update_status
()
except
:
status
[
'status'
]
=
7
return
json
.
dumps
(
status
)
...
...
@@ -1044,9 +1049,9 @@ def stats():
@
login_required
@
admin_required
def
shutdown
():
global
global_task
#
global global_task
task
=
int
(
request
.
args
.
get
(
"parameter"
)
.
strip
())
global_task
=
task
helper
.
global_task
=
task
if
task
==
1
or
task
==
0
:
# valid commandos received
# close all database connections
db
.
session
.
close
()
...
...
@@ -1084,9 +1089,10 @@ def search():
else
:
filter
=
True
entries
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
or_
(
db
.
Books
.
tags
.
any
(
db
.
Tags
.
name
.
like
(
"
%
"
+
term
+
"
%
"
)),
db
.
Books
.
series
.
any
(
db
.
Series
.
name
.
like
(
"
%
"
+
term
+
"
%
"
)),
db
.
Books
.
authors
.
any
(
db
.
Authors
.
name
.
like
(
"
%
"
+
term
+
"
%
"
)),
db
.
Books
.
title
.
like
(
"
%
"
+
term
+
"
%
"
)))
.
filter
(
filter
)
.
all
()
db
.
Books
.
series
.
any
(
db
.
Series
.
name
.
like
(
"
%
"
+
term
+
"
%
"
)),
db
.
Books
.
authors
.
any
(
db
.
Authors
.
name
.
like
(
"
%
"
+
term
+
"
%
"
)),
db
.
Books
.
publishers
.
any
(
db
.
Publishers
.
name
.
like
(
"
%
"
+
term
+
"
%
"
)),
db
.
Books
.
title
.
like
(
"
%
"
+
term
+
"
%
"
)))
.
filter
(
filter
)
.
all
()
return
render_title_template
(
'search.html'
,
searchterm
=
term
,
entries
=
entries
)
else
:
return
render_title_template
(
'search.html'
,
searchterm
=
""
)
...
...
@@ -1106,12 +1112,14 @@ def advanced_search():
author_name
=
request
.
args
.
get
(
"author_name"
)
book_title
=
request
.
args
.
get
(
"book_title"
)
publisher
=
request
.
args
.
get
(
"publisher"
)
if
author_name
:
author_name
=
author_name
.
strip
()
if
book_title
:
book_title
=
book_title
.
strip
()
if
publisher
:
publisher
=
publisher
.
strip
()
if
include_tag_inputs
or
exclude_tag_inputs
or
include_series_inputs
or
exclude_series_inputs
or
\
include_languages_inputs
or
exclude_languages_inputs
or
author_name
or
book_title
:
include_languages_inputs
or
exclude_languages_inputs
or
author_name
or
book_title
or
publisher
:
searchterm
=
[]
searchterm
.
extend
((
author_name
,
book_title
))
searchterm
.
extend
((
author_name
,
book_title
,
publisher
))
tag_names
=
db
.
session
.
query
(
db
.
Tags
)
.
filter
(
db
.
Tags
.
id
.
in_
(
include_tag_inputs
))
.
all
()
searchterm
.
extend
(
tag
.
name
for
tag
in
tag_names
)
# searchterm = " + ".join(filter(None, searchterm))
...
...
@@ -1127,7 +1135,8 @@ def advanced_search():
searchterm
.
extend
(
language
.
name
for
language
in
language_names
)
searchterm
=
" + "
.
join
(
filter
(
None
,
searchterm
))
q
=
q
.
filter
(
db
.
Books
.
authors
.
any
(
db
.
Authors
.
name
.
like
(
"
%
"
+
author_name
+
"
%
"
)),
db
.
Books
.
title
.
like
(
"
%
"
+
book_title
+
"
%
"
))
db
.
Books
.
title
.
like
(
"
%
"
+
book_title
+
"
%
"
),
db
.
Books
.
publishers
.
any
(
db
.
Publishers
.
name
.
like
(
"
%
"
+
publisher
+
"
%
"
)))
for
tag
in
include_tag_inputs
:
q
=
q
.
filter
(
db
.
Books
.
tags
.
any
(
db
.
Tags
.
id
==
tag
))
for
tag
in
exclude_tag_inputs
:
...
...
@@ -1611,7 +1620,7 @@ def basic_configuration():
def
configuration_helper
(
origin
):
global
global_task
#
global global_task
reboot_required
=
False
db_change
=
False
success
=
False
...
...
@@ -1686,7 +1695,7 @@ def configuration_helper(origin):
# stop tornado server
server
=
IOLoop
.
instance
()
server
.
add_callback
(
server
.
stop
)
global_task
=
0
helper
.
global_task
=
0
app
.
logger
.
info
(
'Reboot required, restarting'
)
if
origin
:
success
=
True
...
...
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