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
76c90748
Commit
76c90748
authored
Feb 27, 2017
by
Radosław Kierznowski
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'refs/remotes/janeczku/master'
parents
9ec5303f
679effba
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
221 additions
and
81 deletions
+221
-81
db.py
cps/db.py
+21
-1
epub.py
cps/epub.py
+14
-7
helper.py
cps/helper.py
+4
-0
main.js
cps/static/js/main.js
+4
-3
detail.html
cps/templates/detail.html
+10
-3
languages.html
cps/templates/languages.html
+7
-1
list.html
cps/templates/list.html
+6
-0
search_form.html
cps/templates/search_form.html
+16
-12
stats.html
cps/templates/stats.html
+57
-16
user_edit.html
cps/templates/user_edit.html
+9
-1
messages.mo
cps/translations/zh_Hans_CN/LC_MESSAGES/messages.mo
+0
-0
messages.po
cps/translations/zh_Hans_CN/LC_MESSAGES/messages.po
+24
-24
ub.py
cps/ub.py
+0
-1
web.py
cps/web.py
+49
-12
No files found.
cps/db.py
View file @
76c90748
...
...
@@ -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
,
...
...
@@ -274,7 +294,7 @@ def setup_db():
return
False
dbpath
=
os
.
path
.
join
(
config
.
config_calibre_dir
,
"metadata.db"
)
engine
=
create_engine
(
'sqlite:///{0}'
.
format
(
dbpath
.
encode
(
'utf-8'
)),
echo
=
False
)
engine
=
create_engine
(
'sqlite:///{0}'
.
format
(
dbpath
.
encode
(
'utf-8'
)),
echo
=
False
,
isolation_level
=
"SERIALIZABLE"
)
try
:
conn
=
engine
.
connect
()
...
...
cps/epub.py
View file @
76c90748
...
...
@@ -7,13 +7,14 @@ import os
import
uploader
def
extractCover
(
zip
,
coverFile
,
tmp_file_name
):
def
extractCover
(
zip
,
coverFile
,
coverpath
,
tmp_file_name
):
if
coverFile
is
None
:
return
None
else
:
cf
=
zip
.
read
(
"OPS/"
+
coverFile
)
zipCoverPath
=
os
.
path
.
join
(
coverpath
,
coverFile
)
.
replace
(
'
\\
'
,
'/'
)
cf
=
zip
.
read
(
zipCoverPath
)
prefix
=
os
.
path
.
splitext
(
tmp_file_name
)[
0
]
tmp_cover_name
=
prefix
+
"."
+
coverFile
tmp_cover_name
=
prefix
+
'.'
+
os
.
path
.
basename
(
zipCoverPath
)
image
=
open
(
tmp_cover_name
,
'wb'
)
image
.
write
(
cf
)
image
.
close
()
...
...
@@ -32,10 +33,11 @@ def get_epub_info(tmp_file_path, original_file_name, original_file_extension):
txt
=
zip
.
read
(
'META-INF/container.xml'
)
tree
=
etree
.
fromstring
(
txt
)
cfname
=
tree
.
xpath
(
'n:rootfiles/n:rootfile/@full-path'
,
namespaces
=
ns
)[
0
]
cf
=
zip
.
read
(
cfname
)
tree
=
etree
.
fromstring
(
cf
)
coverpath
=
os
.
path
.
dirname
(
cfname
)
p
=
tree
.
xpath
(
'/pkg:package/pkg:metadata'
,
namespaces
=
ns
)[
0
]
epub_metadata
=
{}
...
...
@@ -46,11 +48,16 @@ def get_epub_info(tmp_file_path, original_file_name, original_file_extension):
else
:
epub_metadata
[
s
]
=
"Unknown"
coversection
=
tree
.
xpath
(
"/pkg:package/pkg:manifest/pkg:item[@id='cover']/@href"
,
namespaces
=
ns
)
coversection
=
tree
.
xpath
(
"/pkg:package/pkg:manifest/pkg:item[@id='cover
-image
']/@href"
,
namespaces
=
ns
)
if
len
(
coversection
)
>
0
:
coverfile
=
extractCover
(
zip
,
coversection
[
0
],
tmp_file_path
)
coverfile
=
extractCover
(
zip
,
coversection
[
0
],
coverpath
,
tmp_file_path
)
else
:
coverfile
=
None
coversection
=
tree
.
xpath
(
"/pkg:package/pkg:manifest/pkg:item[@id='cover']/@href"
,
namespaces
=
ns
)
if
len
(
coversection
)
>
0
:
coverfile
=
extractCover
(
zip
,
coversection
[
0
],
coverpath
,
tmp_file_path
)
else
:
coverfile
=
None
if
epub_metadata
[
'title'
]
is
None
:
title
=
original_file_name
else
:
...
...
cps/helper.py
View file @
76c90748
...
...
@@ -19,6 +19,8 @@ from email.MIMEBase import MIMEBase
from
email.MIMEMultipart
import
MIMEMultipart
from
email.MIMEText
import
MIMEText
from
email.generator
import
Generator
from
email.utils
import
formatdate
from
email.utils
import
make_msgid
from
flask_babel
import
gettext
as
_
import
subprocess
import
threading
...
...
@@ -165,6 +167,8 @@ def send_mail(book_id, kindle_mail, calibrepath):
# create MIME message
msg
=
MIMEMultipart
()
msg
[
'Subject'
]
=
_
(
u'Send to Kindle'
)
msg
[
'Message-Id'
]
=
make_msgid
(
'calibre-web'
)
msg
[
'Date'
]
=
formatdate
(
localtime
=
True
)
text
=
_
(
u'This email has been sent via calibre web.'
)
msg
.
attach
(
MIMEText
(
text
.
encode
(
'UTF-8'
),
'plain'
,
'UTF-8'
))
...
...
cps/static/js/main.js
View file @
76c90748
...
...
@@ -36,7 +36,7 @@ $(function() {
success
:
function
(
data
)
{
$
(
'#spinner'
).
show
();
displaytext
=
data
.
text
;
window
.
setTimeout
(
restartTimer
,
3000
);}
setTimeout
(
restartTimer
,
3000
);}
});
});
$
(
"#shutdown"
).
click
(
function
()
{
...
...
@@ -50,7 +50,7 @@ $(function() {
});
$
(
"#check_for_update"
).
click
(
function
()
{
var
button_text
=
$
(
"#check_for_update"
).
html
();
$
(
"#check_for_update"
).
html
(
'
Checking
...'
);
$
(
"#check_for_update"
).
html
(
'...'
);
$
.
ajax
({
dataType
:
'json'
,
url
:
window
.
location
.
pathname
+
"/../../get_update_status"
,
...
...
@@ -110,7 +110,8 @@ function updateTimer() {
$
(
'#UpdateprogressDialog #updateFinished'
).
removeClass
(
'hidden'
);
$
(
"#check_for_update"
).
removeClass
(
'hidden'
);
$
(
"#perform_update"
).
addClass
(
'hidden'
);
}
},
timeout
:
2000
});
}
...
...
cps/templates/detail.html
View file @
76c90748
...
...
@@ -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 %}
...
...
@@ -125,10 +132,10 @@
</div>
{% endif %}
{% if g.user.is_authenticated %}
{% if g.user.kindle_mail %}
{% if g.user.kindle_mail and g.user.is_authenticated %}
<a
href=
"{{url_for('send_to_kindle', book_id=entry.id)}}"
id=
"sendbtn"
class=
"btn btn-primary"
role=
"button"
><span
class=
"glyphicon glyphicon-send"
></span>
{{_('Send to Kindle')}}
</a>
{% endif %}
{% if (g.user.role_download() and g.user.is_anonymous()) or g.user.is_authenticated %}
<div
class=
"btn-group"
role=
"group"
>
<button
id=
"btnGroupDrop2"
type=
"button"
class=
"btn btn-primary dropdown-toggle"
data-toggle=
"dropdown"
aria-haspopup=
"true"
aria-expanded=
"false"
>
<span
class=
"glyphicon glyphicon-eye-open"
></span>
{{_('Read in browser')}}
...
...
cps/templates/languages.html
View file @
76c90748
...
...
@@ -2,11 +2,17 @@
{% block body %}
<h1>
{{title}}
</h1>
<div
class=
"container"
>
<div
class=
"col-sm-6"
>
{% for lang in languages %}
{% if loop.index0 == (loop.length/2)|int and loop.length > 20 %}
</div>
<div
class=
"col-sm-6"
>
{% endif %}
<div
class=
"row"
>
<div
class=
"col-xs-1"
align=
"left"
><span
class=
"badge"
>
{{lang_counter[loop.index0].bookcount}}
</span></div>
<div
class=
"col-xs-6"
><a
id=
"list_{{loop.index0}}"
href=
"{{url_for('language', name=lang.lang_code)}}"
>
{{lang.name}}
</a></div>
</div>
{% endfor %}
</div>
</div>
</div>
{% endblock %}
cps/templates/list.html
View file @
76c90748
...
...
@@ -2,11 +2,17 @@
{% block body %}
<h1>
{{title}}
</h1>
<div
class=
"container"
>
<div
class=
"col-sm-6"
>
{% for entry in entries %}
{% if loop.index0 == (loop.length/2)|int and loop.length > 20 %}
</div>
<div
class=
"col-sm-6"
>
{% endif %}
<div
class=
"row"
>
<div
class=
"col-xs-1"
align=
"left"
><span
class=
"badge"
>
{{entry.count}}
</span></div>
<div
class=
"col-xs-6"
><a
id=
"list_{{loop.index0}}"
href=
"{{url_for(folder, id=entry[0].id )}}"
>
{{entry[0].name}}
</a></div>
</div>
{% endfor %}
</div>
</div>
{% endblock %}
cps/templates/search_form.html
View file @
76c90748
...
...
@@ -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/templates/stats.html
View file @
76c90748
{% extends "layout.html" %}
{% block body %}
<h3>
{{_('Calibre library statistics')}}
</h3>
<table
id=
"stats"
class=
"table"
>
<tbody>
<tr>
<th>
{{bookcounter}}
</th>
<td>
{{_('Books in this Library')}}
</td>
</tr>
<tr>
<th>
{{authorcounter}}
</th>
<td>
{{_('Authors in this Library')}}
</td>
</tr>
<tr>
<th>
{{categorycounter}}
</th>
<td>
{{_('Categories in this Library')}}
</td>
</tr>
<tr>
<th>
{{seriecounter}}
</th>
<td>
{{_('Series in this Library')}}
</td>
</tr>
</tbody>
</table>
<h3>
{{_('Linked libraries')}}
</h3>
<table
id=
"libs"
class=
"table"
>
<thead>
<tr>
...
...
@@ -24,30 +44,51 @@
</tr>
<tr>
<th>
PyPDF2
</th>
<td>
{{versions['PyPdfVersion']}}
</td>
<td>
v
{{versions['PyPdfVersion']}}
</td>
</tr>
</tbody>
</table>
<h3>
{{_('Calibre library statistics')}}
</h3>
<table
id=
"stats"
class=
"table"
>
<tbody>
<tr>
<th>
{{bookcounter}}
</th>
<td>
{{_('Books in this Library')
}}
</td>
<th>
Babel
</th>
<td>
v{{versions['babel']
}}
</td>
</tr>
<tr>
<th>
{{authorcounter}}
</th>
<td>
{{_('Authors in this Library')
}}
</td>
<th>
SqlAlchemy
</th>
<td>
v{{versions['sqlalchemy']
}}
</td>
</tr>
<tr>
<th>
{{categorycounter}}
</th>
<td>
{{_('Categories in this Library')
}}
</td>
<th>
Flask
</th>
<td>
v{{versions['flask']
}}
</td>
</tr>
<tr>
<th>
{{seriecounter}}
</th>
<td>
{{_('Series in this Library')}}
</td>
<th>
Flask Login
</th>
<td>
v{{versions['flasklogin']}}
</td>
</tr>
<tr>
<th>
Flask Principal
</th>
<td>
v{{versions['flask_principal']}}
</td>
</tr>
<tr>
<th>
Tornado web server
</th>
<td>
v{{versions['tornado']}}
</td>
</tr>
<tr>
<th>
ISO639 Languages
</th>
<td>
v{{versions['iso639']}}
</td>
</tr>
<tr>
<th>
Requests
</th>
<td>
v{{versions['requests']}}
</td>
</tr>
<tr>
<th>
SQlite
</th>
<td>
v{{versions['sqlite']}}
</td>
</tr>
<tr>
<th>
Pysqlite
</th>
<td>
v{{versions['pysqlite']}}
</td>
</tr>
</tbody>
</table>
{% endblock %}
cps/templates/user_edit.html
View file @
76c90748
...
...
@@ -40,6 +40,8 @@
{% endfor %}
</select>
</div>
<div
class=
"col-sm-6"
>
<div
class=
"form-group"
>
<input
type=
"checkbox"
name=
"show_random"
id=
"show_random"
{%
if
content
.
show_random_books
()
%}
checked
{%
endif
%}
>
<label
for=
"show_random"
>
{{_('Show random books')}}
</label>
...
...
@@ -72,7 +74,8 @@
<input
type=
"checkbox"
name=
"show_detail_random"
id=
"show_detail_random"
{%
if
content
.
show_detail_random
()
%}
checked
{%
endif
%}
>
<label
for=
"show_detail_random"
>
{{_('Show random books in detail view')}}
</label>
</div>
</div>
<div
class=
"col-sm-6"
>
{% if g.user and g.user.role_admin() and not profile %}
{% if not content.role_anonymous() %}
<div
class=
"form-group"
>
...
...
@@ -106,13 +109,17 @@
</label>
</div>
{% endif %}
</div>
<div
class=
"col-sm-12"
>
<button
type=
"submit"
id=
"submit"
class=
"btn btn-default"
>
{{_('Submit')}}
</button>
{% if not profile %}
<a
href=
"{{ url_for('admin') }}"
id=
"back"
class=
"btn btn-default"
>
{{_('Back')}}
</a>
</div>
{% endif %}
</form>
{% if downloads %}
<div
class=
"col-sm-12"
>
<h2>
{{_('Recent Downloads')}}
</h2>
{% for entry in downloads %}
<div
class=
"col-sm-2"
>
...
...
@@ -121,6 +128,7 @@
</a>
</div>
{% endfor %}
</div>
{% endif %}
</div>
{% endblock %}
cps/translations/zh_Hans_CN/LC_MESSAGES/messages.mo
View file @
76c90748
No preview for this file type
cps/translations/zh_Hans_CN/LC_MESSAGES/messages.po
View file @
76c90748
...
...
@@ -61,31 +61,31 @@ msgstr "游客"
#: cps/web.py:734
msgid "Requesting update package"
msgstr ""
msgstr "
正在请求更新包
"
#: cps/web.py:735
msgid "Downloading update package"
msgstr ""
msgstr "
正在下载更新包
"
#: cps/web.py:736
msgid "Unzipping update package"
msgstr ""
msgstr "
正在解压更新包
"
#: cps/web.py:737
msgid "Files are replaced"
msgstr ""
msgstr "
文件已替换
"
#: cps/web.py:738
msgid "Database connections are closed"
msgstr ""
msgstr "
数据库连接已关闭
"
#: cps/web.py:739
msgid "Server is stopped"
msgstr ""
msgstr "
服务器已停止
"
#: cps/web.py:740
msgid "Update finished, please press okay and reload page"
msgstr ""
msgstr "
更新完成,请按确定并刷新页面
"
#: cps/web.py:810
msgid "Latest Books"
...
...
@@ -97,7 +97,7 @@ msgstr "热门书籍(最多下载)"
#: cps/web.py:845
msgid "Best rated books"
msgstr ""
msgstr "
最高评分书籍
"
#: cps/templates/index.xml:36 cps/web.py:854
msgid "Random Books"
...
...
@@ -108,9 +108,9 @@ msgid "Author list"
msgstr "作者列表"
#: cps/web.py:878
#, python-forma
t
#, python-forma
msgid "Author: %(name)s"
msgstr ""
msgstr "
作者: %(name)s
"
#: cps/web.py:880 cps/web.py:908 cps/web.py:1007 cps/web.py:1235
#: cps/web.py:2115
...
...
@@ -150,7 +150,7 @@ msgstr "统计"
#: cps/web.py:1061
msgid "Server restarted, please reload page"
msgstr ""
msgstr "
服务器已重启,请刷新页面
"
#: cps/web.py:1063
msgid "Performing shutdown of server, please close window"
...
...
@@ -158,7 +158,7 @@ msgstr "正在关闭服务器,请关闭窗口"
#: cps/web.py:1073
msgid "Update done"
msgstr ""
msgstr "
更新完成
"
#: cps/web.py:1147 cps/web.py:1160
msgid "search"
...
...
@@ -475,11 +475,11 @@ msgstr "管理"
#: cps/templates/admin.html:80
msgid "Current commit timestamp"
msgstr ""
msgstr "
当前提交时间戳
"
#: cps/templates/admin.html:81
msgid "Newest commit timestamp"
msgstr ""
msgstr "
最新提交时间戳
"
#: cps/templates/admin.html:83
msgid "Restart Calibre-web"
...
...
@@ -491,11 +491,11 @@ msgstr "停止 Calibre-web"
#: cps/templates/admin.html:85
msgid "Check for update"
msgstr ""
msgstr "
检查更新
"
#: cps/templates/admin.html:86
msgid "Perform Update"
msgstr ""
msgstr "
执行更新
"
#: cps/templates/admin.html:96
msgid "Do you really want to restart Calibre-web?"
...
...
@@ -519,7 +519,7 @@ msgstr "您确定要关闭 Calibre-web 吗?"
#: cps/templates/admin.html:127
msgid "Updating, please do not reload page"
msgstr ""
msgstr "
正在更新,请不要刷新页面
"
#: cps/templates/book_edit.html:16 cps/templates/search_form.html:6
msgid "Book Title"
...
...
@@ -610,7 +610,7 @@ msgstr "启用注册"
#: cps/templates/config_edit.html:52
msgid "Default Settings for new users"
msgstr ""
msgstr "
新用户默认设置
"
#: cps/templates/config_edit.html:55 cps/templates/user_edit.html:80
msgid "Admin user"
...
...
@@ -651,7 +651,7 @@ msgstr "语言"
#: cps/templates/detail.html:74
msgid "Publishing date"
msgstr ""
msgstr "
出版日期
"
#: cps/templates/detail.html:106
msgid "Description:"
...
...
@@ -723,11 +723,11 @@ msgstr "热门书籍"
#: cps/templates/index.xml:19
msgid "Popular publications from this catalog based on Downloads."
msgstr ""
msgstr "
基于下载数的热门书籍
"
#: cps/templates/index.xml:22 cps/templates/layout.html:129
msgid "Best rated Books"
msgstr ""
msgstr "
最高评分书籍
"
#: cps/templates/index.xml:26
msgid "Popular publications from this catalog based on Rating."
...
...
@@ -933,11 +933,11 @@ msgstr "个作者在此书库"
#: cps/templates/stats.html:45
msgid "Categories in this Library"
msgstr ""
msgstr "
个分类在此书库
"
#: cps/templates/stats.html:49
msgid "Series in this Library"
msgstr ""
msgstr "
个丛书在此书库
"
#: cps/templates/user_edit.html:23
msgid "Kindle E-Mail"
...
...
@@ -961,7 +961,7 @@ msgstr "显示热门书籍"
#: cps/templates/user_edit.html:53
msgid "Show best rated books"
msgstr ""
msgstr "
显示最高评分书籍
"
#: cps/templates/user_edit.html:57
msgid "Show language selection"
...
...
cps/ub.py
View file @
76c90748
...
...
@@ -7,7 +7,6 @@ from sqlalchemy.ext.declarative import declarative_base
from
sqlalchemy.orm
import
*
from
flask_login
import
AnonymousUserMixin
import
os
import
traceback
import
logging
from
werkzeug.security
import
generate_password_hash
from
flask_babel
import
gettext
as
_
...
...
cps/web.py
View file @
76c90748
...
...
@@ -4,8 +4,9 @@ import mimetypes
import
logging
from
logging.handlers
import
RotatingFileHandler
import
textwrap
from
flask
import
Flask
,
render_template
,
session
,
request
,
Response
,
redirect
,
url_for
,
send_from_directory
,
\
from
flask
import
Flask
,
render_template
,
request
,
Response
,
redirect
,
url_for
,
send_from_directory
,
\
make_response
,
g
,
flash
,
abort
from
flask
import
__version__
as
flaskVersion
import
ub
from
ub
import
config
import
helper
...
...
@@ -14,9 +15,12 @@ import errno
from
sqlalchemy.sql.expression
import
func
from
sqlalchemy.sql.expression
import
false
from
sqlalchemy.exc
import
IntegrityError
from
sqlalchemy
import
__version__
as
sqlalchemyVersion
from
math
import
ceil
from
flask_login
import
LoginManager
,
login_user
,
logout_user
,
login_required
,
current_user
from
flask_login
import
__version__
as
flask_loginVersion
from
flask_principal
import
Principal
,
Identity
,
AnonymousIdentity
,
identity_changed
from
flask_login
import
__version__
as
flask_principalVersion
from
flask_babel
import
Babel
from
flask_babel
import
gettext
as
_
import
requests
...
...
@@ -24,6 +28,7 @@ import zipfile
from
werkzeug.security
import
generate_password_hash
,
check_password_hash
from
babel
import
Locale
as
LC
from
babel
import
negotiate_locale
from
babel
import
__version__
as
babelVersion
from
babel.dates
import
format_date
from
functools
import
wraps
import
base64
...
...
@@ -32,16 +37,16 @@ import json
import
urllib
import
datetime
from
iso639
import
languages
as
isoLanguages
from
iso639
import
__version__
as
iso639Version
from
uuid
import
uuid4
import
os.path
import
sys
import
subprocess
import
re
import
db
import
thread
from
shutil
import
move
,
copyfile
from
tornado.ioloop
import
IOLoop
from
tornado
import
version
as
tornadoVersion
try
:
from
wand.image
import
Image
...
...
@@ -51,6 +56,7 @@ except ImportError, e:
use_generic_pdf_cover
=
True
from
cgi
import
escape
ALLOWED_EXTENSIONS
=
set
([
'txt'
,
'pdf'
,
'epub'
,
'mobi'
,
'azw'
,
'azw3'
,
'cbr'
,
'cbz'
,
'cbt'
,
'djvu'
,
'prc'
,
'doc'
,
'docx'
,
'fb2'
])
# Proxy Helper class
class
ReverseProxied
(
object
):
...
...
@@ -473,8 +479,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
)
...
...
@@ -1039,6 +1047,17 @@ def stats():
if
re
.
search
(
'Amazon kindlegen
\
('
,
lines
):
versions
[
'KindlegenVersion'
]
=
lines
versions
[
'PythonVersion'
]
=
sys
.
version
versions
[
'babel'
]
=
babelVersion
versions
[
'sqlalchemy'
]
=
sqlalchemyVersion
versions
[
'flask'
]
=
flaskVersion
versions
[
'flasklogin'
]
=
flask_loginVersion
versions
[
'flask_principal'
]
=
flask_principalVersion
versions
[
'tornado'
]
=
tornadoVersion
versions
[
'iso639'
]
=
iso639Version
versions
[
'requests'
]
=
requests
.
__version__
versions
[
'pysqlite'
]
=
db
.
engine
.
dialect
.
dbapi
.
version
versions
[
'sqlite'
]
=
db
.
engine
.
dialect
.
dbapi
.
sqlite_version
return
render_title_template
(
'stats.html'
,
bookcounter
=
counter
,
authorcounter
=
authors
,
versions
=
versions
,
categorycounter
=
categorys
,
seriecounter
=
series
,
title
=
_
(
u"Statistics"
))
...
...
@@ -1087,9 +1106,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
=
""
)
...
...
@@ -1109,12 +1129,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))
...
...
@@ -1130,7 +1152,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
:
...
...
@@ -1180,7 +1203,7 @@ def feed_get_cover(book_id):
@
app
.
route
(
"/read/<int:book_id>/<format>"
)
@
login_required
@
login_required
_if_no_ano
def
read_book
(
book_id
,
format
):
book
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book_id
)
.
first
()
if
book
:
...
...
@@ -1789,6 +1812,8 @@ def edit_mailsettings():
category
=
"success"
)
else
:
flash
(
_
(
u"There was an error sending the Test E-Mail:
%(res)
s"
,
res
=
result
),
category
=
"error"
)
else
:
flash
(
_
(
u"E-Mail settings updated"
),
category
=
"success"
)
return
render_title_template
(
"email_edit.html"
,
content
=
content
,
title
=
_
(
u"Edit mail settings"
))
...
...
@@ -2130,6 +2155,18 @@ def upload():
db
.
session
.
connection
()
.
connection
.
connection
.
create_function
(
'uuid4'
,
0
,
lambda
:
str
(
uuid4
()))
if
request
.
method
==
'POST'
and
'btn-upload'
in
request
.
files
:
file
=
request
.
files
[
'btn-upload'
]
if
'.'
in
file
.
filename
:
file_ext
=
file
.
filename
.
rsplit
(
'.'
,
1
)[
-
1
]
.
lower
()
if
file_ext
not
in
ALLOWED_EXTENSIONS
:
flash
(
_
(
'File extension "
%
s" is not allowed to be uploaded to this server'
%
file_ext
),
category
=
"error"
)
return
redirect
(
url_for
(
'index'
))
else
:
flash
(
_
(
'File to be uploaded must have an extension'
),
category
=
"error"
)
return
redirect
(
url_for
(
'index'
))
meta
=
uploader
.
upload
(
file
)
title
=
meta
.
title
...
...
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