mirror of
https://github.com/janeczku/calibre-web
synced 2024-11-15 14:24:57 +00:00
Merge remote-tracking branch 'chinese_translation/master'
This commit is contained in:
commit
00462237fe
27
cps/epub.py
27
cps/epub.py
@ -7,12 +7,13 @@ import os
|
|||||||
import uploader
|
import uploader
|
||||||
from iso639 import languages as isoLanguages
|
from iso639 import languages as isoLanguages
|
||||||
|
|
||||||
def extractCover(zip, coverFile, coverpath, tmp_file_name):
|
|
||||||
|
def extractCover(zipFile, coverFile, coverpath, tmp_file_name):
|
||||||
if coverFile is None:
|
if coverFile is None:
|
||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
zipCoverPath = os.path.join(coverpath , coverFile).replace('\\','/')
|
zipCoverPath = os.path.join(coverpath , coverFile).replace('\\','/')
|
||||||
cf = zip.read(zipCoverPath)
|
cf = zipFile.read(zipCoverPath)
|
||||||
prefix = os.path.splitext(tmp_file_name)[0]
|
prefix = os.path.splitext(tmp_file_name)[0]
|
||||||
tmp_cover_name = prefix + '.' + os.path.basename(zipCoverPath)
|
tmp_cover_name = prefix + '.' + os.path.basename(zipCoverPath)
|
||||||
image = open(tmp_cover_name, 'wb')
|
image = open(tmp_cover_name, 'wb')
|
||||||
@ -28,15 +29,15 @@ def get_epub_info(tmp_file_path, original_file_name, original_file_extension):
|
|||||||
'dc': 'http://purl.org/dc/elements/1.1/'
|
'dc': 'http://purl.org/dc/elements/1.1/'
|
||||||
}
|
}
|
||||||
|
|
||||||
zip = zipfile.ZipFile(tmp_file_path)
|
epubZip = zipfile.ZipFile(tmp_file_path)
|
||||||
|
|
||||||
txt = zip.read('META-INF/container.xml')
|
txt = epubZip.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 = epubZip.read(cfname)
|
||||||
tree = etree.fromstring(cf)
|
tree = etree.fromstring(cf)
|
||||||
|
|
||||||
coverpath=os.path.dirname(cfname)
|
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]
|
||||||
|
|
||||||
@ -70,23 +71,23 @@ def get_epub_info(tmp_file_path, original_file_name, original_file_extension):
|
|||||||
coversection = tree.xpath("/pkg:package/pkg:manifest/pkg:item[@id='cover-image']/@href", namespaces=ns)
|
coversection = tree.xpath("/pkg:package/pkg:manifest/pkg:item[@id='cover-image']/@href", namespaces=ns)
|
||||||
coverfile = None
|
coverfile = None
|
||||||
if len(coversection) > 0:
|
if len(coversection) > 0:
|
||||||
coverfile = extractCover(zip, coversection[0], coverpath, tmp_file_path)
|
coverfile = extractCover(epubZip, coversection[0], coverpath, tmp_file_path)
|
||||||
else:
|
else:
|
||||||
meta_cover = tree.xpath("/pkg:package/pkg:metadata/pkg:meta[@name='cover']/@content", namespaces=ns)
|
meta_cover = tree.xpath("/pkg:package/pkg:metadata/pkg:meta[@name='cover']/@content", namespaces=ns)
|
||||||
if len(meta_cover) > 0:
|
if len(meta_cover) > 0:
|
||||||
coversection = tree.xpath("/pkg:package/pkg:manifest/pkg:item[@id='"+meta_cover[0]+"']/@href", namespaces=ns)
|
coversection = tree.xpath("/pkg:package/pkg:manifest/pkg:item[@id='"+meta_cover[0]+"']/@href", namespaces=ns)
|
||||||
if len(coversection) > 0:
|
if len(coversection) > 0:
|
||||||
filetype = coversection[0].rsplit('.',1)[-1]
|
filetype = coversection[0].rsplit('.', 1)[-1]
|
||||||
if filetype == "xhtml" or filetype == "html": #if cover is (x)html format
|
if filetype == "xhtml" or filetype == "html": #if cover is (x)html format
|
||||||
markup = zip.read(os.path.join(coverpath,coversection[0]))
|
markup = epubZip.read(os.path.join(coverpath, coversection[0]))
|
||||||
markupTree = etree.fromstring(markup)
|
markupTree = etree.fromstring(markup)
|
||||||
#no matter xhtml or html with no namespace
|
# no matter xhtml or html with no namespace
|
||||||
imgsrc = markupTree.xpath("//*[local-name() = 'img']/@src")
|
imgsrc = markupTree.xpath("//*[local-name() = 'img']/@src")
|
||||||
#imgsrc maybe startwith "../"" so fullpath join then relpath to cwd
|
# imgsrc maybe startwith "../"" so fullpath join then relpath to cwd
|
||||||
filename = os.path.relpath(os.path.join(os.path.dirname(os.path.join(coverpath, coversection[0])), imgsrc[0]))
|
filename = os.path.relpath(os.path.join(os.path.dirname(os.path.join(coverpath, coversection[0])), imgsrc[0]))
|
||||||
coverfile = extractCover(zip, filename, "", tmp_file_path)
|
coverfile = extractCover(epubZip, filename, "", tmp_file_path)
|
||||||
else:
|
else:
|
||||||
coverfile = extractCover(zip, coversection[0], coverpath, tmp_file_path)
|
coverfile = extractCover(epubZip, coversection[0], coverpath, tmp_file_path)
|
||||||
|
|
||||||
if epub_metadata['title'] is None:
|
if epub_metadata['title'] is None:
|
||||||
title = original_file_name
|
title = original_file_name
|
||||||
|
@ -43,9 +43,9 @@ import web
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
import unidecode
|
import unidecode
|
||||||
use_unidecode=True
|
use_unidecode = True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
use_unidecode=False
|
use_unidecode = False
|
||||||
|
|
||||||
# Global variables
|
# Global variables
|
||||||
global_task = None
|
global_task = None
|
||||||
@ -242,7 +242,7 @@ def get_valid_filename(value, replace_whitespace=True):
|
|||||||
Returns the given string converted to a string that can be used for a clean
|
Returns the given string converted to a string that can be used for a clean
|
||||||
filename. Limits num characters to 128 max.
|
filename. Limits num characters to 128 max.
|
||||||
"""
|
"""
|
||||||
if value[-1:] ==u'.':
|
if value[-1:] == u'.':
|
||||||
value = value[:-1]+u'_'
|
value = value[:-1]+u'_'
|
||||||
if use_unidecode:
|
if use_unidecode:
|
||||||
value=(unidecode.unidecode(value)).strip()
|
value=(unidecode.unidecode(value)).strip()
|
||||||
@ -266,7 +266,7 @@ def get_sorted_author(value):
|
|||||||
regexes = ["^(JR|SR)\.?$","^I{1,3}\.?$","^IV\.?$"]
|
regexes = ["^(JR|SR)\.?$","^I{1,3}\.?$","^IV\.?$"]
|
||||||
combined = "(" + ")|(".join(regexes) + ")"
|
combined = "(" + ")|(".join(regexes) + ")"
|
||||||
value = value.split(" ")
|
value = value.split(" ")
|
||||||
if re.match(combined,value[-1].upper()):
|
if re.match(combined, value[-1].upper()):
|
||||||
value2 = value[-2] + ", " + " ".join(value[:-2]) + " " + value[-1]
|
value2 = value[-2] + ", " + " ".join(value[:-2]) + " " + value[-1]
|
||||||
else:
|
else:
|
||||||
value2 = value[-1] + ", " + " ".join(value[:-1])
|
value2 = value[-1] + ", " + " ".join(value[:-1])
|
||||||
@ -295,6 +295,7 @@ def update_dir_stucture(book_id, calibrepath):
|
|||||||
book.path = new_authordir + '/' + book.path.split('/')[1]
|
book.path = new_authordir + '/' + book.path.split('/')[1]
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
|
|
||||||
def update_dir_structure_gdrive(book_id):
|
def update_dir_structure_gdrive(book_id):
|
||||||
db.session.connection().connection.connection.create_function("title_sort", 1, db.title_sort)
|
db.session.connection().connection.connection.create_function("title_sort", 1, db.title_sort)
|
||||||
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()
|
||||||
@ -313,7 +314,7 @@ def update_dir_structure_gdrive(book_id):
|
|||||||
|
|
||||||
if authordir != new_authordir:
|
if authordir != new_authordir:
|
||||||
gFile=gd.getFileFromEbooksFolder(web.Gdrive.Instance().drive,None,authordir)
|
gFile=gd.getFileFromEbooksFolder(web.Gdrive.Instance().drive,None,authordir)
|
||||||
gFile['title']= new_authordir
|
gFile['title'] = new_authordir
|
||||||
gFile.Upload()
|
gFile.Upload()
|
||||||
book.path = new_authordir + '/' + book.path.split('/')[1]
|
book.path = new_authordir + '/' + book.path.split('/')[1]
|
||||||
|
|
||||||
@ -327,23 +328,23 @@ class Updater(threading.Thread):
|
|||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
global global_task
|
global global_task
|
||||||
self.status=1
|
self.status = 1
|
||||||
r = requests.get('https://api.github.com/repos/janeczku/calibre-web/zipball/master', stream=True)
|
r = requests.get('https://api.github.com/repos/janeczku/calibre-web/zipball/master', stream=True)
|
||||||
fname = re.findall("filename=(.+)", r.headers['content-disposition'])[0]
|
fname = re.findall("filename=(.+)", r.headers['content-disposition'])[0]
|
||||||
self.status=2
|
self.status = 2
|
||||||
z = zipfile.ZipFile(StringIO(r.content))
|
z = zipfile.ZipFile(StringIO(r.content))
|
||||||
self.status=3
|
self.status = 3
|
||||||
tmp_dir = gettempdir()
|
tmp_dir = gettempdir()
|
||||||
z.extractall(tmp_dir)
|
z.extractall(tmp_dir)
|
||||||
self.status=4
|
self.status = 4
|
||||||
self.update_source(os.path.join(tmp_dir,os.path.splitext(fname)[0]),ub.config.get_main_dir)
|
self.update_source(os.path.join(tmp_dir,os.path.splitext(fname)[0]),ub.config.get_main_dir)
|
||||||
self.status=5
|
self.status = 5
|
||||||
global_task = 0
|
global_task = 0
|
||||||
db.session.close()
|
db.session.close()
|
||||||
db.engine.dispose()
|
db.engine.dispose()
|
||||||
ub.session.close()
|
ub.session.close()
|
||||||
ub.engine.dispose()
|
ub.engine.dispose()
|
||||||
self.status=6
|
self.status = 6
|
||||||
|
|
||||||
if web.gevent_server:
|
if web.gevent_server:
|
||||||
web.gevent_server.stop()
|
web.gevent_server.stop()
|
||||||
@ -351,7 +352,7 @@ class Updater(threading.Thread):
|
|||||||
# stop tornado server
|
# stop tornado server
|
||||||
server = IOLoop.instance()
|
server = IOLoop.instance()
|
||||||
server.add_callback(server.stop)
|
server.add_callback(server.stop)
|
||||||
self.status=7
|
self.status = 7
|
||||||
|
|
||||||
def get_update_status(self):
|
def get_update_status(self):
|
||||||
return self.status
|
return self.status
|
||||||
@ -432,7 +433,7 @@ class Updater(threading.Thread):
|
|||||||
old_list = list()
|
old_list = list()
|
||||||
exclude = (
|
exclude = (
|
||||||
'vendor' + os.sep + 'kindlegen.exe', 'vendor' + os.sep + 'kindlegen', os.sep + 'app.db',
|
'vendor' + os.sep + 'kindlegen.exe', 'vendor' + os.sep + 'kindlegen', os.sep + 'app.db',
|
||||||
os.sep + 'vendor',os.sep + 'calibre-web.log')
|
os.sep + 'vendor', os.sep + 'calibre-web.log')
|
||||||
for root, dirs, files in os.walk(destination, topdown=True):
|
for root, dirs, files in os.walk(destination, topdown=True):
|
||||||
for name in files:
|
for name in files:
|
||||||
old_list.append(os.path.join(root, name).replace(destination, ''))
|
old_list.append(os.path.join(root, name).replace(destination, ''))
|
||||||
@ -462,7 +463,7 @@ class Updater(threading.Thread):
|
|||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
logging.getLogger('cps.web').debug("Delete file " + item_path)
|
logging.getLogger('cps.web').debug("Delete file " + item_path)
|
||||||
log_from_thread("Delete file " + item_path)
|
# log_from_thread("Delete file " + item_path)
|
||||||
os.remove(item_path)
|
os.remove(item_path)
|
||||||
except Exception:
|
except Exception:
|
||||||
logging.getLogger('cps.web').debug("Could not remove:" + item_path)
|
logging.getLogger('cps.web').debug("Could not remove:" + item_path)
|
||||||
|
Binary file not shown.
@ -307,7 +307,7 @@ msgstr "用户 '%(user)s' 已被创建"
|
|||||||
|
|
||||||
#: cps/web.py:2198
|
#: cps/web.py:2198
|
||||||
msgid "Found an existing account for this email address or nickname."
|
msgid "Found an existing account for this email address or nickname."
|
||||||
msgstr "已找到使用此邮箱或昵称的账号。"
|
msgstr "已存在使用此邮箱或昵称的账号。"
|
||||||
|
|
||||||
#: cps/web.py:2220
|
#: cps/web.py:2220
|
||||||
msgid "Mail settings updated"
|
msgid "Mail settings updated"
|
||||||
@ -496,7 +496,7 @@ msgstr "最新提交时间戳"
|
|||||||
|
|
||||||
#: cps/templates/admin.html:83
|
#: cps/templates/admin.html:83
|
||||||
msgid "Reconnect to Calibre DB"
|
msgid "Reconnect to Calibre DB"
|
||||||
msgstr ""
|
msgstr "重新连接到Calibre数据库"
|
||||||
|
|
||||||
#: cps/templates/admin.html:84
|
#: cps/templates/admin.html:84
|
||||||
msgid "Restart Calibre-web"
|
msgid "Restart Calibre-web"
|
||||||
@ -590,7 +590,7 @@ msgstr "编辑后查看书籍"
|
|||||||
|
|
||||||
#: cps/templates/book_edit.html:107 cps/templates/book_edit.html:118
|
#: cps/templates/book_edit.html:107 cps/templates/book_edit.html:118
|
||||||
msgid "Get metadata"
|
msgid "Get metadata"
|
||||||
msgstr ""
|
msgstr "获取元数据"
|
||||||
|
|
||||||
#: cps/templates/book_edit.html:108 cps/templates/config_edit.html:117
|
#: cps/templates/book_edit.html:108 cps/templates/config_edit.html:117
|
||||||
#: cps/templates/login.html:19 cps/templates/search_form.html:79
|
#: cps/templates/login.html:19 cps/templates/search_form.html:79
|
||||||
@ -600,11 +600,11 @@ msgstr "提交"
|
|||||||
|
|
||||||
#: cps/templates/book_edit.html:121
|
#: cps/templates/book_edit.html:121
|
||||||
msgid "Keyword"
|
msgid "Keyword"
|
||||||
msgstr ""
|
msgstr "关键字"
|
||||||
|
|
||||||
#: cps/templates/book_edit.html:122
|
#: cps/templates/book_edit.html:122
|
||||||
msgid " Search keyword "
|
msgid " Search keyword "
|
||||||
msgstr ""
|
msgstr "搜索关键字"
|
||||||
|
|
||||||
#: cps/templates/book_edit.html:124 cps/templates/layout.html:60
|
#: cps/templates/book_edit.html:124 cps/templates/layout.html:60
|
||||||
msgid "Go!"
|
msgid "Go!"
|
||||||
@ -612,32 +612,32 @@ msgstr "走起!"
|
|||||||
|
|
||||||
#: cps/templates/book_edit.html:125
|
#: cps/templates/book_edit.html:125
|
||||||
msgid "Click the cover to load metadata to the form"
|
msgid "Click the cover to load metadata to the form"
|
||||||
msgstr ""
|
msgstr "点击封面加载元数据到表单"
|
||||||
|
|
||||||
#: cps/templates/book_edit.html:129 cps/templates/book_edit.html:142
|
#: cps/templates/book_edit.html:129 cps/templates/book_edit.html:142
|
||||||
msgid "Loading..."
|
msgid "Loading..."
|
||||||
msgstr ""
|
msgstr "加载中..."
|
||||||
|
|
||||||
#: cps/templates/book_edit.html:132
|
#: cps/templates/book_edit.html:132
|
||||||
msgid "Close"
|
msgid "Close"
|
||||||
msgstr ""
|
msgstr "关闭"
|
||||||
|
|
||||||
#: cps/templates/book_edit.html:143
|
#: cps/templates/book_edit.html:143
|
||||||
msgid "Search error!"
|
msgid "Search error!"
|
||||||
msgstr ""
|
msgstr "搜索错误"
|
||||||
|
|
||||||
#: cps/templates/book_edit.html:144
|
#: cps/templates/book_edit.html:144
|
||||||
msgid "No Result! Please try anonther keyword."
|
msgid "No Result! Please try anonther keyword."
|
||||||
msgstr ""
|
msgstr "没有结果!请尝试别的关键字."
|
||||||
|
|
||||||
#: cps/templates/book_edit.html:146 cps/templates/detail.html:76
|
#: cps/templates/book_edit.html:146 cps/templates/detail.html:76
|
||||||
#: cps/templates/search_form.html:14
|
#: cps/templates/search_form.html:14
|
||||||
msgid "Publisher"
|
msgid "Publisher"
|
||||||
msgstr ""
|
msgstr "出版社"
|
||||||
|
|
||||||
#: cps/templates/book_edit.html:148
|
#: cps/templates/book_edit.html:148
|
||||||
msgid "Source"
|
msgid "Source"
|
||||||
msgstr ""
|
msgstr "来源"
|
||||||
|
|
||||||
#: cps/templates/config_edit.html:7
|
#: cps/templates/config_edit.html:7
|
||||||
msgid "Location of Calibre database"
|
msgid "Location of Calibre database"
|
||||||
@ -645,7 +645,7 @@ msgstr "Calibre 数据库位置"
|
|||||||
|
|
||||||
#: cps/templates/config_edit.html:13
|
#: cps/templates/config_edit.html:13
|
||||||
msgid "Use google drive?"
|
msgid "Use google drive?"
|
||||||
msgstr ""
|
msgstr "是否使用google drive?"
|
||||||
|
|
||||||
#: cps/templates/config_edit.html:17
|
#: cps/templates/config_edit.html:17
|
||||||
msgid "Client id"
|
msgid "Client id"
|
||||||
@ -660,8 +660,8 @@ msgid "Calibre Base URL"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/templates/config_edit.html:29
|
#: cps/templates/config_edit.html:29
|
||||||
msgid "Google drive Calibre folder"
|
msgid "Google drive Calibre folde"
|
||||||
msgstr ""
|
msgstr "Google drive Calibre 文件夹"
|
||||||
|
|
||||||
#: cps/templates/config_edit.html:38
|
#: cps/templates/config_edit.html:38
|
||||||
msgid "Metadata Watch Channel ID"
|
msgid "Metadata Watch Channel ID"
|
||||||
@ -843,12 +843,12 @@ msgstr "显示随机书籍"
|
|||||||
#: cps/templates/index.xml:43 cps/templates/index.xml:47
|
#: cps/templates/index.xml:43 cps/templates/index.xml:47
|
||||||
#: cps/templates/layout.html:132
|
#: cps/templates/layout.html:132
|
||||||
msgid "Read Books"
|
msgid "Read Books"
|
||||||
msgstr ""
|
msgstr "已读书籍"
|
||||||
|
|
||||||
#: cps/templates/index.xml:50 cps/templates/index.xml:54
|
#: cps/templates/index.xml:50 cps/templates/index.xml:54
|
||||||
#: cps/templates/layout.html:133
|
#: cps/templates/layout.html:133
|
||||||
msgid "Unread Books"
|
msgid "Unread Books"
|
||||||
msgstr ""
|
msgstr "未读书籍"
|
||||||
|
|
||||||
#: cps/templates/index.xml:57 cps/templates/layout.html:144
|
#: cps/templates/index.xml:57 cps/templates/layout.html:144
|
||||||
msgid "Authors"
|
msgid "Authors"
|
||||||
@ -1082,7 +1082,7 @@ msgstr "显示作者选择"
|
|||||||
|
|
||||||
#: cps/templates/user_edit.html:75
|
#: cps/templates/user_edit.html:75
|
||||||
msgid "Show read and unread"
|
msgid "Show read and unread"
|
||||||
msgstr ""
|
msgstr "显示已读和未读"
|
||||||
|
|
||||||
#: cps/templates/user_edit.html:79
|
#: cps/templates/user_edit.html:79
|
||||||
msgid "Show random books in detail view"
|
msgid "Show random books in detail view"
|
||||||
|
@ -131,6 +131,7 @@ class Singleton:
|
|||||||
def __instancecheck__(self, inst):
|
def __instancecheck__(self, inst):
|
||||||
return isinstance(inst, self._decorated)
|
return isinstance(inst, self._decorated)
|
||||||
|
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
class Gauth:
|
class Gauth:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@ -567,7 +568,7 @@ def feed_index():
|
|||||||
@app.route("/opds/osd")
|
@app.route("/opds/osd")
|
||||||
@requires_basic_auth_if_no_ano
|
@requires_basic_auth_if_no_ano
|
||||||
def feed_osd():
|
def feed_osd():
|
||||||
xml = render_title_template('osd.xml',lang='de-DE')
|
xml = render_title_template('osd.xml', lang='de-DE')
|
||||||
response = make_response(xml)
|
response = make_response(xml)
|
||||||
response.headers["Content-Type"] = "application/xml"
|
response.headers["Content-Type"] = "application/xml"
|
||||||
return response
|
return response
|
||||||
@ -1466,7 +1467,7 @@ def advanced_search():
|
|||||||
try:
|
try:
|
||||||
cur_l = LC.parse(lang.lang_code)
|
cur_l = LC.parse(lang.lang_code)
|
||||||
lang.name = cur_l.get_language_name(get_locale())
|
lang.name = cur_l.get_language_name(get_locale())
|
||||||
except Exception as e:
|
except Exception:
|
||||||
lang.name = _(isoLanguages.get(part3=lang.lang_code).name)
|
lang.name = _(isoLanguages.get(part3=lang.lang_code).name)
|
||||||
else:
|
else:
|
||||||
languages = None
|
languages = None
|
||||||
|
Loading…
Reference in New Issue
Block a user