mirror of
https://github.com/janeczku/calibre-web
synced 2024-12-22 16:10:30 +00:00
changes for #77
Code cosmetics #75: - More debug infos for kindlegen and sending e-mail. - Button for sending test e-mail. - timeout of 5min for sending e-mail
This commit is contained in:
parent
c582ccf79c
commit
ba44a15891
1
.gitignore
vendored
1
.gitignore
vendored
@ -17,6 +17,7 @@ eggs/
|
|||||||
*.db
|
*.db
|
||||||
*.log
|
*.log
|
||||||
config.ini
|
config.ini
|
||||||
|
cps/static/[0-9]*
|
||||||
|
|
||||||
.idea/
|
.idea/
|
||||||
*.bak
|
*.bak
|
||||||
|
54
cps.py
54
cps.py
@ -2,10 +2,14 @@
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
from threading import Thread
|
||||||
|
from multiprocessing import Queue
|
||||||
|
import time
|
||||||
|
|
||||||
base_path = os.path.dirname(os.path.abspath(__file__))
|
base_path = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
|
||||||
# Insert local directories into path
|
# Insert local directories into path
|
||||||
sys.path.insert(0,os.path.join(base_path, 'vendor'))
|
sys.path.insert(0, os.path.join(base_path, 'vendor'))
|
||||||
|
|
||||||
from cps import web
|
from cps import web
|
||||||
from cps import config
|
from cps import config
|
||||||
@ -15,11 +19,47 @@ from tornado.ioloop import IOLoop
|
|||||||
|
|
||||||
global title_sort
|
global title_sort
|
||||||
|
|
||||||
|
|
||||||
def title_sort(title):
|
def title_sort(title):
|
||||||
return title
|
return title
|
||||||
if config.DEVELOPMENT:
|
|
||||||
web.app.run(host="0.0.0.0",port=config.PORT, debug=True)
|
|
||||||
else:
|
def start_calibreweb(messagequeue):
|
||||||
http_server = HTTPServer(WSGIContainer(web.app))
|
web.global_queue = messagequeue
|
||||||
http_server.listen(config.PORT)
|
if config.DEVELOPMENT:
|
||||||
IOLoop.instance().start()
|
web.app.run(host="0.0.0.0", port=config.PORT, debug=True)
|
||||||
|
else:
|
||||||
|
http_server = HTTPServer(WSGIContainer(web.app))
|
||||||
|
http_server.listen(config.PORT)
|
||||||
|
IOLoop.instance().start()
|
||||||
|
print "Tornado finished"
|
||||||
|
http_server.stop()
|
||||||
|
|
||||||
|
|
||||||
|
def stop_calibreweb():
|
||||||
|
# Close Database connections for user and data
|
||||||
|
web.db.session.close()
|
||||||
|
web.db.engine.dispose()
|
||||||
|
web.ub.session.close()
|
||||||
|
web.ub.engine.dispose()
|
||||||
|
test=IOLoop.instance()
|
||||||
|
test.add_callback(test.stop)
|
||||||
|
print("Asked Tornado to exit")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
if config.DEVELOPMENT:
|
||||||
|
web.app.run(host="0.0.0.0",port=config.PORT, debug=True)
|
||||||
|
else:
|
||||||
|
while True:
|
||||||
|
q = Queue()
|
||||||
|
t = Thread(target=start_calibreweb, args=(q,))
|
||||||
|
t.start()
|
||||||
|
while True: #watching queue, if there is no call than sleep, otherwise break
|
||||||
|
if q.empty():
|
||||||
|
time.sleep(1)
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
stop_calibreweb()
|
||||||
|
t.join()
|
||||||
|
|
||||||
|
@ -1,18 +1,22 @@
|
|||||||
__author__ = 'lemmsh'
|
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
logger = logging.getLogger("book_formats")
|
|
||||||
|
|
||||||
import uploader
|
import uploader
|
||||||
import os
|
import os
|
||||||
|
from flask_babel import gettext as _
|
||||||
|
|
||||||
|
__author__ = 'lemmsh'
|
||||||
|
|
||||||
|
logger = logging.getLogger("book_formats")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from wand.image import Image
|
from wand.image import Image
|
||||||
|
from wand import version as ImageVersion
|
||||||
use_generic_pdf_cover = False
|
use_generic_pdf_cover = False
|
||||||
except ImportError, e:
|
except ImportError, e:
|
||||||
logger.warning('cannot import Image, generating pdf covers for pdf uploads will not work: %s', e)
|
logger.warning('cannot import Image, generating pdf covers for pdf uploads will not work: %s', e)
|
||||||
use_generic_pdf_cover = True
|
use_generic_pdf_cover = True
|
||||||
try:
|
try:
|
||||||
from PyPDF2 import PdfFileReader
|
from PyPDF2 import PdfFileReader
|
||||||
|
from PyPDF2 import __version__ as PyPdfVersion
|
||||||
use_pdf_meta = True
|
use_pdf_meta = True
|
||||||
except ImportError, e:
|
except ImportError, e:
|
||||||
logger.warning('cannot import PyPDF2, extracting pdf metadata will not work: %s', e)
|
logger.warning('cannot import PyPDF2, extracting pdf metadata will not work: %s', e)
|
||||||
@ -37,9 +41,9 @@ def process(tmp_file_path, original_file_name, original_file_extension):
|
|||||||
try:
|
try:
|
||||||
if ".PDF" == original_file_extension.upper():
|
if ".PDF" == original_file_extension.upper():
|
||||||
return pdf_meta(tmp_file_path, original_file_name, original_file_extension)
|
return pdf_meta(tmp_file_path, original_file_name, original_file_extension)
|
||||||
if ".EPUB" == original_file_extension.upper() and use_epub_meta == True:
|
if ".EPUB" == original_file_extension.upper() and use_epub_meta is True:
|
||||||
return epub.get_epub_info(tmp_file_path, original_file_name, original_file_extension)
|
return epub.get_epub_info(tmp_file_path, original_file_name, original_file_extension)
|
||||||
if ".FB2" == original_file_extension.upper() and use_fb2_meta == True:
|
if ".FB2" == original_file_extension.upper() and use_fb2_meta is True:
|
||||||
return fb2.get_fb2_info(tmp_file_path, original_file_name, original_file_extension)
|
return fb2.get_fb2_info(tmp_file_path, original_file_name, original_file_extension)
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
logger.warning('cannot parse metadata, using default: %s', e)
|
logger.warning('cannot parse metadata, using default: %s', e)
|
||||||
@ -47,29 +51,28 @@ def process(tmp_file_path, original_file_name, original_file_extension):
|
|||||||
return default_meta(tmp_file_path, original_file_name, original_file_extension)
|
return default_meta(tmp_file_path, original_file_name, original_file_extension)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def default_meta(tmp_file_path, original_file_name, original_file_extension):
|
def default_meta(tmp_file_path, original_file_name, original_file_extension):
|
||||||
return uploader.BookMeta(
|
return uploader.BookMeta(
|
||||||
file_path = tmp_file_path,
|
file_path=tmp_file_path,
|
||||||
extension = original_file_extension,
|
extension=original_file_extension,
|
||||||
title = original_file_name,
|
title=original_file_name,
|
||||||
author = "Unknown",
|
author="Unknown",
|
||||||
cover = None,
|
cover=None,
|
||||||
description = "",
|
description="",
|
||||||
tags = "",
|
tags="",
|
||||||
series = "",
|
series="",
|
||||||
series_id="")
|
series_id="")
|
||||||
|
|
||||||
|
|
||||||
def pdf_meta(tmp_file_path, original_file_name, original_file_extension):
|
def pdf_meta(tmp_file_path, original_file_name, original_file_extension):
|
||||||
|
|
||||||
if (use_pdf_meta):
|
if use_pdf_meta:
|
||||||
pdf = PdfFileReader(open(tmp_file_path, 'rb'))
|
pdf = PdfFileReader(open(tmp_file_path, 'rb'))
|
||||||
doc_info = pdf.getDocumentInfo()
|
doc_info = pdf.getDocumentInfo()
|
||||||
else:
|
else:
|
||||||
doc_info = None
|
doc_info = None
|
||||||
|
|
||||||
if (doc_info is not None):
|
if doc_info is not None:
|
||||||
author = doc_info.author if doc_info.author is not None else "Unknown"
|
author = doc_info.author if doc_info.author is not None else "Unknown"
|
||||||
title = doc_info.title if doc_info.title is not None else original_file_name
|
title = doc_info.title if doc_info.title is not None else original_file_name
|
||||||
subject = doc_info.subject
|
subject = doc_info.subject
|
||||||
@ -78,16 +81,17 @@ def pdf_meta(tmp_file_path, original_file_name, original_file_extension):
|
|||||||
title = original_file_name
|
title = original_file_name
|
||||||
subject = ""
|
subject = ""
|
||||||
return uploader.BookMeta(
|
return uploader.BookMeta(
|
||||||
file_path = tmp_file_path,
|
file_path=tmp_file_path,
|
||||||
extension = original_file_extension,
|
extension=original_file_extension,
|
||||||
title = title,
|
title=title,
|
||||||
author = author,
|
author=author,
|
||||||
cover = pdf_preview(tmp_file_path, original_file_name),
|
cover=pdf_preview(tmp_file_path, original_file_name),
|
||||||
description = subject,
|
description=subject,
|
||||||
tags = "",
|
tags="",
|
||||||
series = "",
|
series="",
|
||||||
series_id="")
|
series_id="")
|
||||||
|
|
||||||
|
|
||||||
def pdf_preview(tmp_file_path, tmp_dir):
|
def pdf_preview(tmp_file_path, tmp_dir):
|
||||||
if use_generic_pdf_cover:
|
if use_generic_pdf_cover:
|
||||||
return None
|
return None
|
||||||
@ -97,3 +101,14 @@ def pdf_preview(tmp_file_path, tmp_dir):
|
|||||||
img.compression_quality = 88
|
img.compression_quality = 88
|
||||||
img.save(filename=os.path.join(tmp_dir, cover_file_name))
|
img.save(filename=os.path.join(tmp_dir, cover_file_name))
|
||||||
return cover_file_name
|
return cover_file_name
|
||||||
|
|
||||||
|
def get_versions():
|
||||||
|
if not use_generic_pdf_cover:
|
||||||
|
IVersion=ImageVersion.MAGICK_VERSION
|
||||||
|
else:
|
||||||
|
IVersion=_('not installed')
|
||||||
|
if use_pdf_meta:
|
||||||
|
PVersion=PyPdfVersion
|
||||||
|
else:
|
||||||
|
PVersion=_('not installed')
|
||||||
|
return {'ImageVersion':IVersion,'PyPdfVersion':PVersion}
|
@ -5,9 +5,10 @@ import os
|
|||||||
import sys
|
import sys
|
||||||
from configobj import ConfigObj
|
from configobj import ConfigObj
|
||||||
|
|
||||||
CONFIG_FILE= os.path.join(os.path.normpath(os.path.dirname(os.path.realpath(__file__))+os.sep+".."+os.sep), "config.ini")
|
CONFIG_FILE = os.path.join(os.path.normpath(os.path.dirname(os.path.realpath(__file__))+os.sep+".."+os.sep), "config.ini")
|
||||||
CFG = ConfigObj(CONFIG_FILE)
|
CFG = ConfigObj(CONFIG_FILE)
|
||||||
CFG.encoding='UTF-8'
|
CFG.encoding = 'UTF-8'
|
||||||
|
|
||||||
|
|
||||||
def CheckSection(sec):
|
def CheckSection(sec):
|
||||||
""" Check if INI section exists, if not create it """
|
""" Check if INI section exists, if not create it """
|
||||||
@ -18,6 +19,7 @@ def CheckSection(sec):
|
|||||||
CFG[sec] = {}
|
CFG[sec] = {}
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def check_setting_str(config, cfg_name, item_name, def_val, log=True):
|
def check_setting_str(config, cfg_name, item_name, def_val, log=True):
|
||||||
try:
|
try:
|
||||||
my_val = config[cfg_name][item_name].decode('UTF-8')
|
my_val = config[cfg_name][item_name].decode('UTF-8')
|
||||||
@ -62,24 +64,16 @@ PUBLIC_REG = bool(check_setting_int(CFG, 'Advanced', 'PUBLIC_REG', 0))
|
|||||||
UPLOADING = bool(check_setting_int(CFG, 'Advanced', 'UPLOADING', 0))
|
UPLOADING = bool(check_setting_int(CFG, 'Advanced', 'UPLOADING', 0))
|
||||||
ANON_BROWSE = bool(check_setting_int(CFG, 'Advanced', 'ANON_BROWSE', 0))
|
ANON_BROWSE = bool(check_setting_int(CFG, 'Advanced', 'ANON_BROWSE', 0))
|
||||||
|
|
||||||
SYS_ENCODING="UTF-8"
|
SYS_ENCODING = "UTF-8"
|
||||||
|
|
||||||
if DB_ROOT == "":
|
if DB_ROOT == "":
|
||||||
print "Calibre database directory (DB_ROOT) is not configured"
|
print "Calibre database directory (DB_ROOT) is not configured"
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
configval={}
|
configval = {"DB_ROOT": DB_ROOT, "APP_DB_ROOT": APP_DB_ROOT, "MAIN_DIR": MAIN_DIR, "LOG_DIR": LOG_DIR, "PORT": PORT,
|
||||||
configval["DB_ROOT"] = DB_ROOT
|
"NEWEST_BOOKS": NEWEST_BOOKS, "DEVELOPMENT": DEVELOPMENT, "TITLE_REGEX": TITLE_REGEX,
|
||||||
configval["APP_DB_ROOT"] = APP_DB_ROOT
|
"PUBLIC_REG": PUBLIC_REG, "UPLOADING": UPLOADING, "ANON_BROWSE": ANON_BROWSE}
|
||||||
configval["MAIN_DIR"] = MAIN_DIR
|
|
||||||
configval["LOG_DIR"] = LOG_DIR
|
|
||||||
configval["PORT"] = PORT
|
|
||||||
configval["NEWEST_BOOKS"] = NEWEST_BOOKS
|
|
||||||
configval["DEVELOPMENT"] = DEVELOPMENT
|
|
||||||
configval["TITLE_REGEX"] = TITLE_REGEX
|
|
||||||
configval["PUBLIC_REG"] = PUBLIC_REG
|
|
||||||
configval["UPLOADING"] = UPLOADING
|
|
||||||
configval["ANON_BROWSE"] = ANON_BROWSE
|
|
||||||
|
|
||||||
def save_config(configval):
|
def save_config(configval):
|
||||||
new_config = ConfigObj(encoding='UTF-8')
|
new_config = ConfigObj(encoding='UTF-8')
|
||||||
|
46
cps/db.py
46
cps/db.py
@ -9,8 +9,10 @@ import config
|
|||||||
import re
|
import re
|
||||||
import ast
|
import ast
|
||||||
|
|
||||||
#calibre sort stuff
|
# calibre sort stuff
|
||||||
title_pat = re.compile(config.TITLE_REGEX, re.IGNORECASE)
|
title_pat = re.compile(config.TITLE_REGEX, re.IGNORECASE)
|
||||||
|
|
||||||
|
|
||||||
def title_sort(title):
|
def title_sort(title):
|
||||||
match = title_pat.search(title)
|
match = title_pat.search(title)
|
||||||
if match:
|
if match:
|
||||||
@ -52,7 +54,7 @@ books_languages_link = Table('books_languages_link', Base.metadata,
|
|||||||
|
|
||||||
cc = conn.execute("SELECT id, datatype FROM custom_columns")
|
cc = conn.execute("SELECT id, datatype FROM custom_columns")
|
||||||
cc_ids = []
|
cc_ids = []
|
||||||
cc_exceptions = [ 'datetime', 'int', 'comments', 'float', 'composite','series' ]
|
cc_exceptions = ['datetime', 'int', 'comments', 'float', 'composite', 'series']
|
||||||
books_custom_column_links = {}
|
books_custom_column_links = {}
|
||||||
cc_classes = {}
|
cc_classes = {}
|
||||||
for row in cc:
|
for row in cc:
|
||||||
@ -61,18 +63,19 @@ for row in cc:
|
|||||||
Column('book', Integer, ForeignKey('books.id'), primary_key=True),
|
Column('book', Integer, ForeignKey('books.id'), primary_key=True),
|
||||||
Column('value', Integer, ForeignKey('custom_column_' + str(row.id) + '.id'), primary_key=True)
|
Column('value', Integer, ForeignKey('custom_column_' + str(row.id) + '.id'), primary_key=True)
|
||||||
)
|
)
|
||||||
cc_ids.append([row.id,row.datatype])
|
cc_ids.append([row.id, row.datatype])
|
||||||
if row.datatype == 'bool':
|
if row.datatype == 'bool':
|
||||||
ccdict = {'__tablename__': 'custom_column_' + str(row.id),
|
ccdict = {'__tablename__': 'custom_column_' + str(row.id),
|
||||||
'id': Column(Integer, primary_key=True),
|
'id': Column(Integer, primary_key=True),
|
||||||
'book': Column(Integer,ForeignKey('books.id')),
|
'book': Column(Integer, ForeignKey('books.id')),
|
||||||
'value': Column(Boolean)}
|
'value': Column(Boolean)}
|
||||||
else:
|
else:
|
||||||
ccdict={'__tablename__':'custom_column_' + str(row.id),
|
ccdict = {'__tablename__': 'custom_column_' + str(row.id),
|
||||||
'id':Column(Integer, primary_key=True),
|
'id': Column(Integer, primary_key=True),
|
||||||
'value':Column(String)}
|
'value': Column(String)}
|
||||||
cc_classes[row.id] = type('Custom_Column_' + str(row.id), (Base,), ccdict)
|
cc_classes[row.id] = type('Custom_Column_' + str(row.id), (Base,), ccdict)
|
||||||
|
|
||||||
|
|
||||||
class Comments(Base):
|
class Comments(Base):
|
||||||
__tablename__ = 'comments'
|
__tablename__ = 'comments'
|
||||||
|
|
||||||
@ -100,6 +103,7 @@ class Tags(Base):
|
|||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return u"<Tags('{0})>".format(self.name)
|
return u"<Tags('{0})>".format(self.name)
|
||||||
|
|
||||||
|
|
||||||
class Authors(Base):
|
class Authors(Base):
|
||||||
__tablename__ = 'authors'
|
__tablename__ = 'authors'
|
||||||
|
|
||||||
@ -116,6 +120,7 @@ class Authors(Base):
|
|||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return u"<Authors('{0},{1}{2}')>".format(self.name, self.sort, self.link)
|
return u"<Authors('{0},{1}{2}')>".format(self.name, self.sort, self.link)
|
||||||
|
|
||||||
|
|
||||||
class Series(Base):
|
class Series(Base):
|
||||||
__tablename__ = 'series'
|
__tablename__ = 'series'
|
||||||
|
|
||||||
@ -130,30 +135,33 @@ class Series(Base):
|
|||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return u"<Series('{0},{1}')>".format(self.name, self.sort)
|
return u"<Series('{0},{1}')>".format(self.name, self.sort)
|
||||||
|
|
||||||
|
|
||||||
class Ratings(Base):
|
class Ratings(Base):
|
||||||
__tablename__ = 'ratings'
|
__tablename__ = 'ratings'
|
||||||
|
|
||||||
id = Column(Integer, primary_key=True)
|
id = Column(Integer, primary_key=True)
|
||||||
rating = Column(Integer)
|
rating = Column(Integer)
|
||||||
|
|
||||||
def __init__(self,rating):
|
def __init__(self, rating):
|
||||||
self.rating = rating
|
self.rating = rating
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return u"<Ratings('{0}')>".format(self.rating)
|
return u"<Ratings('{0}')>".format(self.rating)
|
||||||
|
|
||||||
|
|
||||||
class Languages(Base):
|
class Languages(Base):
|
||||||
__tablename__ = 'languages'
|
__tablename__ = 'languages'
|
||||||
|
|
||||||
id = Column(Integer, primary_key=True)
|
id = Column(Integer, primary_key=True)
|
||||||
lang_code = Column(String)
|
lang_code = Column(String)
|
||||||
|
|
||||||
def __init__(self,lang_code):
|
def __init__(self, lang_code):
|
||||||
self.lang_code = lang_code
|
self.lang_code = lang_code
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return u"<Languages('{0}')>".format(self.lang_code)
|
return u"<Languages('{0}')>".format(self.lang_code)
|
||||||
|
|
||||||
|
|
||||||
class Data(Base):
|
class Data(Base):
|
||||||
__tablename__ = 'data'
|
__tablename__ = 'data'
|
||||||
|
|
||||||
@ -172,6 +180,7 @@ class Data(Base):
|
|||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return u"<Data('{0},{1}{2}{3}')>".format(self.book, self.format, self.uncompressed_size, self.name)
|
return u"<Data('{0},{1}{2}{3}')>".format(self.book, self.format, self.uncompressed_size, self.name)
|
||||||
|
|
||||||
|
|
||||||
class Books(Base):
|
class Books(Base):
|
||||||
__tablename__ = 'books'
|
__tablename__ = 'books'
|
||||||
|
|
||||||
@ -207,17 +216,24 @@ class Books(Base):
|
|||||||
self.has_cover = has_cover
|
self.has_cover = has_cover
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return u"<Books('{0},{1}{2}{3}{4}{5}{6}{7}{8}')>".format(self.title, self.sort, self.author_sort, self.timestamp, self.pubdate, self.series_index, self.last_modified ,self.path, self.has_cover)
|
return u"<Books('{0},{1}{2}{3}{4}{5}{6}{7}{8}')>".format(self.title, self.sort, self.author_sort,
|
||||||
|
self.timestamp, self.pubdate, self.series_index,
|
||||||
|
self.last_modified, self.path, self.has_cover)
|
||||||
for id in cc_ids:
|
for id in cc_ids:
|
||||||
if id[1] == 'bool':
|
if id[1] == 'bool':
|
||||||
setattr(Books, 'custom_column_' + str(id[0]), relationship(cc_classes[id[0]], primaryjoin=(Books.id==cc_classes[id[0]].book), backref='books'))
|
setattr(Books, 'custom_column_' + str(id[0]), relationship(cc_classes[id[0]],
|
||||||
|
primaryjoin=(Books.id == cc_classes[id[0]].book),
|
||||||
|
backref='books'))
|
||||||
else:
|
else:
|
||||||
setattr(Books, 'custom_column_' + str(id[0]), relationship(cc_classes[id[0]], secondary=books_custom_column_links[id[0]], backref='books'))
|
setattr(Books, 'custom_column_' + str(id[0]), relationship(cc_classes[id[0]],
|
||||||
|
secondary = books_custom_column_links[id[0]],
|
||||||
|
backref='books'))
|
||||||
|
|
||||||
|
|
||||||
class Custom_Columns(Base):
|
class Custom_Columns(Base):
|
||||||
__tablename__ = 'custom_columns'
|
__tablename__ = 'custom_columns'
|
||||||
|
|
||||||
id = Column(Integer,primary_key=True)
|
id = Column(Integer, primary_key=True)
|
||||||
label = Column(String)
|
label = Column(String)
|
||||||
name = Column(String)
|
name = Column(String)
|
||||||
datatype = Column(String)
|
datatype = Column(String)
|
||||||
@ -231,9 +247,7 @@ class Custom_Columns(Base):
|
|||||||
display_dict = ast.literal_eval(self.display)
|
display_dict = ast.literal_eval(self.display)
|
||||||
return display_dict
|
return display_dict
|
||||||
|
|
||||||
#Base.metadata.create_all(engine)
|
# Base.metadata.create_all(engine)
|
||||||
Session = sessionmaker()
|
Session = sessionmaker()
|
||||||
Session.configure(bind=engine)
|
Session.configure(bind=engine)
|
||||||
session = Session()
|
session = Session()
|
||||||
|
|
||||||
|
|
||||||
|
42
cps/epub.py
42
cps/epub.py
@ -3,8 +3,9 @@ from lxml import etree
|
|||||||
import os
|
import os
|
||||||
import uploader
|
import uploader
|
||||||
|
|
||||||
|
|
||||||
def extractCover(zip, coverFile, tmp_file_name):
|
def extractCover(zip, coverFile, tmp_file_name):
|
||||||
if (coverFile is None):
|
if coverFile is None:
|
||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
cf = zip.read("OPS/" + coverFile)
|
cf = zip.read("OPS/" + coverFile)
|
||||||
@ -16,35 +17,34 @@ def extractCover(zip, coverFile, tmp_file_name):
|
|||||||
return tmp_cover_name
|
return tmp_cover_name
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def get_epub_info(tmp_file_path, original_file_name, original_file_extension):
|
def get_epub_info(tmp_file_path, original_file_name, original_file_extension):
|
||||||
ns = {
|
ns = {
|
||||||
'n':'urn:oasis:names:tc:opendocument:xmlns:container',
|
'n': 'urn:oasis:names:tc:opendocument:xmlns:container',
|
||||||
'pkg':'http://www.idpf.org/2007/opf',
|
'pkg': 'http://www.idpf.org/2007/opf',
|
||||||
'dc':'http://purl.org/dc/elements/1.1/'
|
'dc': 'http://purl.org/dc/elements/1.1/'
|
||||||
}
|
}
|
||||||
|
|
||||||
zip = zipfile.ZipFile(tmp_file_path)
|
zip = zipfile.ZipFile(tmp_file_path)
|
||||||
|
|
||||||
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)
|
||||||
|
|
||||||
p = tree.xpath('/pkg:package/pkg:metadata',namespaces=ns)[0]
|
p = tree.xpath('/pkg:package/pkg:metadata', namespaces=ns)[0]
|
||||||
|
|
||||||
epub_metadata = {}
|
epub_metadata = {}
|
||||||
for s in ['title', 'description', 'creator']:
|
for s in ['title', 'description', 'creator']:
|
||||||
tmp = p.xpath('dc:%s/text()'%(s),namespaces=ns)
|
tmp = p.xpath('dc:%s/text()' % s, namespaces=ns)
|
||||||
if (len(tmp) > 0):
|
if len(tmp) > 0:
|
||||||
epub_metadata[s] = p.xpath('dc:%s/text()'%(s),namespaces=ns)[0]
|
epub_metadata[s] = p.xpath('dc:%s/text()' % s, namespaces=ns)[0]
|
||||||
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']/@href", namespaces=ns)
|
||||||
if (len(coversection) > 0):
|
if len(coversection) > 0:
|
||||||
coverfile = extractCover(zip, coversection[0], tmp_file_path)
|
coverfile = extractCover(zip, coversection[0], tmp_file_path)
|
||||||
else:
|
else:
|
||||||
coverfile = None
|
coverfile = None
|
||||||
@ -53,15 +53,13 @@ def get_epub_info(tmp_file_path, original_file_name, original_file_extension):
|
|||||||
else:
|
else:
|
||||||
title = epub_metadata['title']
|
title = epub_metadata['title']
|
||||||
|
|
||||||
|
|
||||||
return uploader.BookMeta(
|
return uploader.BookMeta(
|
||||||
file_path = tmp_file_path,
|
file_path=tmp_file_path,
|
||||||
extension = original_file_extension,
|
extension=original_file_extension,
|
||||||
title = title,
|
title=title,
|
||||||
author = epub_metadata['creator'],
|
author=epub_metadata['creator'],
|
||||||
cover = coverfile,
|
cover=coverfile,
|
||||||
description = epub_metadata['description'],
|
description=epub_metadata['description'],
|
||||||
tags = "",
|
tags="",
|
||||||
series = "",
|
series="",
|
||||||
series_id="")
|
series_id="")
|
||||||
|
|
||||||
|
28
cps/fb2.py
28
cps/fb2.py
@ -7,29 +7,31 @@ import uploader
|
|||||||
def get_fb2_info(tmp_file_path, original_file_name, original_file_extension):
|
def get_fb2_info(tmp_file_path, original_file_name, original_file_extension):
|
||||||
|
|
||||||
ns = {
|
ns = {
|
||||||
'fb':'http://www.gribuser.ru/xml/fictionbook/2.0',
|
'fb': 'http://www.gribuser.ru/xml/fictionbook/2.0',
|
||||||
'l':'http://www.w3.org/1999/xlink',
|
'l': 'http://www.w3.org/1999/xlink',
|
||||||
}
|
}
|
||||||
|
|
||||||
fb2_file = open(tmp_file_path)
|
fb2_file = open(tmp_file_path)
|
||||||
tree = etree.fromstring(fb2_file.read())
|
tree = etree.fromstring(fb2_file.read())
|
||||||
|
|
||||||
authors = tree.xpath('/fb:FictionBook/fb:description/fb:title-info/fb:author', namespaces=ns)
|
authors = tree.xpath('/fb:FictionBook/fb:description/fb:title-info/fb:author', namespaces=ns)
|
||||||
|
|
||||||
def get_author(element):
|
def get_author(element):
|
||||||
return element.xpath('fb:first-name/text()', namespaces=ns)[0] + ' ' + element.xpath('fb:middle-name/text()', namespaces=ns)[0] + ' ' + element.xpath('fb:last-name/text()', namespaces=ns)[0]
|
return element.xpath('fb:first-name/text()', namespaces=ns)[0] + ' ' + element.xpath('fb:middle-name/text()',
|
||||||
|
namespaces=ns)[0] + ' ' + element.xpath('fb:last-name/text()', namespaces=ns)[0]
|
||||||
author = ", ".join(map(get_author, authors))
|
author = ", ".join(map(get_author, authors))
|
||||||
|
|
||||||
title = unicode(tree.xpath('/fb:FictionBook/fb:description/fb:title-info/fb:book-title/text()', namespaces=ns)[0])
|
title = unicode(tree.xpath('/fb:FictionBook/fb:description/fb:title-info/fb:book-title/text()', namespaces=ns)[0])
|
||||||
description = unicode(tree.xpath('/fb:FictionBook/fb:description/fb:publish-info/fb:book-name/text()', namespaces=ns)[0])
|
description = unicode(tree.xpath('/fb:FictionBook/fb:description/fb:publish-info/fb:book-name/text()',
|
||||||
|
namespaces=ns)[0])
|
||||||
|
|
||||||
return uploader.BookMeta(
|
return uploader.BookMeta(
|
||||||
file_path = tmp_file_path,
|
file_path=tmp_file_path,
|
||||||
extension = original_file_extension,
|
extension=original_file_extension,
|
||||||
title = title,
|
title=title,
|
||||||
author = author,
|
author=author,
|
||||||
cover = None,
|
cover=None,
|
||||||
description = description,
|
description=description,
|
||||||
tags = "",
|
tags="",
|
||||||
series = "",
|
series="",
|
||||||
series_id="")
|
series_id="")
|
||||||
|
|
||||||
|
108
cps/helper.py
108
cps/helper.py
@ -4,8 +4,10 @@
|
|||||||
import db, ub
|
import db, ub
|
||||||
import config
|
import config
|
||||||
from flask import current_app as app
|
from flask import current_app as app
|
||||||
|
import logging
|
||||||
|
|
||||||
import smtplib
|
import smtplib
|
||||||
|
import tempfile
|
||||||
import socket
|
import socket
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
@ -21,16 +23,19 @@ from email.generator import Generator
|
|||||||
from flask_babel import gettext as _
|
from flask_babel import gettext as _
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
|
|
||||||
def update_download(book_id, user_id):
|
def update_download(book_id, user_id):
|
||||||
check = ub.session.query(ub.Downloads).filter(ub.Downloads.user_id == user_id).filter(ub.Downloads.book_id == book_id).first()
|
check = ub.session.query(ub.Downloads).filter(ub.Downloads.user_id == user_id).filter(ub.Downloads.book_id ==
|
||||||
|
book_id).first()
|
||||||
|
|
||||||
if not check:
|
if not check:
|
||||||
new_download = ub.Downloads(user_id=user_id, book_id=book_id)
|
new_download = ub.Downloads(user_id=user_id, book_id=book_id)
|
||||||
ub.session.add(new_download)
|
ub.session.add(new_download)
|
||||||
ub.session.commit()
|
ub.session.commit()
|
||||||
|
|
||||||
|
|
||||||
def make_mobi(book_id):
|
def make_mobi(book_id):
|
||||||
if sys.platform =="win32":
|
if sys.platform == "win32":
|
||||||
kindlegen = os.path.join(config.MAIN_DIR, "vendor", u"kindlegen.exe")
|
kindlegen = os.path.join(config.MAIN_DIR, "vendor", u"kindlegen.exe")
|
||||||
else:
|
else:
|
||||||
kindlegen = os.path.join(config.MAIN_DIR, "vendor", u"kindlegen")
|
kindlegen = os.path.join(config.MAIN_DIR, "vendor", u"kindlegen")
|
||||||
@ -45,9 +50,17 @@ def make_mobi(book_id):
|
|||||||
|
|
||||||
file_path = os.path.join(config.DB_ROOT, book.path, data.name)
|
file_path = os.path.join(config.DB_ROOT, book.path, data.name)
|
||||||
if os.path.exists(file_path + u".epub"):
|
if os.path.exists(file_path + u".epub"):
|
||||||
p = subprocess.Popen((kindlegen + " \"" + file_path + u".epub\" ").encode(sys.getfilesystemencoding()), shell=True, stdout=subprocess.PIPE,
|
p = subprocess.Popen((kindlegen + " \"" + file_path + u".epub\" ").encode(sys.getfilesystemencoding()),
|
||||||
stderr=subprocess.PIPE, stdin=subprocess.PIPE)
|
shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
|
||||||
check = p.wait()
|
# Poll process for new output until finished
|
||||||
|
while True:
|
||||||
|
nextline = p.stdout.readline()
|
||||||
|
if nextline == '' and p.poll() is not None:
|
||||||
|
break
|
||||||
|
if nextline != "\r\n":
|
||||||
|
app.logger.debug(nextline.strip('\r\n'))
|
||||||
|
|
||||||
|
check = p.returncode
|
||||||
if not check or check < 2:
|
if not check or check < 2:
|
||||||
book.data.append(db.Data(
|
book.data.append(db.Data(
|
||||||
name=book.data[0].name,
|
name=book.data[0].name,
|
||||||
@ -64,8 +77,67 @@ def make_mobi(book_id):
|
|||||||
app.logger.error("make_mobie: epub not found: %s.epub" % file_path)
|
app.logger.error("make_mobie: epub not found: %s.epub" % file_path)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
class StderrLogger(object):
|
||||||
|
|
||||||
|
buffer=''
|
||||||
|
def __init__(self):
|
||||||
|
self.logger = logging.getLogger('cps.web')
|
||||||
|
|
||||||
|
def write(self, message):
|
||||||
|
if message=='\n':
|
||||||
|
self.logger.debug(self.buffer)
|
||||||
|
self.buffer=''
|
||||||
|
else:
|
||||||
|
self.buffer=self.buffer+message
|
||||||
|
|
||||||
|
def send_test_mail(kindle_mail):
|
||||||
|
settings = ub.get_mail_settings()
|
||||||
|
msg = MIMEMultipart()
|
||||||
|
msg['From'] = settings["mail_from"]
|
||||||
|
msg['To'] = kindle_mail
|
||||||
|
msg['Subject'] = _('Calibre-web test email')
|
||||||
|
text = _('This email has been sent via calibre web.')
|
||||||
|
|
||||||
|
use_ssl = settings.get('mail_use_ssl', 0)
|
||||||
|
|
||||||
|
# convert MIME message to string
|
||||||
|
fp = StringIO()
|
||||||
|
gen = Generator(fp, mangle_from_=False)
|
||||||
|
gen.flatten(msg)
|
||||||
|
msg = fp.getvalue()
|
||||||
|
|
||||||
|
# send email
|
||||||
|
try:
|
||||||
|
timeout=600 # set timeout to 5mins
|
||||||
|
|
||||||
|
org_stderr = smtplib.stderr
|
||||||
|
smtplib.stderr = StderrLogger()
|
||||||
|
|
||||||
|
mailserver = smtplib.SMTP(settings["mail_server"], settings["mail_port"],timeout)
|
||||||
|
mailserver.set_debuglevel(1)
|
||||||
|
|
||||||
|
if int(use_ssl) == 1:
|
||||||
|
mailserver.ehlo()
|
||||||
|
mailserver.starttls()
|
||||||
|
mailserver.ehlo()
|
||||||
|
|
||||||
|
if settings["mail_password"]:
|
||||||
|
mailserver.login(settings["mail_login"], settings["mail_password"])
|
||||||
|
mailserver.sendmail(settings["mail_login"], kindle_mail, msg)
|
||||||
|
mailserver.quit()
|
||||||
|
|
||||||
|
smtplib.stderr = org_stderr
|
||||||
|
|
||||||
|
except (socket.error, smtplib.SMTPRecipientsRefused, smtplib.SMTPException), e:
|
||||||
|
app.logger.error(traceback.print_exc())
|
||||||
|
return _("Failed to send mail: %s" % str(e))
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def send_mail(book_id, kindle_mail):
|
def send_mail(book_id, kindle_mail):
|
||||||
'''Send email with attachments'''
|
"""Send email with attachments"""
|
||||||
is_mobi = False
|
is_mobi = False
|
||||||
is_azw = False
|
is_azw = False
|
||||||
is_azw3 = False
|
is_azw3 = False
|
||||||
@ -84,7 +156,7 @@ def send_mail(book_id, kindle_mail):
|
|||||||
use_ssl = settings.get('mail_use_ssl', 0)
|
use_ssl = settings.get('mail_use_ssl', 0)
|
||||||
|
|
||||||
# attach files
|
# attach files
|
||||||
#msg.attach(self.get_attachment(file_path))
|
# msg.attach(self.get_attachment(file_path))
|
||||||
|
|
||||||
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()
|
||||||
data = db.session.query(db.Data).filter(db.Data.book == book.id)
|
data = db.session.query(db.Data).filter(db.Data.book == book.id)
|
||||||
@ -125,8 +197,13 @@ def send_mail(book_id, kindle_mail):
|
|||||||
|
|
||||||
# send email
|
# send email
|
||||||
try:
|
try:
|
||||||
mailserver = smtplib.SMTP(settings["mail_server"],settings["mail_port"])
|
timeout=600 # set timeout to 5mins
|
||||||
mailserver.set_debuglevel(0)
|
|
||||||
|
org_stderr = smtplib.stderr
|
||||||
|
smtplib.stderr = StderrLogger()
|
||||||
|
|
||||||
|
mailserver = smtplib.SMTP(settings["mail_server"], settings["mail_port"],timeout)
|
||||||
|
mailserver.set_debuglevel(1)
|
||||||
|
|
||||||
if int(use_ssl) == 1:
|
if int(use_ssl) == 1:
|
||||||
mailserver.ehlo()
|
mailserver.ehlo()
|
||||||
@ -137,6 +214,9 @@ def send_mail(book_id, kindle_mail):
|
|||||||
mailserver.login(settings["mail_login"], settings["mail_password"])
|
mailserver.login(settings["mail_login"], settings["mail_password"])
|
||||||
mailserver.sendmail(settings["mail_login"], kindle_mail, msg)
|
mailserver.sendmail(settings["mail_login"], kindle_mail, msg)
|
||||||
mailserver.quit()
|
mailserver.quit()
|
||||||
|
|
||||||
|
smtplib.stderr = org_stderr
|
||||||
|
|
||||||
except (socket.error, smtplib.SMTPRecipientsRefused, smtplib.SMTPException), e:
|
except (socket.error, smtplib.SMTPRecipientsRefused, smtplib.SMTPException), e:
|
||||||
app.logger.error(traceback.print_exc())
|
app.logger.error(traceback.print_exc())
|
||||||
return _("Failed to send mail: %s" % str(e))
|
return _("Failed to send mail: %s" % str(e))
|
||||||
@ -145,7 +225,7 @@ def send_mail(book_id, kindle_mail):
|
|||||||
|
|
||||||
|
|
||||||
def get_attachment(file_path):
|
def get_attachment(file_path):
|
||||||
'''Get file as MIMEBase message'''
|
"""Get file as MIMEBase message"""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
file_ = open(file_path, 'rb')
|
file_ = open(file_path, 'rb')
|
||||||
@ -163,6 +243,7 @@ def get_attachment(file_path):
|
|||||||
'permissions?'))
|
'permissions?'))
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def get_valid_filename(value, replace_whitespace=True):
|
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
|
||||||
@ -178,6 +259,7 @@ def get_valid_filename(value, replace_whitespace=True):
|
|||||||
value = value.replace(u"\u00DF", "ss")
|
value = value.replace(u"\u00DF", "ss")
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
def get_normalized_author(value):
|
def get_normalized_author(value):
|
||||||
"""
|
"""
|
||||||
Normalizes sorted author name
|
Normalizes sorted author name
|
||||||
@ -187,13 +269,14 @@ def get_normalized_author(value):
|
|||||||
value = " ".join(value.split(", ")[::-1])
|
value = " ".join(value.split(", ")[::-1])
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
def update_dir_stucture(book_id):
|
def update_dir_stucture(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()
|
||||||
path = os.path.join(config.DB_ROOT, book.path)
|
path = os.path.join(config.DB_ROOT, book.path)
|
||||||
|
|
||||||
authordir = book.path.split(os.sep)[0]
|
authordir = book.path.split(os.sep)[0]
|
||||||
new_authordir=get_valid_filename(book.authors[0].name, False)
|
new_authordir = get_valid_filename(book.authors[0].name, False)
|
||||||
titledir = book.path.split(os.sep)[1]
|
titledir = book.path.split(os.sep)[1]
|
||||||
new_titledir = get_valid_filename(book.title, False) + " (" + str(book_id) + ")"
|
new_titledir = get_valid_filename(book.title, False) + " (" + str(book_id) + ")"
|
||||||
|
|
||||||
@ -208,4 +291,3 @@ def update_dir_stucture(book_id):
|
|||||||
os.renames(path, new_author_path)
|
os.renames(path, new_author_path)
|
||||||
book.path = new_authordir + os.sep + book.path.split(os.sep)[1]
|
book.path = new_authordir + os.sep + book.path.split(os.sep)[1]
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
|
@ -27,7 +27,8 @@
|
|||||||
<label for="mail_from">{{_('From e-mail')}}</label>
|
<label for="mail_from">{{_('From e-mail')}}</label>
|
||||||
<input type="text" class="form-control" name="mail_from" id="mail_from" value="{{content.mail_from}}">
|
<input type="text" class="form-control" name="mail_from" id="mail_from" value="{{content.mail_from}}">
|
||||||
</div>
|
</div>
|
||||||
<button type="submit" class="btn btn-default">{{_('Submit')}}</button>
|
<button type="submit" name="submit" value="submit" class="btn btn-default">{{_('Save settings')}}</button>
|
||||||
|
<button type="submit" name="test" value="test" class="btn btn-default">{{_('Save settings and send Test E-Mail')}}</button>
|
||||||
<a href="{{ url_for('user_list') }}" class="btn btn-default">{{_('Back')}}</a>
|
<a href="{{ url_for('user_list') }}" class="btn btn-default">{{_('Back')}}</a>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
@ -1,7 +1,45 @@
|
|||||||
{% extends "layout.html" %}
|
{% extends "layout.html" %}
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<div class="discover">
|
<h3>{{_('Linked libraries')}}</h3>
|
||||||
<h2>{{bookcounter}} {{_('Books in this Library')}}</h2>
|
|
||||||
<h2>{{authorcounter}} {{_('Authors in this Library')}}</h2>
|
<table class="table">
|
||||||
</div>
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>{{_('Program library')}}</th>
|
||||||
|
<th>{{_('Installed Version')}}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<th>Python</th>
|
||||||
|
<td>{{Versions['PythonVersion']}}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Kindlegen</th>
|
||||||
|
<td>{{Versions['KindlegenVersion']}}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>ImageMagick</th>
|
||||||
|
<td>{{Versions['ImageVersion']}}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>PyPDF2</th>
|
||||||
|
<td>{{Versions['PyPdfVersion']}}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<h3>{{_('Calibre library statistics')}}</h3>
|
||||||
|
<table 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>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
@ -40,7 +40,6 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
{% if g.user and g.user.role_admin() and not profile %}
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<input type="checkbox" name="show_random" {% if content.random_books %}checked{% endif %}>
|
<input type="checkbox" name="show_random" {% if content.random_books %}checked{% endif %}>
|
||||||
<label for="show_random">{{_('Show random books')}}</label>
|
<label for="show_random">{{_('Show random books')}}</label>
|
||||||
@ -62,6 +61,8 @@
|
|||||||
<label for="show_category">{{_('Show category selection')}}</label>
|
<label for="show_category">{{_('Show category selection')}}</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{% if g.user and g.user.role_admin() and not profile %}
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<input type="checkbox" name="admin_role" id="admin_role" {% if content.role_admin() %}checked{% endif %}>
|
<input type="checkbox" name="admin_role" id="admin_role" {% if content.role_admin() %}checked{% endif %}>
|
||||||
<label for="admin_role">{{_('Admin user')}}</label>
|
<label for="admin_role">{{_('Admin user')}}</label>
|
||||||
|
Binary file not shown.
@ -7,7 +7,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PROJECT VERSION\n"
|
"Project-Id-Version: PROJECT VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||||
"POT-Creation-Date: 2016-11-12 09:44+0100\n"
|
"POT-Creation-Date: 2016-12-23 08:39+0100\n"
|
||||||
"PO-Revision-Date: 2016-07-12 19:54+0200\n"
|
"PO-Revision-Date: 2016-07-12 19:54+0200\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language: de\n"
|
"Language: de\n"
|
||||||
@ -18,250 +18,272 @@ msgstr ""
|
|||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Generated-By: Babel 2.3.4\n"
|
"Generated-By: Babel 2.3.4\n"
|
||||||
|
|
||||||
#: cps/helper.py:80 cps/templates/detail.html:113
|
#: cps/book_formats.py:108 cps/book_formats.py:112 cps/web.py:923
|
||||||
msgid "Send to Kindle"
|
msgid "not installed"
|
||||||
msgstr "An Kindle senden"
|
msgstr "Nicht installiert"
|
||||||
|
|
||||||
#: cps/helper.py:81
|
#: cps/helper.py:93
|
||||||
|
msgid "Calibre-web test email"
|
||||||
|
msgstr "Calibre-web Test E-Mail"
|
||||||
|
|
||||||
|
#: cps/helper.py:94 cps/helper.py:147
|
||||||
msgid "This email has been sent via calibre web."
|
msgid "This email has been sent via calibre web."
|
||||||
msgstr "Die E-Mail wurde via calibre-web versendet"
|
msgstr "Die E-Mail wurde via calibre-web versendet"
|
||||||
|
|
||||||
#: cps/helper.py:103 cps/helper.py:118
|
#: cps/helper.py:128 cps/helper.py:216
|
||||||
|
#, python-format
|
||||||
|
msgid "Failed to send mail: %s"
|
||||||
|
msgstr "E-Mail: %s konnte nicht gesendet werden"
|
||||||
|
|
||||||
|
#: cps/helper.py:146 cps/templates/detail.html:113
|
||||||
|
msgid "Send to Kindle"
|
||||||
|
msgstr "An Kindle senden"
|
||||||
|
|
||||||
|
#: cps/helper.py:169 cps/helper.py:184
|
||||||
msgid "Could not find any formats suitable for sending by email"
|
msgid "Could not find any formats suitable for sending by email"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Konnte keine Formate finden welche für das versenden per E-Mail geeignet "
|
"Konnte keine Formate finden welche für das versenden per E-Mail geeignet "
|
||||||
"sind"
|
"sind"
|
||||||
|
|
||||||
#: cps/helper.py:112
|
#: cps/helper.py:178
|
||||||
msgid "Could not convert epub to mobi"
|
msgid "Could not convert epub to mobi"
|
||||||
msgstr "Konnte .epub nicht nach .mobi convertieren"
|
msgstr "Konnte .epub nicht nach .mobi konvertieren"
|
||||||
|
|
||||||
#: cps/helper.py:142
|
#: cps/helper.py:236
|
||||||
#, python-format
|
|
||||||
msgid "Failed to send mail: %s"
|
|
||||||
msgstr "E-Mail: %s konnte nicht gesendet werden"
|
|
||||||
|
|
||||||
#: cps/helper.py:162
|
|
||||||
msgid "The requested file could not be read. Maybe wrong permissions?"
|
msgid "The requested file could not be read. Maybe wrong permissions?"
|
||||||
msgstr "Die angeforderte Datei konnte nicht gelesen werden. Falsche Dateirechte?"
|
msgstr "Die angeforderte Datei konnte nicht gelesen werden. Falsche Dateirechte?"
|
||||||
|
|
||||||
#: cps/web.py:639
|
#: cps/web.py:717
|
||||||
msgid "Latest Books"
|
msgid "Latest Books"
|
||||||
msgstr "Letzte Bücher"
|
msgstr "Letzte Bücher"
|
||||||
|
|
||||||
#: cps/web.py:661
|
#: cps/web.py:742
|
||||||
msgid "Hot Books (most downloaded)"
|
msgid "Hot Books (most downloaded)"
|
||||||
msgstr "Beliebte Bücher (die meisten Downloads)"
|
msgstr "Beliebte Bücher (die meisten Downloads)"
|
||||||
|
|
||||||
#: cps/templates/index.xml:41 cps/web.py:668
|
#: cps/templates/index.xml:41 cps/web.py:750
|
||||||
msgid "Random Books"
|
msgid "Random Books"
|
||||||
msgstr "Zufällige Bücher"
|
msgstr "Zufällige Bücher"
|
||||||
|
|
||||||
#: cps/web.py:679
|
#: cps/web.py:763
|
||||||
msgid "Author list"
|
msgid "Author list"
|
||||||
msgstr "Autorenliste"
|
msgstr "Autorenliste"
|
||||||
|
|
||||||
#: cps/web.py:695
|
#: cps/web.py:780
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Author: %(nam)s"
|
msgid "Author: %(nam)s"
|
||||||
msgstr "Autor: %(nam)s"
|
msgstr "Autor: %(nam)s"
|
||||||
|
|
||||||
#: cps/templates/index.xml:65 cps/web.py:706
|
#: cps/templates/index.xml:65 cps/web.py:793
|
||||||
msgid "Series list"
|
msgid "Series list"
|
||||||
msgstr "Liste Serien"
|
msgstr "Liste Serien"
|
||||||
|
|
||||||
#: cps/web.py:714
|
#: cps/web.py:804
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Series: %(serie)s"
|
msgid "Series: %(serie)s"
|
||||||
msgstr "Serie: %(serie)s"
|
msgstr "Serie: %(serie)s"
|
||||||
|
|
||||||
#: cps/web.py:716 cps/web.py:796 cps/web.py:914 cps/web.py:1524
|
#: cps/web.py:806 cps/web.py:902 cps/web.py:1061 cps/web.py:1729
|
||||||
msgid "Error opening eBook. File does not exist or file is not accessible:"
|
msgid "Error opening eBook. File does not exist or file is not accessible:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Buch öffnen fehlgeschlagen. Datei existiert nicht, oder ist nicht "
|
"Buch öffnen fehlgeschlagen. Datei existiert nicht, oder ist nicht "
|
||||||
"zugänglich."
|
"zugänglich."
|
||||||
|
|
||||||
#: cps/web.py:742
|
#: cps/web.py:837
|
||||||
msgid "Available languages"
|
msgid "Available languages"
|
||||||
msgstr "Verfügbare Sprachen"
|
msgstr "Verfügbare Sprachen"
|
||||||
|
|
||||||
#: cps/web.py:754
|
#: cps/web.py:852
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Language: %(name)s"
|
msgid "Language: %(name)s"
|
||||||
msgstr "Sprache: %(name)s"
|
msgstr "Sprache: %(name)s"
|
||||||
|
|
||||||
#: cps/templates/index.xml:57 cps/web.py:765
|
#: cps/templates/index.xml:57 cps/web.py:865
|
||||||
msgid "Category list"
|
msgid "Category list"
|
||||||
msgstr "Kategorieliste"
|
msgstr "Kategorieliste"
|
||||||
|
|
||||||
#: cps/web.py:772
|
#: cps/web.py:875
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Category: %(name)s"
|
msgid "Category: %(name)s"
|
||||||
msgstr "Kategorie: %(name)s"
|
msgstr "Kategorie: %(name)s"
|
||||||
|
|
||||||
#: cps/web.py:810
|
#: cps/web.py:931
|
||||||
msgid "Statistics"
|
msgid "Statistics"
|
||||||
msgstr "Statistiken"
|
msgstr "Statistiken"
|
||||||
|
|
||||||
#: cps/web.py:898 cps/web.py:905 cps/web.py:912
|
#: cps/web.py:939
|
||||||
|
msgid "Server restarts"
|
||||||
|
msgstr "Server startet neu"
|
||||||
|
|
||||||
|
#: cps/web.py:1037 cps/web.py:1044 cps/web.py:1051 cps/web.py:1058
|
||||||
msgid "Read a Book"
|
msgid "Read a Book"
|
||||||
msgstr "Lese ein Buch"
|
msgstr "Lese ein Buch"
|
||||||
|
|
||||||
#: cps/web.py:951 cps/web.py:1179
|
#: cps/web.py:1100 cps/web.py:1365
|
||||||
msgid "Please fill out all fields!"
|
msgid "Please fill out all fields!"
|
||||||
msgstr "Bitte alle Felder ausfüllen!"
|
msgstr "Bitte alle Felder ausfüllen!"
|
||||||
|
|
||||||
#: cps/web.py:967
|
#: cps/web.py:1116
|
||||||
msgid "An unknown error occured. Please try again later."
|
msgid "An unknown error occured. Please try again later."
|
||||||
msgstr "Es ist ein unbekannter Fehler aufgetreten. Bitte später erneut versuchen."
|
msgstr "Es ist ein unbekannter Fehler aufgetreten. Bitte später erneut versuchen."
|
||||||
|
|
||||||
#: cps/web.py:972
|
#: cps/web.py:1121
|
||||||
msgid "This username or email address is already in use."
|
msgid "This username or email address is already in use."
|
||||||
msgstr "Der Benutzername oder die E-Mailadresse ist in bereits in Benutzung."
|
msgstr "Der Benutzername oder die E-Mailadresse ist in bereits in Benutzung."
|
||||||
|
|
||||||
#: cps/web.py:975
|
#: cps/web.py:1124
|
||||||
msgid "register"
|
msgid "register"
|
||||||
msgstr "Registieren"
|
msgstr "Registieren"
|
||||||
|
|
||||||
#: cps/web.py:990
|
#: cps/web.py:1140
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "you are now logged in as: '%(nickname)s'"
|
msgid "you are now logged in as: '%(nickname)s'"
|
||||||
msgstr "Du bist nun eingeloggt als '%(nickname)s'"
|
msgstr "Du bist nun eingeloggt als '%(nickname)s'"
|
||||||
|
|
||||||
#: cps/web.py:993
|
#: cps/web.py:1143
|
||||||
msgid "Wrong Username or Password"
|
msgid "Wrong Username or Password"
|
||||||
msgstr "Flascher Benutzername oder Passwort"
|
msgstr "Flascher Benutzername oder Passwort"
|
||||||
|
|
||||||
#: cps/web.py:995
|
#: cps/web.py:1145
|
||||||
msgid "login"
|
msgid "login"
|
||||||
msgstr "Login"
|
msgstr "Login"
|
||||||
|
|
||||||
#: cps/web.py:1011
|
#: cps/web.py:1162
|
||||||
msgid "Please configure the SMTP mail settings first..."
|
msgid "Please configure the SMTP mail settings first..."
|
||||||
msgstr "Bitte zuerst die SMTP Mail Einstellung konfigurieren ..."
|
msgstr "Bitte zuerst die SMTP Mail Einstellung konfigurieren ..."
|
||||||
|
|
||||||
#: cps/web.py:1015
|
#: cps/web.py:1166
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Book successfully send to %(kindlemail)s"
|
msgid "Book successfully send to %(kindlemail)s"
|
||||||
msgstr "Buch erfolgreich versandt an %(kindlemail)s"
|
msgstr "Buch erfolgreich versandt an %(kindlemail)s"
|
||||||
|
|
||||||
#: cps/web.py:1018
|
#: cps/web.py:1170
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "There was an error sending this book: %(res)s"
|
msgid "There was an error sending this book: %(res)s"
|
||||||
msgstr "Beim Senden des Buchs trat ein Fehler auf: %(res)s"
|
msgstr "Beim Senden des Buchs trat ein Fehler auf: %(res)s"
|
||||||
|
|
||||||
#: cps/web.py:1020
|
#: cps/web.py:1172
|
||||||
msgid "Please configure your kindle email address first..."
|
msgid "Please configure your kindle email address first..."
|
||||||
msgstr "Bitte die Kindle E-Mail Adresse zuuerst konfigurieren..."
|
msgstr "Bitte die Kindle E-Mail Adresse zuuerst konfigurieren..."
|
||||||
|
|
||||||
#: cps/web.py:1035
|
#: cps/web.py:1188
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Book has been added to shelf: %(sname)s"
|
msgid "Book has been added to shelf: %(sname)s"
|
||||||
msgstr "Das Buch wurde dem Bücherregal: %(sname)s hinzugefügt"
|
msgstr "Das Buch wurde dem Bücherregal: %(sname)s hinzugefügt"
|
||||||
|
|
||||||
#: cps/web.py:1054
|
#: cps/web.py:1209
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Book has been removed from shelf: %(sname)s"
|
msgid "Book has been removed from shelf: %(sname)s"
|
||||||
msgstr "Das Buch wurde aus dem Bücherregal: %(sname)s entfernt"
|
msgstr "Das Buch wurde aus dem Bücherregal: %(sname)s entfernt"
|
||||||
|
|
||||||
#: cps/web.py:1070
|
#: cps/web.py:1226
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "A shelf with the name '%(title)s' already exists."
|
msgid "A shelf with the name '%(title)s' already exists."
|
||||||
msgstr "Es existiert bereits ein Bücheregal mit dem Titel '%(title)s'"
|
msgstr "Es existiert bereits ein Bücheregal mit dem Titel '%(title)s'"
|
||||||
|
|
||||||
#: cps/web.py:1075
|
#: cps/web.py:1231
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Shelf %(title)s created"
|
msgid "Shelf %(title)s created"
|
||||||
msgstr "Bücherregal %(title)s erzeugt"
|
msgstr "Bücherregal %(title)s erzeugt"
|
||||||
|
|
||||||
#: cps/web.py:1077
|
#: cps/web.py:1233
|
||||||
msgid "There was an error"
|
msgid "There was an error"
|
||||||
msgstr "Es trat ein Fehler auf"
|
msgstr "Es trat ein Fehler auf"
|
||||||
|
|
||||||
#: cps/web.py:1078 cps/web.py:1080
|
#: cps/web.py:1234 cps/web.py:1236
|
||||||
msgid "create a shelf"
|
msgid "create a shelf"
|
||||||
msgstr "Bücherregal erzeugen"
|
msgstr "Bücherregal erzeugen"
|
||||||
|
|
||||||
#: cps/web.py:1096
|
#: cps/web.py:1256
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "successfully deleted shelf %(name)s"
|
msgid "successfully deleted shelf %(name)s"
|
||||||
msgstr "Bücherregal %(name)s erfolgreich gelöscht"
|
msgstr "Bücherregal %(name)s erfolgreich gelöscht"
|
||||||
|
|
||||||
#: cps/web.py:1113
|
#: cps/web.py:1277
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Shelf: '%(name)s'"
|
msgid "Shelf: '%(name)s'"
|
||||||
msgstr "Bücherregal: '%(name)s'"
|
msgstr "Bücherregal: '%(name)s'"
|
||||||
|
|
||||||
#: cps/web.py:1150
|
#: cps/web.py:1332
|
||||||
msgid "Found an existing account for this email address."
|
msgid "Found an existing account for this email address."
|
||||||
msgstr "Es existiert ein Benutzerkonto für diese E-Mailadresse"
|
msgstr "Es existiert ein Benutzerkonto für diese E-Mailadresse"
|
||||||
|
|
||||||
#: cps/web.py:1151 cps/web.py:1153
|
#: cps/web.py:1334 cps/web.py:1337
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "%(name)s's profile"
|
msgid "%(name)s's profile"
|
||||||
msgstr "%(name)s's Profil"
|
msgstr "%(name)s's Profil"
|
||||||
|
|
||||||
#: cps/web.py:1152
|
#: cps/web.py:1335
|
||||||
msgid "Profile updated"
|
msgid "Profile updated"
|
||||||
msgstr "Profil aktualisiert"
|
msgstr "Profil aktualisiert"
|
||||||
|
|
||||||
#: cps/web.py:1161
|
#: cps/web.py:1346
|
||||||
msgid "User list"
|
msgid "User list"
|
||||||
msgstr "Benutzerliste"
|
msgstr "Benutzerliste"
|
||||||
|
|
||||||
#: cps/templates/user_list.html:32 cps/web.py:1180
|
#: cps/templates/user_list.html:32 cps/web.py:1366
|
||||||
msgid "Add new user"
|
msgid "Add new user"
|
||||||
msgstr "Neuen Benutzer hinzufügen"
|
msgstr "Neuen Benutzer hinzufügen"
|
||||||
|
|
||||||
#: cps/web.py:1213
|
#: cps/web.py:1399
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "User '%(user)s' created"
|
msgid "User '%(user)s' created"
|
||||||
msgstr "Benutzer '%(user)s' angelegt"
|
msgstr "Benutzer '%(user)s' angelegt"
|
||||||
|
|
||||||
#: cps/web.py:1217
|
#: cps/web.py:1403
|
||||||
msgid "Found an existing account for this email address or nickname."
|
msgid "Found an existing account for this email address or nickname."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Es existiert ein Benutzerkonto für diese Emailadresse oder den "
|
"Es existiert ein Benutzerkonto für diese Emailadresse oder den "
|
||||||
"Benutzernamen"
|
"Benutzernamen"
|
||||||
|
|
||||||
#: cps/web.py:1238
|
#: cps/web.py:1426 cps/web.py:1437
|
||||||
msgid "Mail settings updated"
|
msgid "Mail settings updated"
|
||||||
msgstr "E-Mail Einstellungen aktualisiert"
|
msgstr "E-Mail Einstellungen aktualisiert"
|
||||||
|
|
||||||
#: cps/web.py:1241
|
#: cps/web.py:1432
|
||||||
|
#, python-format
|
||||||
|
msgid "Test E-Mail successfully send to %(kindlemail)s"
|
||||||
|
msgstr "Test E-Mail erfolgreich an %(kindlemail)s versendet"
|
||||||
|
|
||||||
|
#: cps/web.py:1435
|
||||||
|
#, python-format
|
||||||
|
msgid "There was an error sending the Test E-Mail: %(res)s"
|
||||||
|
msgstr "Fehler beim versenden der Test E-Mail: %(res)s"
|
||||||
|
|
||||||
|
#: cps/web.py:1438
|
||||||
msgid "Edit mail settings"
|
msgid "Edit mail settings"
|
||||||
msgstr "E-Mail Einstellungen editieren"
|
msgstr "E-Mail Einstellungen editieren"
|
||||||
|
|
||||||
#: cps/web.py:1263
|
#: cps/web.py:1461
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "User '%(nick)s' deleted"
|
msgid "User '%(nick)s' deleted"
|
||||||
msgstr "Benutzer '%(nick)s' gelöscht"
|
msgstr "Benutzer '%(nick)s' gelöscht"
|
||||||
|
|
||||||
#: cps/web.py:1318
|
#: cps/web.py:1516
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "User '%(nick)s' updated"
|
msgid "User '%(nick)s' updated"
|
||||||
msgstr "Benutzer '%(nick)s' aktualisiert"
|
msgstr "Benutzer '%(nick)s' aktualisiert"
|
||||||
|
|
||||||
#: cps/web.py:1321
|
#: cps/web.py:1519
|
||||||
msgid "An unknown error occured."
|
msgid "An unknown error occured."
|
||||||
msgstr "Es ist ein unbekanter Fehler aufgetreten"
|
msgstr "Es ist ein unbekanter Fehler aufgetreten"
|
||||||
|
|
||||||
#: cps/web.py:1322
|
#: cps/web.py:1521
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Edit User %(nick)s"
|
msgid "Edit User %(nick)s"
|
||||||
msgstr "Benutzer %(nick)s bearbeiten"
|
msgstr "Benutzer %(nick)s bearbeiten"
|
||||||
|
|
||||||
#: cps/web.py:1556
|
#: cps/web.py:1759
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Failed to create path %s (Permission denied)."
|
msgid "Failed to create path %s (Permission denied)."
|
||||||
msgstr "Fehler beim Erzeugen des Pfads %s (Zugriff verweigert)"
|
msgstr "Fehler beim Erzeugen des Pfads %s (Zugriff verweigert)"
|
||||||
|
|
||||||
#: cps/web.py:1561
|
#: cps/web.py:1764
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Failed to store file %s (Permission denied)."
|
msgid "Failed to store file %s (Permission denied)."
|
||||||
msgstr "Fehler beim speichern der Datei %s (Zugriff verweigert)"
|
msgstr "Fehler beim speichern der Datei %s (Zugriff verweigert)"
|
||||||
|
|
||||||
#: cps/web.py:1566
|
#: cps/web.py:1769
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Failed to delete file %s (Permission denied)."
|
msgid "Failed to delete file %s (Permission denied)."
|
||||||
msgstr "Fehler beim Löschen von Datei %s (Zugriff verweigert)"
|
msgstr "Fehler beim Löschen von Datei %s (Zugriff verweigert)"
|
||||||
@ -346,14 +368,14 @@ msgstr "Nein"
|
|||||||
msgid "view book after edit"
|
msgid "view book after edit"
|
||||||
msgstr "Buch nach Bearbeitung ansehen"
|
msgstr "Buch nach Bearbeitung ansehen"
|
||||||
|
|
||||||
#: cps/templates/edit_book.html:105 cps/templates/email_edit.html:30
|
#: cps/templates/edit_book.html:105 cps/templates/login.html:19
|
||||||
#: cps/templates/login.html:19 cps/templates/search_form.html:33
|
#: cps/templates/search_form.html:33 cps/templates/shelf_edit.html:15
|
||||||
#: cps/templates/shelf_edit.html:15 cps/templates/user_edit.html:93
|
#: cps/templates/user_edit.html:94
|
||||||
msgid "Submit"
|
msgid "Submit"
|
||||||
msgstr "Abschicken"
|
msgstr "Abschicken"
|
||||||
|
|
||||||
#: cps/templates/edit_book.html:106 cps/templates/email_edit.html:31
|
#: cps/templates/edit_book.html:106 cps/templates/email_edit.html:32
|
||||||
#: cps/templates/user_edit.html:95
|
#: cps/templates/user_edit.html:96
|
||||||
msgid "Back"
|
msgid "Back"
|
||||||
msgstr "Zurück"
|
msgstr "Zurück"
|
||||||
|
|
||||||
@ -381,6 +403,14 @@ msgstr "SMTP Passwort"
|
|||||||
msgid "From e-mail"
|
msgid "From e-mail"
|
||||||
msgstr "Absenderadresse"
|
msgstr "Absenderadresse"
|
||||||
|
|
||||||
|
#: cps/templates/email_edit.html:30
|
||||||
|
msgid "Save settings"
|
||||||
|
msgstr "Einstellungen speichern"
|
||||||
|
|
||||||
|
#: cps/templates/email_edit.html:31
|
||||||
|
msgid "Save settings and send Test E-Mail"
|
||||||
|
msgstr "Einstellungen speichern und Test E-Mail versenden"
|
||||||
|
|
||||||
#: cps/templates/feed.xml:14
|
#: cps/templates/feed.xml:14
|
||||||
msgid "Next"
|
msgid "Next"
|
||||||
msgstr "Nächste"
|
msgstr "Nächste"
|
||||||
@ -511,6 +541,14 @@ msgstr "Passwort"
|
|||||||
msgid "Remember me"
|
msgid "Remember me"
|
||||||
msgstr "Merken"
|
msgstr "Merken"
|
||||||
|
|
||||||
|
#: cps/templates/read.html:136
|
||||||
|
msgid "Reflow text when sidebars are open."
|
||||||
|
msgstr "Text umbrechen wenn Seitenleiste geöffnet ist"
|
||||||
|
|
||||||
|
#: cps/templates/readpdf.html:29
|
||||||
|
msgid "PDF.js viewer"
|
||||||
|
msgstr "PDF.js Viewer"
|
||||||
|
|
||||||
#: cps/templates/register.html:4
|
#: cps/templates/register.html:4
|
||||||
msgid "Register a new account"
|
msgid "Register a new account"
|
||||||
msgstr "Neues Benutzerkonto erzeugen"
|
msgstr "Neues Benutzerkonto erzeugen"
|
||||||
@ -551,6 +589,10 @@ msgstr "Tags ausschließen"
|
|||||||
msgid "Delete this Shelf"
|
msgid "Delete this Shelf"
|
||||||
msgstr "Lösche dieses Bücherregal"
|
msgstr "Lösche dieses Bücherregal"
|
||||||
|
|
||||||
|
#: cps/templates/shelf.html:7
|
||||||
|
msgid "Edit Shelf name"
|
||||||
|
msgstr "Bücherregal umbenennen"
|
||||||
|
|
||||||
#: cps/templates/shelf_edit.html:7
|
#: cps/templates/shelf_edit.html:7
|
||||||
msgid "Title"
|
msgid "Title"
|
||||||
msgstr "Titel"
|
msgstr "Titel"
|
||||||
@ -559,11 +601,27 @@ msgstr "Titel"
|
|||||||
msgid "should the shelf be public?"
|
msgid "should the shelf be public?"
|
||||||
msgstr "Soll das Bücherregal öffentlich sein?"
|
msgstr "Soll das Bücherregal öffentlich sein?"
|
||||||
|
|
||||||
#: cps/templates/stats.html:4
|
#: cps/templates/stats.html:3
|
||||||
|
msgid "Linked libraries"
|
||||||
|
msgstr "Dynamische Bibliotheken"
|
||||||
|
|
||||||
|
#: cps/templates/stats.html:8
|
||||||
|
msgid "Program library"
|
||||||
|
msgstr "Programm Bibliotheken"
|
||||||
|
|
||||||
|
#: cps/templates/stats.html:9
|
||||||
|
msgid "Installed Version"
|
||||||
|
msgstr "Installierte Version"
|
||||||
|
|
||||||
|
#: cps/templates/stats.html:32
|
||||||
|
msgid "Calibre library statistics"
|
||||||
|
msgstr "Calibre Bibliothek Statistiken"
|
||||||
|
|
||||||
|
#: cps/templates/stats.html:37
|
||||||
msgid "Books in this Library"
|
msgid "Books in this Library"
|
||||||
msgstr "Bücher in dieser Bibliothek"
|
msgstr "Bücher in dieser Bibliothek"
|
||||||
|
|
||||||
#: cps/templates/stats.html:5
|
#: cps/templates/stats.html:41
|
||||||
msgid "Authors in this Library"
|
msgid "Authors in this Library"
|
||||||
msgstr "Autoren in dieser Bibliothek"
|
msgstr "Autoren in dieser Bibliothek"
|
||||||
|
|
||||||
@ -579,51 +637,51 @@ msgstr "Zeige nur Bücher mit dieser Sprache"
|
|||||||
msgid "Show all"
|
msgid "Show all"
|
||||||
msgstr "Zeige alle"
|
msgstr "Zeige alle"
|
||||||
|
|
||||||
#: cps/templates/user_edit.html:46
|
#: cps/templates/user_edit.html:45
|
||||||
msgid "Show random books"
|
msgid "Show random books"
|
||||||
msgstr "Zeige Zufällige Bücher"
|
msgstr "Zeige Zufällige Bücher"
|
||||||
|
|
||||||
#: cps/templates/user_edit.html:50
|
#: cps/templates/user_edit.html:49
|
||||||
msgid "Show hot books"
|
msgid "Show hot books"
|
||||||
msgstr "Zeige Auswahl Beliebte Bücher"
|
msgstr "Zeige Auswahl Beliebte Bücher"
|
||||||
|
|
||||||
#: cps/templates/user_edit.html:54
|
#: cps/templates/user_edit.html:53
|
||||||
msgid "Show language selection"
|
msgid "Show language selection"
|
||||||
msgstr "Zeige Sprachauswahl"
|
msgstr "Zeige Sprachauswahl"
|
||||||
|
|
||||||
#: cps/templates/user_edit.html:58
|
#: cps/templates/user_edit.html:57
|
||||||
msgid "Show series selection"
|
msgid "Show series selection"
|
||||||
msgstr "Zeige Auswahl Serien"
|
msgstr "Zeige Auswahl Serien"
|
||||||
|
|
||||||
#: cps/templates/user_edit.html:62
|
#: cps/templates/user_edit.html:61
|
||||||
msgid "Show category selection"
|
msgid "Show category selection"
|
||||||
msgstr "Zeige Kategorie Auswahl"
|
msgstr "Zeige Kategorie Auswahl"
|
||||||
|
|
||||||
#: cps/templates/user_edit.html:67
|
#: cps/templates/user_edit.html:68
|
||||||
msgid "Admin user"
|
msgid "Admin user"
|
||||||
msgstr "Admin Benutzer"
|
msgstr "Admin Benutzer"
|
||||||
|
|
||||||
#: cps/templates/user_edit.html:71
|
#: cps/templates/user_edit.html:72
|
||||||
msgid "Allow Downloads"
|
msgid "Allow Downloads"
|
||||||
msgstr "Downloads erlauben"
|
msgstr "Downloads erlauben"
|
||||||
|
|
||||||
#: cps/templates/user_edit.html:75
|
#: cps/templates/user_edit.html:76
|
||||||
msgid "Allow Uploads"
|
msgid "Allow Uploads"
|
||||||
msgstr "Uploads erlauben"
|
msgstr "Uploads erlauben"
|
||||||
|
|
||||||
#: cps/templates/user_edit.html:79
|
#: cps/templates/user_edit.html:80
|
||||||
msgid "Allow Edit"
|
msgid "Allow Edit"
|
||||||
msgstr "Bearbeiten erlauben"
|
msgstr "Bearbeiten erlauben"
|
||||||
|
|
||||||
#: cps/templates/user_edit.html:83
|
#: cps/templates/user_edit.html:84
|
||||||
msgid "Allow Changing Password"
|
msgid "Allow Changing Password"
|
||||||
msgstr "Passwort ändern erlauben"
|
msgstr "Passwort ändern erlauben"
|
||||||
|
|
||||||
#: cps/templates/user_edit.html:89
|
#: cps/templates/user_edit.html:90
|
||||||
msgid "Delete this user"
|
msgid "Delete this user"
|
||||||
msgstr "Benutzer löschen"
|
msgstr "Benutzer löschen"
|
||||||
|
|
||||||
#: cps/templates/user_edit.html:100
|
#: cps/templates/user_edit.html:101
|
||||||
msgid "Recent Downloads"
|
msgid "Recent Downloads"
|
||||||
msgstr "Letzte Downloads"
|
msgstr "Letzte Downloads"
|
||||||
|
|
||||||
@ -674,6 +732,3 @@ msgstr "SMTP Einstellungen ändern"
|
|||||||
msgid "Latin"
|
msgid "Latin"
|
||||||
msgstr "Latein"
|
msgstr "Latein"
|
||||||
|
|
||||||
#~ msgid "Version"
|
|
||||||
#~ msgstr "Version"
|
|
||||||
|
|
||||||
|
Binary file not shown.
@ -1,4 +1,4 @@
|
|||||||
# Translations template for PROJECT.
|
# French translations for PROJECT.
|
||||||
# Copyright (C) 2016 ORGANIZATION
|
# Copyright (C) 2016 ORGANIZATION
|
||||||
# This file is distributed under the same license as the PROJECT project.
|
# This file is distributed under the same license as the PROJECT project.
|
||||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2016.
|
# FIRST AUTHOR <EMAIL@ADDRESS>, 2016.
|
||||||
@ -7,256 +7,281 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PROJECT VERSION\n"
|
"Project-Id-Version: PROJECT VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||||
"POT-Creation-Date: 2016-11-13 16:45+0100\n"
|
"POT-Creation-Date: 2016-12-23 08:39+0100\n"
|
||||||
"PO-Revision-Date: 2016-11-13 18:35+0100\n"
|
"PO-Revision-Date: 2016-11-13 18:35+0100\n"
|
||||||
|
"Last-Translator: Nicolas Roudninski <nicoroud@gmail.com>\n"
|
||||||
|
"Language: fr\n"
|
||||||
"Language-Team: \n"
|
"Language-Team: \n"
|
||||||
|
"Plural-Forms: nplurals=2; plural=(n > 1)\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=utf-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Generated-By: Babel 2.3.4\n"
|
"Generated-By: Babel 2.3.4\n"
|
||||||
"X-Generator: Poedit 1.8.11\n"
|
|
||||||
"Last-Translator: Nicolas Roudninski <nicoroud@gmail.com>\n"
|
|
||||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
|
||||||
"Language: fr_FR\n"
|
|
||||||
|
|
||||||
#: cps/helper.py:80 cps/templates/detail.html:113
|
#: cps/book_formats.py:108 cps/book_formats.py:112 cps/web.py:923
|
||||||
msgid "Send to Kindle"
|
msgid "not installed"
|
||||||
msgstr "Envoyer ver Kindle"
|
msgstr ""
|
||||||
|
|
||||||
#: cps/helper.py:81
|
#: cps/helper.py:93
|
||||||
|
msgid "Calibre-web test email"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: cps/helper.py:94 cps/helper.py:147
|
||||||
msgid "This email has been sent via calibre web."
|
msgid "This email has been sent via calibre web."
|
||||||
msgstr "Ce message a été envoyé depuis calibre web."
|
msgstr "Ce message a été envoyé depuis calibre web."
|
||||||
|
|
||||||
#: cps/helper.py:103 cps/helper.py:118
|
#: cps/helper.py:128 cps/helper.py:216
|
||||||
msgid "Could not find any formats suitable for sending by email"
|
|
||||||
msgstr "Impossible de trouver un format adapté à envoyer par courriel"
|
|
||||||
|
|
||||||
#: cps/helper.py:112
|
|
||||||
msgid "Could not convert epub to mobi"
|
|
||||||
msgstr "Impossible de convertir epub vers mobi"
|
|
||||||
|
|
||||||
#: cps/helper.py:142
|
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Failed to send mail: %s"
|
msgid "Failed to send mail: %s"
|
||||||
msgstr "Impossible d'envoyer le courriel : %s"
|
msgstr "Impossible d'envoyer le courriel : %s"
|
||||||
|
|
||||||
#: cps/helper.py:162
|
#: cps/helper.py:146 cps/templates/detail.html:113
|
||||||
msgid "The requested file could not be read. Maybe wrong permissions?"
|
msgid "Send to Kindle"
|
||||||
msgstr "Le fichier demandé ne peux pas être lu. Peut-être de mauvaises permissions ?"
|
msgstr "Envoyer ver Kindle"
|
||||||
|
|
||||||
#: cps/web.py:639
|
#: cps/helper.py:169 cps/helper.py:184
|
||||||
|
msgid "Could not find any formats suitable for sending by email"
|
||||||
|
msgstr "Impossible de trouver un format adapté à envoyer par courriel"
|
||||||
|
|
||||||
|
#: cps/helper.py:178
|
||||||
|
msgid "Could not convert epub to mobi"
|
||||||
|
msgstr "Impossible de convertir epub vers mobi"
|
||||||
|
|
||||||
|
#: cps/helper.py:236
|
||||||
|
msgid "The requested file could not be read. Maybe wrong permissions?"
|
||||||
|
msgstr ""
|
||||||
|
"Le fichier demandé ne peux pas être lu. Peut-être de mauvaises "
|
||||||
|
"permissions ?"
|
||||||
|
|
||||||
|
#: cps/web.py:717
|
||||||
msgid "Latest Books"
|
msgid "Latest Books"
|
||||||
msgstr "Derniers livres"
|
msgstr "Derniers livres"
|
||||||
|
|
||||||
#: cps/web.py:661
|
#: cps/web.py:742
|
||||||
msgid "Hot Books (most downloaded)"
|
msgid "Hot Books (most downloaded)"
|
||||||
msgstr "Livres populaires (les plus téléchargés)"
|
msgstr "Livres populaires (les plus téléchargés)"
|
||||||
|
|
||||||
#: cps/templates/index.xml:41 cps/web.py:668
|
#: cps/templates/index.xml:41 cps/web.py:750
|
||||||
msgid "Random Books"
|
msgid "Random Books"
|
||||||
msgstr "Livres au hasard"
|
msgstr "Livres au hasard"
|
||||||
|
|
||||||
#: cps/web.py:679
|
#: cps/web.py:763
|
||||||
msgid "Author list"
|
msgid "Author list"
|
||||||
msgstr "Liste des auteurs"
|
msgstr "Liste des auteurs"
|
||||||
|
|
||||||
#: cps/web.py:695
|
#: cps/web.py:780
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Author: %(nam)s"
|
msgid "Author: %(nam)s"
|
||||||
msgstr "Auteur : %(nam)s"
|
msgstr "Auteur : %(nam)s"
|
||||||
|
|
||||||
#: cps/templates/index.xml:65 cps/web.py:706
|
#: cps/templates/index.xml:65 cps/web.py:793
|
||||||
msgid "Series list"
|
msgid "Series list"
|
||||||
msgstr "Liste des séries"
|
msgstr "Liste des séries"
|
||||||
|
|
||||||
#: cps/web.py:714
|
#: cps/web.py:804
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Series: %(serie)s"
|
msgid "Series: %(serie)s"
|
||||||
msgstr "Séries : %(serie)s"
|
msgstr "Séries : %(serie)s"
|
||||||
|
|
||||||
#: cps/web.py:716 cps/web.py:796 cps/web.py:914 cps/web.py:1524
|
#: cps/web.py:806 cps/web.py:902 cps/web.py:1061 cps/web.py:1729
|
||||||
msgid "Error opening eBook. File does not exist or file is not accessible:"
|
msgid "Error opening eBook. File does not exist or file is not accessible:"
|
||||||
msgstr "Erreur d'ouverture du livre numérique. Le fichier n'existe pas ou n'est pas accessible :"
|
msgstr ""
|
||||||
|
"Erreur d'ouverture du livre numérique. Le fichier n'existe pas ou n'est "
|
||||||
|
"pas accessible :"
|
||||||
|
|
||||||
#: cps/web.py:742
|
#: cps/web.py:837
|
||||||
msgid "Available languages"
|
msgid "Available languages"
|
||||||
msgstr "Langues disponibles"
|
msgstr "Langues disponibles"
|
||||||
|
|
||||||
#: cps/web.py:754
|
#: cps/web.py:852
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Language: %(name)s"
|
msgid "Language: %(name)s"
|
||||||
msgstr "Langue : %(name)s"
|
msgstr "Langue : %(name)s"
|
||||||
|
|
||||||
#: cps/templates/index.xml:57 cps/web.py:765
|
#: cps/templates/index.xml:57 cps/web.py:865
|
||||||
msgid "Category list"
|
msgid "Category list"
|
||||||
msgstr "Liste des catégories"
|
msgstr "Liste des catégories"
|
||||||
|
|
||||||
#: cps/web.py:772
|
#: cps/web.py:875
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Category: %(name)s"
|
msgid "Category: %(name)s"
|
||||||
msgstr "Catégorie : %(name)s"
|
msgstr "Catégorie : %(name)s"
|
||||||
|
|
||||||
#: cps/web.py:810
|
#: cps/web.py:931
|
||||||
msgid "Statistics"
|
msgid "Statistics"
|
||||||
msgstr "Statistiques"
|
msgstr "Statistiques"
|
||||||
|
|
||||||
#: cps/web.py:898 cps/web.py:905 cps/web.py:912
|
#: cps/web.py:939
|
||||||
|
msgid "Server restarts"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: cps/web.py:1037 cps/web.py:1044 cps/web.py:1051 cps/web.py:1058
|
||||||
msgid "Read a Book"
|
msgid "Read a Book"
|
||||||
msgstr "Lire un livre"
|
msgstr "Lire un livre"
|
||||||
|
|
||||||
#: cps/web.py:951 cps/web.py:1179
|
#: cps/web.py:1100 cps/web.py:1365
|
||||||
msgid "Please fill out all fields!"
|
msgid "Please fill out all fields!"
|
||||||
msgstr "SVP, complétez tous les champs !"
|
msgstr "SVP, complétez tous les champs !"
|
||||||
|
|
||||||
#: cps/web.py:967
|
#: cps/web.py:1116
|
||||||
msgid "An unknown error occured. Please try again later."
|
msgid "An unknown error occured. Please try again later."
|
||||||
msgstr "Une erreur a eu lieu. Merci de réessayez plus tard."
|
msgstr "Une erreur a eu lieu. Merci de réessayez plus tard."
|
||||||
|
|
||||||
#: cps/web.py:972
|
#: cps/web.py:1121
|
||||||
msgid "This username or email address is already in use."
|
msgid "This username or email address is already in use."
|
||||||
msgstr "Ce nom d'utilisateur ou cette adresse de courriel est déjà utilisée."
|
msgstr "Ce nom d'utilisateur ou cette adresse de courriel est déjà utilisée."
|
||||||
|
|
||||||
#: cps/web.py:975
|
#: cps/web.py:1124
|
||||||
msgid "register"
|
msgid "register"
|
||||||
msgstr "S'enregistrer"
|
msgstr "S'enregistrer"
|
||||||
|
|
||||||
#: cps/web.py:990
|
#: cps/web.py:1140
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "you are now logged in as: '%(nickname)s'"
|
msgid "you are now logged in as: '%(nickname)s'"
|
||||||
msgstr "Vous êtes maintenant connecté sous : '%(nickname)s'"
|
msgstr "Vous êtes maintenant connecté sous : '%(nickname)s'"
|
||||||
|
|
||||||
#: cps/web.py:993
|
#: cps/web.py:1143
|
||||||
msgid "Wrong Username or Password"
|
msgid "Wrong Username or Password"
|
||||||
msgstr "Mauvais nom d'utilisateur ou mot de passe"
|
msgstr "Mauvais nom d'utilisateur ou mot de passe"
|
||||||
|
|
||||||
#: cps/web.py:995
|
#: cps/web.py:1145
|
||||||
msgid "login"
|
msgid "login"
|
||||||
msgstr "Connexion"
|
msgstr "Connexion"
|
||||||
|
|
||||||
#: cps/web.py:1011
|
#: cps/web.py:1162
|
||||||
msgid "Please configure the SMTP mail settings first..."
|
msgid "Please configure the SMTP mail settings first..."
|
||||||
msgstr "Veillez configurer les paramètres smtp d'abord..."
|
msgstr "Veillez configurer les paramètres smtp d'abord..."
|
||||||
|
|
||||||
#: cps/web.py:1015
|
#: cps/web.py:1166
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Book successfully send to %(kindlemail)s"
|
msgid "Book successfully send to %(kindlemail)s"
|
||||||
msgstr "Livres envoyés à %(kindlemail)s avec succès"
|
msgstr "Livres envoyés à %(kindlemail)s avec succès"
|
||||||
|
|
||||||
#: cps/web.py:1018
|
#: cps/web.py:1170
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "There was an error sending this book: %(res)s"
|
msgid "There was an error sending this book: %(res)s"
|
||||||
msgstr "Il y a eu une erreur en envoyant ce livre : %(res)s"
|
msgstr "Il y a eu une erreur en envoyant ce livre : %(res)s"
|
||||||
|
|
||||||
#: cps/web.py:1020
|
#: cps/web.py:1172
|
||||||
msgid "Please configure your kindle email address first..."
|
msgid "Please configure your kindle email address first..."
|
||||||
msgstr "Veuillez configurer votre adresse kindle d'abord..."
|
msgstr "Veuillez configurer votre adresse kindle d'abord..."
|
||||||
|
|
||||||
#: cps/web.py:1035
|
#: cps/web.py:1188
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Book has been added to shelf: %(sname)s"
|
msgid "Book has been added to shelf: %(sname)s"
|
||||||
msgstr "Le livre a bien été ajouté à l'étagère : %(sname)s"
|
msgstr "Le livre a bien été ajouté à l'étagère : %(sname)s"
|
||||||
|
|
||||||
#: cps/web.py:1054
|
#: cps/web.py:1209
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Book has been removed from shelf: %(sname)s"
|
msgid "Book has been removed from shelf: %(sname)s"
|
||||||
msgstr "Le livre a été supprimé de l'étagère %(sname)s"
|
msgstr "Le livre a été supprimé de l'étagère %(sname)s"
|
||||||
|
|
||||||
#: cps/web.py:1070
|
#: cps/web.py:1226
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "A shelf with the name '%(title)s' already exists."
|
msgid "A shelf with the name '%(title)s' already exists."
|
||||||
msgstr "Une étagère de ce nom '%(title)s' existe déjà."
|
msgstr "Une étagère de ce nom '%(title)s' existe déjà."
|
||||||
|
|
||||||
#: cps/web.py:1075
|
#: cps/web.py:1231
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Shelf %(title)s created"
|
msgid "Shelf %(title)s created"
|
||||||
msgstr "Étagère %(title)s créée"
|
msgstr "Étagère %(title)s créée"
|
||||||
|
|
||||||
#: cps/web.py:1077
|
#: cps/web.py:1233
|
||||||
msgid "There was an error"
|
msgid "There was an error"
|
||||||
msgstr "Il y a eu une erreur"
|
msgstr "Il y a eu une erreur"
|
||||||
|
|
||||||
#: cps/web.py:1078 cps/web.py:1080
|
#: cps/web.py:1234 cps/web.py:1236
|
||||||
msgid "create a shelf"
|
msgid "create a shelf"
|
||||||
msgstr "Créer une étagère"
|
msgstr "Créer une étagère"
|
||||||
|
|
||||||
#: cps/web.py:1096
|
#: cps/web.py:1256
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "successfully deleted shelf %(name)s"
|
msgid "successfully deleted shelf %(name)s"
|
||||||
msgstr "L'étagère %(name)s a été supprimé avec succès"
|
msgstr "L'étagère %(name)s a été supprimé avec succès"
|
||||||
|
|
||||||
#: cps/web.py:1113
|
#: cps/web.py:1277
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Shelf: '%(name)s'"
|
msgid "Shelf: '%(name)s'"
|
||||||
msgstr "Étagère : '%(name)s'"
|
msgstr "Étagère : '%(name)s'"
|
||||||
|
|
||||||
#: cps/web.py:1150
|
#: cps/web.py:1332
|
||||||
msgid "Found an existing account for this email address."
|
msgid "Found an existing account for this email address."
|
||||||
msgstr "Un compte avec cette adresse de courriel existe déjà."
|
msgstr "Un compte avec cette adresse de courriel existe déjà."
|
||||||
|
|
||||||
#: cps/web.py:1151 cps/web.py:1153
|
#: cps/web.py:1334 cps/web.py:1337
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "%(name)s's profile"
|
msgid "%(name)s's profile"
|
||||||
msgstr "Profil de %(name)s"
|
msgstr "Profil de %(name)s"
|
||||||
|
|
||||||
#: cps/web.py:1152
|
#: cps/web.py:1335
|
||||||
msgid "Profile updated"
|
msgid "Profile updated"
|
||||||
msgstr "Profil mis à jour"
|
msgstr "Profil mis à jour"
|
||||||
|
|
||||||
#: cps/web.py:1161
|
#: cps/web.py:1346
|
||||||
msgid "User list"
|
msgid "User list"
|
||||||
msgstr "Liste des ustilisateurs"
|
msgstr "Liste des ustilisateurs"
|
||||||
|
|
||||||
#: cps/templates/user_list.html:32 cps/web.py:1180
|
#: cps/templates/user_list.html:32 cps/web.py:1366
|
||||||
msgid "Add new user"
|
msgid "Add new user"
|
||||||
msgstr "Ajouter un nouvel utilisateur"
|
msgstr "Ajouter un nouvel utilisateur"
|
||||||
|
|
||||||
#: cps/web.py:1213
|
#: cps/web.py:1399
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "User '%(user)s' created"
|
msgid "User '%(user)s' created"
|
||||||
msgstr "Utilisateur '%(user)s' créé"
|
msgstr "Utilisateur '%(user)s' créé"
|
||||||
|
|
||||||
#: cps/web.py:1217
|
#: cps/web.py:1403
|
||||||
msgid "Found an existing account for this email address or nickname."
|
msgid "Found an existing account for this email address or nickname."
|
||||||
msgstr "Un compte avec cette adresse de courriel ou ce surnom existe déjà."
|
msgstr "Un compte avec cette adresse de courriel ou ce surnom existe déjà."
|
||||||
|
|
||||||
#: cps/web.py:1238
|
#: cps/web.py:1426 cps/web.py:1437
|
||||||
msgid "Mail settings updated"
|
msgid "Mail settings updated"
|
||||||
msgstr "Paramètres de courriel mis à jour"
|
msgstr "Paramètres de courriel mis à jour"
|
||||||
|
|
||||||
#: cps/web.py:1241
|
#: cps/web.py:1432
|
||||||
|
#, python-format
|
||||||
|
msgid "Test E-Mail successfully send to %(kindlemail)s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: cps/web.py:1435
|
||||||
|
#, python-format
|
||||||
|
msgid "There was an error sending the Test E-Mail: %(res)s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: cps/web.py:1438
|
||||||
msgid "Edit mail settings"
|
msgid "Edit mail settings"
|
||||||
msgstr "Éditer les paramètres de courriel"
|
msgstr "Éditer les paramètres de courriel"
|
||||||
|
|
||||||
#: cps/web.py:1263
|
#: cps/web.py:1461
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "User '%(nick)s' deleted"
|
msgid "User '%(nick)s' deleted"
|
||||||
msgstr "Utilisateur '%(nick)s' supprimé"
|
msgstr "Utilisateur '%(nick)s' supprimé"
|
||||||
|
|
||||||
#: cps/web.py:1318
|
#: cps/web.py:1516
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "User '%(nick)s' updated"
|
msgid "User '%(nick)s' updated"
|
||||||
msgstr "Utilisateur '%(nick)s' mis à jour"
|
msgstr "Utilisateur '%(nick)s' mis à jour"
|
||||||
|
|
||||||
#: cps/web.py:1321
|
#: cps/web.py:1519
|
||||||
msgid "An unknown error occured."
|
msgid "An unknown error occured."
|
||||||
msgstr "Oups ! Une erreur inconnue a eu lieu."
|
msgstr "Oups ! Une erreur inconnue a eu lieu."
|
||||||
|
|
||||||
#: cps/web.py:1322
|
#: cps/web.py:1521
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Edit User %(nick)s"
|
msgid "Edit User %(nick)s"
|
||||||
msgstr "Éditer l'utilisateur %(nick)s"
|
msgstr "Éditer l'utilisateur %(nick)s"
|
||||||
|
|
||||||
#: cps/web.py:1556
|
#: cps/web.py:1759
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Failed to create path %s (Permission denied)."
|
msgid "Failed to create path %s (Permission denied)."
|
||||||
msgstr "Impossible de créer le chemin %s (permission refusée)"
|
msgstr "Impossible de créer le chemin %s (permission refusée)"
|
||||||
|
|
||||||
#: cps/web.py:1561
|
#: cps/web.py:1764
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Failed to store file %s (Permission denied)."
|
msgid "Failed to store file %s (Permission denied)."
|
||||||
msgstr "Impossible d'enregistrer le fichier %s (permission refusée)"
|
msgstr "Impossible d'enregistrer le fichier %s (permission refusée)"
|
||||||
|
|
||||||
#: cps/web.py:1566
|
#: cps/web.py:1769
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Failed to delete file %s (Permission denied)."
|
msgid "Failed to delete file %s (Permission denied)."
|
||||||
msgstr "Impossible de supprimer le fichier %s (permission refusée)"
|
msgstr "Impossible de supprimer le fichier %s (permission refusée)"
|
||||||
@ -341,14 +366,14 @@ msgstr "Non"
|
|||||||
msgid "view book after edit"
|
msgid "view book after edit"
|
||||||
msgstr "Voir le livre après l'édition"
|
msgstr "Voir le livre après l'édition"
|
||||||
|
|
||||||
#: cps/templates/edit_book.html:105 cps/templates/email_edit.html:30
|
#: cps/templates/edit_book.html:105 cps/templates/login.html:19
|
||||||
#: cps/templates/login.html:19 cps/templates/search_form.html:33
|
#: cps/templates/search_form.html:33 cps/templates/shelf_edit.html:15
|
||||||
#: cps/templates/shelf_edit.html:15 cps/templates/user_edit.html:93
|
#: cps/templates/user_edit.html:94
|
||||||
msgid "Submit"
|
msgid "Submit"
|
||||||
msgstr "Soumettre"
|
msgstr "Soumettre"
|
||||||
|
|
||||||
#: cps/templates/edit_book.html:106 cps/templates/email_edit.html:31
|
#: cps/templates/edit_book.html:106 cps/templates/email_edit.html:32
|
||||||
#: cps/templates/user_edit.html:95
|
#: cps/templates/user_edit.html:96
|
||||||
msgid "Back"
|
msgid "Back"
|
||||||
msgstr "Retour"
|
msgstr "Retour"
|
||||||
|
|
||||||
@ -376,6 +401,14 @@ msgstr "Mot de passe smtp"
|
|||||||
msgid "From e-mail"
|
msgid "From e-mail"
|
||||||
msgstr "Expéditeur des courriels"
|
msgstr "Expéditeur des courriels"
|
||||||
|
|
||||||
|
#: cps/templates/email_edit.html:30
|
||||||
|
msgid "Save settings"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: cps/templates/email_edit.html:31
|
||||||
|
msgid "Save settings and send Test E-Mail"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: cps/templates/feed.xml:14
|
#: cps/templates/feed.xml:14
|
||||||
msgid "Next"
|
msgid "Next"
|
||||||
msgstr "Suivant"
|
msgstr "Suivant"
|
||||||
@ -506,6 +539,14 @@ msgstr "Mot de passe"
|
|||||||
msgid "Remember me"
|
msgid "Remember me"
|
||||||
msgstr "Se rappeler de moi"
|
msgstr "Se rappeler de moi"
|
||||||
|
|
||||||
|
#: cps/templates/read.html:136
|
||||||
|
msgid "Reflow text when sidebars are open."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: cps/templates/readpdf.html:29
|
||||||
|
msgid "PDF.js viewer"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: cps/templates/register.html:4
|
#: cps/templates/register.html:4
|
||||||
msgid "Register a new account"
|
msgid "Register a new account"
|
||||||
msgstr "Enregistrer un nouveau compte"
|
msgstr "Enregistrer un nouveau compte"
|
||||||
@ -546,6 +587,10 @@ msgstr "Exclure des étiquettes"
|
|||||||
msgid "Delete this Shelf"
|
msgid "Delete this Shelf"
|
||||||
msgstr "Effacer cette étagère"
|
msgstr "Effacer cette étagère"
|
||||||
|
|
||||||
|
#: cps/templates/shelf.html:7
|
||||||
|
msgid "Edit Shelf name"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: cps/templates/shelf_edit.html:7
|
#: cps/templates/shelf_edit.html:7
|
||||||
msgid "Title"
|
msgid "Title"
|
||||||
msgstr "Titre"
|
msgstr "Titre"
|
||||||
@ -554,11 +599,27 @@ msgstr "Titre"
|
|||||||
msgid "should the shelf be public?"
|
msgid "should the shelf be public?"
|
||||||
msgstr "Cette étagère doit-elle être publique ?"
|
msgstr "Cette étagère doit-elle être publique ?"
|
||||||
|
|
||||||
#: cps/templates/stats.html:4
|
#: cps/templates/stats.html:3
|
||||||
|
msgid "Linked libraries"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: cps/templates/stats.html:8
|
||||||
|
msgid "Program library"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: cps/templates/stats.html:9
|
||||||
|
msgid "Installed Version"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: cps/templates/stats.html:32
|
||||||
|
msgid "Calibre library statistics"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: cps/templates/stats.html:37
|
||||||
msgid "Books in this Library"
|
msgid "Books in this Library"
|
||||||
msgstr "Livres dans la bibiothèque"
|
msgstr "Livres dans la bibiothèque"
|
||||||
|
|
||||||
#: cps/templates/stats.html:5
|
#: cps/templates/stats.html:41
|
||||||
msgid "Authors in this Library"
|
msgid "Authors in this Library"
|
||||||
msgstr "Auteurs dans la bibliothèque"
|
msgstr "Auteurs dans la bibliothèque"
|
||||||
|
|
||||||
@ -574,51 +635,51 @@ msgstr "Montrer les livres dans la langue"
|
|||||||
msgid "Show all"
|
msgid "Show all"
|
||||||
msgstr "Montrer tout"
|
msgstr "Montrer tout"
|
||||||
|
|
||||||
#: cps/templates/user_edit.html:46
|
#: cps/templates/user_edit.html:45
|
||||||
msgid "Show random books"
|
msgid "Show random books"
|
||||||
msgstr "Montrer des livres au hasard"
|
msgstr "Montrer des livres au hasard"
|
||||||
|
|
||||||
#: cps/templates/user_edit.html:50
|
#: cps/templates/user_edit.html:49
|
||||||
msgid "Show hot books"
|
msgid "Show hot books"
|
||||||
msgstr "Montrer les livres populaires"
|
msgstr "Montrer les livres populaires"
|
||||||
|
|
||||||
#: cps/templates/user_edit.html:54
|
#: cps/templates/user_edit.html:53
|
||||||
msgid "Show language selection"
|
msgid "Show language selection"
|
||||||
msgstr "Montrer la sélection de la langue"
|
msgstr "Montrer la sélection de la langue"
|
||||||
|
|
||||||
#: cps/templates/user_edit.html:58
|
#: cps/templates/user_edit.html:57
|
||||||
msgid "Show series selection"
|
msgid "Show series selection"
|
||||||
msgstr "Montrer la sélection des séries"
|
msgstr "Montrer la sélection des séries"
|
||||||
|
|
||||||
#: cps/templates/user_edit.html:62
|
#: cps/templates/user_edit.html:61
|
||||||
msgid "Show category selection"
|
msgid "Show category selection"
|
||||||
msgstr "Montrer la sélection des catégories"
|
msgstr "Montrer la sélection des catégories"
|
||||||
|
|
||||||
#: cps/templates/user_edit.html:67
|
#: cps/templates/user_edit.html:68
|
||||||
msgid "Admin user"
|
msgid "Admin user"
|
||||||
msgstr "Utilisateur admin"
|
msgstr "Utilisateur admin"
|
||||||
|
|
||||||
#: cps/templates/user_edit.html:71
|
#: cps/templates/user_edit.html:72
|
||||||
msgid "Allow Downloads"
|
msgid "Allow Downloads"
|
||||||
msgstr "Permettre les téléchargements"
|
msgstr "Permettre les téléchargements"
|
||||||
|
|
||||||
#: cps/templates/user_edit.html:75
|
#: cps/templates/user_edit.html:76
|
||||||
msgid "Allow Uploads"
|
msgid "Allow Uploads"
|
||||||
msgstr "Permettre les téléversements"
|
msgstr "Permettre les téléversements"
|
||||||
|
|
||||||
#: cps/templates/user_edit.html:79
|
#: cps/templates/user_edit.html:80
|
||||||
msgid "Allow Edit"
|
msgid "Allow Edit"
|
||||||
msgstr "Permettre l'édition"
|
msgstr "Permettre l'édition"
|
||||||
|
|
||||||
#: cps/templates/user_edit.html:83
|
#: cps/templates/user_edit.html:84
|
||||||
msgid "Allow Changing Password"
|
msgid "Allow Changing Password"
|
||||||
msgstr "Permettre le changement de mot de passe"
|
msgstr "Permettre le changement de mot de passe"
|
||||||
|
|
||||||
#: cps/templates/user_edit.html:89
|
#: cps/templates/user_edit.html:90
|
||||||
msgid "Delete this user"
|
msgid "Delete this user"
|
||||||
msgstr "Supprimer cet utilisateur"
|
msgstr "Supprimer cet utilisateur"
|
||||||
|
|
||||||
#: cps/templates/user_edit.html:100
|
#: cps/templates/user_edit.html:101
|
||||||
msgid "Recent Downloads"
|
msgid "Recent Downloads"
|
||||||
msgstr "Téléchargements récents"
|
msgstr "Téléchargements récents"
|
||||||
|
|
||||||
@ -668,3 +729,4 @@ msgstr "Changer les paramètre smtp"
|
|||||||
|
|
||||||
msgid "Latin"
|
msgid "Latin"
|
||||||
msgstr "Latin"
|
msgstr "Latin"
|
||||||
|
|
||||||
|
60
cps/ub.py
60
cps/ub.py
@ -21,18 +21,19 @@ ROLE_EDIT = 8
|
|||||||
ROLE_PASSWD = 16
|
ROLE_PASSWD = 16
|
||||||
DEFAULT_PASS = "admin123"
|
DEFAULT_PASS = "admin123"
|
||||||
|
|
||||||
|
|
||||||
class User(Base):
|
class User(Base):
|
||||||
__tablename__ = 'user'
|
__tablename__ = 'user'
|
||||||
|
|
||||||
id = Column(Integer, primary_key = True)
|
id = Column(Integer, primary_key=True)
|
||||||
nickname = Column(String(64), unique = True)
|
nickname = Column(String(64), unique=True)
|
||||||
email = Column(String(120), unique = True, default = "")
|
email = Column(String(120), unique=True, default="")
|
||||||
role = Column(SmallInteger, default = ROLE_USER)
|
role = Column(SmallInteger, default=ROLE_USER)
|
||||||
password = Column(String)
|
password = Column(String)
|
||||||
kindle_mail = Column(String(120), default="")
|
kindle_mail = Column(String(120), default="")
|
||||||
shelf = relationship('Shelf', backref = 'user', lazy = 'dynamic')
|
shelf = relationship('Shelf', backref='user', lazy='dynamic')
|
||||||
whislist = relationship('Whislist', backref = 'user', lazy = 'dynamic')
|
whislist = relationship('Whislist', backref='user', lazy='dynamic')
|
||||||
downloads = relationship('Downloads', backref= 'user', lazy = 'dynamic')
|
downloads = relationship('Downloads', backref='user', lazy='dynamic')
|
||||||
locale = Column(String(2), default="en")
|
locale = Column(String(2), default="en")
|
||||||
random_books = Column(Integer, default=1)
|
random_books = Column(Integer, default=1)
|
||||||
language_books = Column(Integer, default=1)
|
language_books = Column(Integer, default=1)
|
||||||
@ -43,26 +44,31 @@ class User(Base):
|
|||||||
|
|
||||||
def is_authenticated(self):
|
def is_authenticated(self):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def role_admin(self):
|
def role_admin(self):
|
||||||
if self.role is not None:
|
if self.role is not None:
|
||||||
return True if self.role & ROLE_ADMIN == ROLE_ADMIN else False
|
return True if self.role & ROLE_ADMIN == ROLE_ADMIN else False
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def role_download(self):
|
def role_download(self):
|
||||||
if self.role is not None:
|
if self.role is not None:
|
||||||
return True if self.role & ROLE_DOWNLOAD == ROLE_DOWNLOAD else False
|
return True if self.role & ROLE_DOWNLOAD == ROLE_DOWNLOAD else False
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def role_upload(self):
|
def role_upload(self):
|
||||||
if self.role is not None:
|
if self.role is not None:
|
||||||
return True if self.role & ROLE_UPLOAD == ROLE_UPLOAD else False
|
return True if self.role & ROLE_UPLOAD == ROLE_UPLOAD else False
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def role_edit(self):
|
def role_edit(self):
|
||||||
if self.role is not None:
|
if self.role is not None:
|
||||||
return True if self.role & ROLE_EDIT == ROLE_EDIT else False
|
return True if self.role & ROLE_EDIT == ROLE_EDIT else False
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def role_passwd(self):
|
def role_passwd(self):
|
||||||
if self.role is not None:
|
if self.role is not None:
|
||||||
return True if self.role & ROLE_PASSWD == ROLE_PASSWD else False
|
return True if self.role & ROLE_PASSWD == ROLE_PASSWD else False
|
||||||
@ -96,20 +102,20 @@ class User(Base):
|
|||||||
def show_category(self):
|
def show_category(self):
|
||||||
return self.category_books
|
return self.category_books
|
||||||
|
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return '<User %r>' % (self.nickname)
|
return '<User %r>' % self.nickname
|
||||||
|
|
||||||
|
|
||||||
class Shelf(Base):
|
class Shelf(Base):
|
||||||
__tablename__ = 'shelf'
|
__tablename__ = 'shelf'
|
||||||
|
|
||||||
id = Column(Integer, primary_key = True)
|
id = Column(Integer, primary_key=True)
|
||||||
name = Column(String)
|
name = Column(String)
|
||||||
is_public = Column(Integer, default=0)
|
is_public = Column(Integer, default=0)
|
||||||
user_id = Column(Integer, ForeignKey('user.id'))
|
user_id = Column(Integer, ForeignKey('user.id'))
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return '<Shelf %r>' % (self.name)
|
return '<Shelf %r>' % self.name
|
||||||
|
|
||||||
|
|
||||||
class Whislist(Base):
|
class Whislist(Base):
|
||||||
@ -124,7 +130,7 @@ class Whislist(Base):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return '<Whislist %r>' % (self.name)
|
return '<Whislist %r>' % self.name
|
||||||
|
|
||||||
|
|
||||||
class BookShelf(Base):
|
class BookShelf(Base):
|
||||||
@ -135,7 +141,7 @@ class BookShelf(Base):
|
|||||||
shelf = Column(Integer, ForeignKey('shelf.id'))
|
shelf = Column(Integer, ForeignKey('shelf.id'))
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return '<Book %r>' % (self.id)
|
return '<Book %r>' % self.id
|
||||||
|
|
||||||
|
|
||||||
class Downloads(Base):
|
class Downloads(Base):
|
||||||
@ -146,7 +152,8 @@ class Downloads(Base):
|
|||||||
user_id = Column(Integer, ForeignKey('user.id'))
|
user_id = Column(Integer, ForeignKey('user.id'))
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return '<Download %r' % (self.book_id)
|
return '<Download %r' % self.book_id
|
||||||
|
|
||||||
|
|
||||||
class Whish(Base):
|
class Whish(Base):
|
||||||
__tablename__ = 'whish'
|
__tablename__ = 'whish'
|
||||||
@ -157,7 +164,8 @@ class Whish(Base):
|
|||||||
wishlist = Column(Integer, ForeignKey('wishlist.id'))
|
wishlist = Column(Integer, ForeignKey('wishlist.id'))
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return '<Whish %r>' % (self.title)
|
return '<Whish %r>' % self.title
|
||||||
|
|
||||||
|
|
||||||
class Settings(Base):
|
class Settings(Base):
|
||||||
__tablename__ = 'settings'
|
__tablename__ = 'settings'
|
||||||
@ -174,12 +182,13 @@ class Settings(Base):
|
|||||||
#return '<Smtp %r>' % (self.mail_server)
|
#return '<Smtp %r>' % (self.mail_server)
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def migrate_Database():
|
def migrate_Database():
|
||||||
try:
|
try:
|
||||||
session.query(exists().where(User.random_books)).scalar()
|
session.query(exists().where(User.random_books)).scalar()
|
||||||
session.commit()
|
session.commit()
|
||||||
except exc.OperationalError: # Database is not compatible, some rows are missing
|
except exc.OperationalError: # Database is not compatible, some rows are missing
|
||||||
conn=engine.connect()
|
conn = engine.connect()
|
||||||
conn.execute("ALTER TABLE user ADD column random_books INTEGER DEFAULT 1")
|
conn.execute("ALTER TABLE user ADD column random_books INTEGER DEFAULT 1")
|
||||||
conn.execute("ALTER TABLE user ADD column locale String(2) DEFAULT 'en'")
|
conn.execute("ALTER TABLE user ADD column locale String(2) DEFAULT 'en'")
|
||||||
conn.execute("ALTER TABLE user ADD column default_language String(3) DEFAULT 'all'")
|
conn.execute("ALTER TABLE user ADD column default_language String(3) DEFAULT 'all'")
|
||||||
@ -208,23 +217,25 @@ def create_default_config():
|
|||||||
session.add(settings)
|
session.add(settings)
|
||||||
session.commit()
|
session.commit()
|
||||||
|
|
||||||
|
|
||||||
def get_mail_settings():
|
def get_mail_settings():
|
||||||
settings = session.query(Settings).first()
|
settings = session.query(Settings).first()
|
||||||
|
|
||||||
if not settings:
|
if not settings:
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
data = {
|
data = {
|
||||||
'mail_server': settings.mail_server,
|
'mail_server': settings.mail_server,
|
||||||
'mail_port': settings.mail_port,
|
'mail_port': settings.mail_port,
|
||||||
'mail_use_ssl': settings.mail_use_ssl,
|
'mail_use_ssl': settings.mail_use_ssl,
|
||||||
'mail_login': settings.mail_login,
|
'mail_login': settings.mail_login,
|
||||||
'mail_password': settings.mail_password,
|
'mail_password': settings.mail_password,
|
||||||
'mail_from': settings.mail_from
|
'mail_from': settings.mail_from
|
||||||
}
|
}
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
def create_admin_user():
|
def create_admin_user():
|
||||||
user = User()
|
user = User()
|
||||||
user.nickname = "admin"
|
user.nickname = "admin"
|
||||||
@ -251,4 +262,3 @@ if not os.path.exists(dbpath):
|
|||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
migrate_Database()
|
migrate_Database()
|
||||||
|
|
||||||
|
@ -9,6 +9,8 @@ BookMeta = namedtuple('BookMeta', 'file_path, extension, title, author, cover, d
|
|||||||
"""
|
"""
|
||||||
:rtype: BookMeta
|
:rtype: BookMeta
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def upload(file):
|
def upload(file):
|
||||||
tmp_dir = os.path.join(gettempdir(), 'calibre_web')
|
tmp_dir = os.path.join(gettempdir(), 'calibre_web')
|
||||||
|
|
||||||
@ -23,7 +25,3 @@ def upload(file):
|
|||||||
file.save(tmp_file_path)
|
file.save(tmp_file_path)
|
||||||
meta = book_formats.process(tmp_file_path, filename_root, file_extension)
|
meta = book_formats.process(tmp_file_path, filename_root, file_extension)
|
||||||
return meta
|
return meta
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
671
cps/web.py
671
cps/web.py
File diff suppressed because it is too large
Load Diff
224
messages.pot
224
messages.pot
@ -8,7 +8,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PROJECT VERSION\n"
|
"Project-Id-Version: PROJECT VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||||
"POT-Creation-Date: 2016-11-12 09:44+0100\n"
|
"POT-Creation-Date: 2016-12-23 08:39+0100\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
@ -17,244 +17,266 @@ msgstr ""
|
|||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Generated-By: Babel 2.3.4\n"
|
"Generated-By: Babel 2.3.4\n"
|
||||||
|
|
||||||
#: cps/helper.py:80 cps/templates/detail.html:113
|
#: cps/book_formats.py:108 cps/book_formats.py:112 cps/web.py:923
|
||||||
msgid "Send to Kindle"
|
msgid "not installed"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/helper.py:81
|
#: cps/helper.py:93
|
||||||
|
msgid "Calibre-web test email"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: cps/helper.py:94 cps/helper.py:147
|
||||||
msgid "This email has been sent via calibre web."
|
msgid "This email has been sent via calibre web."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/helper.py:103 cps/helper.py:118
|
#: cps/helper.py:128 cps/helper.py:216
|
||||||
msgid "Could not find any formats suitable for sending by email"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: cps/helper.py:112
|
|
||||||
msgid "Could not convert epub to mobi"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: cps/helper.py:142
|
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Failed to send mail: %s"
|
msgid "Failed to send mail: %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/helper.py:162
|
#: cps/helper.py:146 cps/templates/detail.html:113
|
||||||
|
msgid "Send to Kindle"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: cps/helper.py:169 cps/helper.py:184
|
||||||
|
msgid "Could not find any formats suitable for sending by email"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: cps/helper.py:178
|
||||||
|
msgid "Could not convert epub to mobi"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: cps/helper.py:236
|
||||||
msgid "The requested file could not be read. Maybe wrong permissions?"
|
msgid "The requested file could not be read. Maybe wrong permissions?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/web.py:639
|
#: cps/web.py:717
|
||||||
msgid "Latest Books"
|
msgid "Latest Books"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/web.py:661
|
#: cps/web.py:742
|
||||||
msgid "Hot Books (most downloaded)"
|
msgid "Hot Books (most downloaded)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/templates/index.xml:41 cps/web.py:668
|
#: cps/templates/index.xml:41 cps/web.py:750
|
||||||
msgid "Random Books"
|
msgid "Random Books"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/web.py:679
|
#: cps/web.py:763
|
||||||
msgid "Author list"
|
msgid "Author list"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/web.py:695
|
#: cps/web.py:780
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Author: %(nam)s"
|
msgid "Author: %(nam)s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/templates/index.xml:65 cps/web.py:706
|
#: cps/templates/index.xml:65 cps/web.py:793
|
||||||
msgid "Series list"
|
msgid "Series list"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/web.py:714
|
#: cps/web.py:804
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Series: %(serie)s"
|
msgid "Series: %(serie)s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/web.py:716 cps/web.py:796 cps/web.py:914 cps/web.py:1524
|
#: cps/web.py:806 cps/web.py:902 cps/web.py:1061 cps/web.py:1729
|
||||||
msgid "Error opening eBook. File does not exist or file is not accessible:"
|
msgid "Error opening eBook. File does not exist or file is not accessible:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/web.py:742
|
#: cps/web.py:837
|
||||||
msgid "Available languages"
|
msgid "Available languages"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/web.py:754
|
#: cps/web.py:852
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Language: %(name)s"
|
msgid "Language: %(name)s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/templates/index.xml:57 cps/web.py:765
|
#: cps/templates/index.xml:57 cps/web.py:865
|
||||||
msgid "Category list"
|
msgid "Category list"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/web.py:772
|
#: cps/web.py:875
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Category: %(name)s"
|
msgid "Category: %(name)s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/web.py:810
|
#: cps/web.py:931
|
||||||
msgid "Statistics"
|
msgid "Statistics"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/web.py:898 cps/web.py:905 cps/web.py:912
|
#: cps/web.py:939
|
||||||
|
msgid "Server restarts"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: cps/web.py:1037 cps/web.py:1044 cps/web.py:1051 cps/web.py:1058
|
||||||
msgid "Read a Book"
|
msgid "Read a Book"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/web.py:951 cps/web.py:1179
|
#: cps/web.py:1100 cps/web.py:1365
|
||||||
msgid "Please fill out all fields!"
|
msgid "Please fill out all fields!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/web.py:967
|
#: cps/web.py:1116
|
||||||
msgid "An unknown error occured. Please try again later."
|
msgid "An unknown error occured. Please try again later."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/web.py:972
|
#: cps/web.py:1121
|
||||||
msgid "This username or email address is already in use."
|
msgid "This username or email address is already in use."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/web.py:975
|
#: cps/web.py:1124
|
||||||
msgid "register"
|
msgid "register"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/web.py:990
|
#: cps/web.py:1140
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "you are now logged in as: '%(nickname)s'"
|
msgid "you are now logged in as: '%(nickname)s'"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/web.py:993
|
#: cps/web.py:1143
|
||||||
msgid "Wrong Username or Password"
|
msgid "Wrong Username or Password"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/web.py:995
|
#: cps/web.py:1145
|
||||||
msgid "login"
|
msgid "login"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/web.py:1011
|
#: cps/web.py:1162
|
||||||
msgid "Please configure the SMTP mail settings first..."
|
msgid "Please configure the SMTP mail settings first..."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/web.py:1015
|
#: cps/web.py:1166
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Book successfully send to %(kindlemail)s"
|
msgid "Book successfully send to %(kindlemail)s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/web.py:1018
|
#: cps/web.py:1170
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "There was an error sending this book: %(res)s"
|
msgid "There was an error sending this book: %(res)s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/web.py:1020
|
#: cps/web.py:1172
|
||||||
msgid "Please configure your kindle email address first..."
|
msgid "Please configure your kindle email address first..."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/web.py:1035
|
#: cps/web.py:1188
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Book has been added to shelf: %(sname)s"
|
msgid "Book has been added to shelf: %(sname)s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/web.py:1054
|
#: cps/web.py:1209
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Book has been removed from shelf: %(sname)s"
|
msgid "Book has been removed from shelf: %(sname)s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/web.py:1070
|
#: cps/web.py:1226
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "A shelf with the name '%(title)s' already exists."
|
msgid "A shelf with the name '%(title)s' already exists."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/web.py:1075
|
#: cps/web.py:1231
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Shelf %(title)s created"
|
msgid "Shelf %(title)s created"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/web.py:1077
|
#: cps/web.py:1233
|
||||||
msgid "There was an error"
|
msgid "There was an error"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/web.py:1078 cps/web.py:1080
|
#: cps/web.py:1234 cps/web.py:1236
|
||||||
msgid "create a shelf"
|
msgid "create a shelf"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/web.py:1096
|
#: cps/web.py:1256
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "successfully deleted shelf %(name)s"
|
msgid "successfully deleted shelf %(name)s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/web.py:1113
|
#: cps/web.py:1277
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Shelf: '%(name)s'"
|
msgid "Shelf: '%(name)s'"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/web.py:1150
|
#: cps/web.py:1332
|
||||||
msgid "Found an existing account for this email address."
|
msgid "Found an existing account for this email address."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/web.py:1151 cps/web.py:1153
|
#: cps/web.py:1334 cps/web.py:1337
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "%(name)s's profile"
|
msgid "%(name)s's profile"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/web.py:1152
|
#: cps/web.py:1335
|
||||||
msgid "Profile updated"
|
msgid "Profile updated"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/web.py:1161
|
#: cps/web.py:1346
|
||||||
msgid "User list"
|
msgid "User list"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/templates/user_list.html:32 cps/web.py:1180
|
#: cps/templates/user_list.html:32 cps/web.py:1366
|
||||||
msgid "Add new user"
|
msgid "Add new user"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/web.py:1213
|
#: cps/web.py:1399
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "User '%(user)s' created"
|
msgid "User '%(user)s' created"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/web.py:1217
|
#: cps/web.py:1403
|
||||||
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:1238
|
#: cps/web.py:1426 cps/web.py:1437
|
||||||
msgid "Mail settings updated"
|
msgid "Mail settings updated"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/web.py:1241
|
#: cps/web.py:1432
|
||||||
|
#, python-format
|
||||||
|
msgid "Test E-Mail successfully send to %(kindlemail)s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: cps/web.py:1435
|
||||||
|
#, python-format
|
||||||
|
msgid "There was an error sending the Test E-Mail: %(res)s"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: cps/web.py:1438
|
||||||
msgid "Edit mail settings"
|
msgid "Edit mail settings"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/web.py:1263
|
#: cps/web.py:1461
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "User '%(nick)s' deleted"
|
msgid "User '%(nick)s' deleted"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/web.py:1318
|
#: cps/web.py:1516
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "User '%(nick)s' updated"
|
msgid "User '%(nick)s' updated"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/web.py:1321
|
#: cps/web.py:1519
|
||||||
msgid "An unknown error occured."
|
msgid "An unknown error occured."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/web.py:1322
|
#: cps/web.py:1521
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Edit User %(nick)s"
|
msgid "Edit User %(nick)s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/web.py:1556
|
#: cps/web.py:1759
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Failed to create path %s (Permission denied)."
|
msgid "Failed to create path %s (Permission denied)."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/web.py:1561
|
#: cps/web.py:1764
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Failed to store file %s (Permission denied)."
|
msgid "Failed to store file %s (Permission denied)."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/web.py:1566
|
#: cps/web.py:1769
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Failed to delete file %s (Permission denied)."
|
msgid "Failed to delete file %s (Permission denied)."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@ -339,14 +361,14 @@ msgstr ""
|
|||||||
msgid "view book after edit"
|
msgid "view book after edit"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/templates/edit_book.html:105 cps/templates/email_edit.html:30
|
#: cps/templates/edit_book.html:105 cps/templates/login.html:19
|
||||||
#: cps/templates/login.html:19 cps/templates/search_form.html:33
|
#: cps/templates/search_form.html:33 cps/templates/shelf_edit.html:15
|
||||||
#: cps/templates/shelf_edit.html:15 cps/templates/user_edit.html:93
|
#: cps/templates/user_edit.html:94
|
||||||
msgid "Submit"
|
msgid "Submit"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/templates/edit_book.html:106 cps/templates/email_edit.html:31
|
#: cps/templates/edit_book.html:106 cps/templates/email_edit.html:32
|
||||||
#: cps/templates/user_edit.html:95
|
#: cps/templates/user_edit.html:96
|
||||||
msgid "Back"
|
msgid "Back"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -374,6 +396,14 @@ msgstr ""
|
|||||||
msgid "From e-mail"
|
msgid "From e-mail"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: cps/templates/email_edit.html:30
|
||||||
|
msgid "Save settings"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: cps/templates/email_edit.html:31
|
||||||
|
msgid "Save settings and send Test E-Mail"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: cps/templates/feed.xml:14
|
#: cps/templates/feed.xml:14
|
||||||
msgid "Next"
|
msgid "Next"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@ -504,6 +534,14 @@ msgstr ""
|
|||||||
msgid "Remember me"
|
msgid "Remember me"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: cps/templates/read.html:136
|
||||||
|
msgid "Reflow text when sidebars are open."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: cps/templates/readpdf.html:29
|
||||||
|
msgid "PDF.js viewer"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: cps/templates/register.html:4
|
#: cps/templates/register.html:4
|
||||||
msgid "Register a new account"
|
msgid "Register a new account"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@ -544,6 +582,10 @@ msgstr ""
|
|||||||
msgid "Delete this Shelf"
|
msgid "Delete this Shelf"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: cps/templates/shelf.html:7
|
||||||
|
msgid "Edit Shelf name"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: cps/templates/shelf_edit.html:7
|
#: cps/templates/shelf_edit.html:7
|
||||||
msgid "Title"
|
msgid "Title"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@ -552,11 +594,27 @@ msgstr ""
|
|||||||
msgid "should the shelf be public?"
|
msgid "should the shelf be public?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/templates/stats.html:4
|
#: cps/templates/stats.html:3
|
||||||
|
msgid "Linked libraries"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: cps/templates/stats.html:8
|
||||||
|
msgid "Program library"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: cps/templates/stats.html:9
|
||||||
|
msgid "Installed Version"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: cps/templates/stats.html:32
|
||||||
|
msgid "Calibre library statistics"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: cps/templates/stats.html:37
|
||||||
msgid "Books in this Library"
|
msgid "Books in this Library"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/templates/stats.html:5
|
#: cps/templates/stats.html:41
|
||||||
msgid "Authors in this Library"
|
msgid "Authors in this Library"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -572,51 +630,51 @@ msgstr ""
|
|||||||
msgid "Show all"
|
msgid "Show all"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/templates/user_edit.html:46
|
#: cps/templates/user_edit.html:45
|
||||||
msgid "Show random books"
|
msgid "Show random books"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/templates/user_edit.html:50
|
#: cps/templates/user_edit.html:49
|
||||||
msgid "Show hot books"
|
msgid "Show hot books"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/templates/user_edit.html:54
|
#: cps/templates/user_edit.html:53
|
||||||
msgid "Show language selection"
|
msgid "Show language selection"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/templates/user_edit.html:58
|
#: cps/templates/user_edit.html:57
|
||||||
msgid "Show series selection"
|
msgid "Show series selection"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/templates/user_edit.html:62
|
#: cps/templates/user_edit.html:61
|
||||||
msgid "Show category selection"
|
msgid "Show category selection"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/templates/user_edit.html:67
|
#: cps/templates/user_edit.html:68
|
||||||
msgid "Admin user"
|
msgid "Admin user"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/templates/user_edit.html:71
|
#: cps/templates/user_edit.html:72
|
||||||
msgid "Allow Downloads"
|
msgid "Allow Downloads"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/templates/user_edit.html:75
|
#: cps/templates/user_edit.html:76
|
||||||
msgid "Allow Uploads"
|
msgid "Allow Uploads"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/templates/user_edit.html:79
|
#: cps/templates/user_edit.html:80
|
||||||
msgid "Allow Edit"
|
msgid "Allow Edit"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/templates/user_edit.html:83
|
#: cps/templates/user_edit.html:84
|
||||||
msgid "Allow Changing Password"
|
msgid "Allow Changing Password"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/templates/user_edit.html:89
|
#: cps/templates/user_edit.html:90
|
||||||
msgid "Delete this user"
|
msgid "Delete this user"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: cps/templates/user_edit.html:100
|
#: cps/templates/user_edit.html:101
|
||||||
msgid "Recent Downloads"
|
msgid "Recent Downloads"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -664,5 +722,3 @@ msgstr ""
|
|||||||
msgid "Change SMTP settings"
|
msgid "Change SMTP settings"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Latin"
|
|
||||||
msgstr ""
|
|
||||||
|
Loading…
Reference in New Issue
Block a user