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