Allow deleting books (fixes #119)

pull/181/head
OzzieIsaacs 8 years ago
parent daaee5b67e
commit cd0d450829

@ -25,8 +25,9 @@ Session = sessionmaker()
Session.configure(bind=engine)
session = scoped_session(Session)
class GdriveId(Base):
__tablename__='gdrive_ids'
__tablename__ = 'gdrive_ids'
id = Column(Integer, primary_key=True)
gdrive_id = Column(Integer, unique=True)
@ -36,8 +37,9 @@ class GdriveId(Base):
def __repr__(self):
return str(self.path)
class PermissionAdded(Base):
__tablename__='permissions_added'
__tablename__ = 'permissions_added'
id = Column(Integer, primary_key=True)
gdrive_id = Column(Integer, unique=True)
@ -45,15 +47,16 @@ class PermissionAdded(Base):
def __repr__(self):
return str(self.gdrive_id)
def migrate():
if not engine.dialect.has_table(engine.connect(), "permissions_added"):
PermissionAdded.__table__.create(bind = engine)
for sql in session.execute("select sql from sqlite_master where type='table'"):
if 'CREATE TABLE gdrive_ids' in sql[0]:
currUniqueConstraint='UNIQUE (gdrive_id)'
currUniqueConstraint = 'UNIQUE (gdrive_id)'
if currUniqueConstraint in sql[0]:
sql=sql[0].replace(currUniqueConstraint, 'UNIQUE (gdrive_id, path)')
sql=sql.replace(GdriveId.__tablename__, GdriveId.__tablename__+ '2')
sql=sql.replace(GdriveId.__tablename__, GdriveId.__tablename__ + '2')
session.execute(sql)
session.execute('INSERT INTO gdrive_ids2 (id, gdrive_id, path) SELECT id, gdrive_id, path FROM gdrive_ids;')
session.commit()
@ -69,9 +72,10 @@ if not os.path.exists(dbpath):
migrate()
def getDrive(gauth=None):
if not gauth:
gauth=GoogleAuth(settings_file='settings.yaml')
gauth = GoogleAuth(settings_file='settings.yaml')
# Try to load saved client credentials
gauth.LoadCredentialsFile("gdrive_credentials")
if gauth.access_token_expired:
@ -83,126 +87,134 @@ def getDrive(gauth=None):
# Save the current credentials to a file
return GoogleDrive(gauth)
def getEbooksFolder(drive=None):
if not drive:
drive = getDrive()
if drive.auth.access_token_expired:
drive.auth.Refresh()
ebooksFolder= "title = '%s' and 'root' in parents and mimeType = 'application/vnd.google-apps.folder' and trashed = false" % config.config_google_drive_folder
ebooksFolder = "title = '%s' and 'root' in parents and mimeType = 'application/vnd.google-apps.folder' and trashed = false" % config.config_google_drive_folder
fileList = drive.ListFile({'q': ebooksFolder}).GetList()
return fileList[0]
def getEbooksFolderId(drive=None):
storedPathName=session.query(GdriveId).filter(GdriveId.path == '/').first()
storedPathName = session.query(GdriveId).filter(GdriveId.path == '/').first()
if storedPathName:
return storedPathName.gdrive_id
else:
gDriveId=GdriveId()
gDriveId.gdrive_id=getEbooksFolder(drive)['id']
gDriveId.path='/'
gDriveId = GdriveId()
gDriveId.gdrive_id = getEbooksFolder(drive)['id']
gDriveId.path = '/'
session.merge(gDriveId)
session.commit()
return
def getFolderInFolder(parentId, folderName, drive=None):
if not drive:
drive = getDrive()
if drive.auth.access_token_expired:
drive.auth.Refresh()
folder= "title = '%s' and '%s' in parents and mimeType = 'application/vnd.google-apps.folder' and trashed = false" % (folderName.replace("'", "\\'"), parentId)
folder = "title = '%s' and '%s' in parents and mimeType = 'application/vnd.google-apps.folder' and trashed = false" % (folderName.replace("'", "\\'"), parentId)
fileList = drive.ListFile({'q': folder}).GetList()
return fileList[0]
def getFile(pathId, fileName, drive=None):
if not drive:
drive = getDrive()
if drive.auth.access_token_expired:
drive.auth.Refresh()
metaDataFile="'%s' in parents and trashed = false and title = '%s'" % (pathId, fileName.replace("'", "\\'"))
metaDataFile = "'%s' in parents and trashed = false and title = '%s'" % (pathId, fileName.replace("'", "\\'"))
fileList = drive.ListFile({'q': metaDataFile}).GetList()
return fileList[0]
def getFolderId(path, drive=None):
if not drive:
drive=getDrive()
drive = getDrive()
if drive.auth.access_token_expired:
drive.auth.Refresh()
currentFolderId=getEbooksFolderId(drive)
sqlCheckPath=path if path[-1] =='/' else path + '/'
storedPathName=session.query(GdriveId).filter(GdriveId.path == sqlCheckPath).first()
currentFolderId = getEbooksFolderId(drive)
sqlCheckPath = path if path[-1] == '/' else path + '/'
storedPathName = session.query(GdriveId).filter(GdriveId.path == sqlCheckPath).first()
if not storedPathName:
dbChange=False
s=path.split('/')
dbChange = False
s = path.split('/')
for i, x in enumerate(s):
if len(x) > 0:
currentPath="/".join(s[:i+1])
currentPath = "/".join(s[:i+1])
if currentPath[-1] != '/':
currentPath = currentPath + '/'
storedPathName=session.query(GdriveId).filter(GdriveId.path == currentPath).first()
storedPathName = session.query(GdriveId).filter(GdriveId.path == currentPath).first()
if storedPathName:
currentFolderId=storedPathName.gdrive_id
currentFolderId = storedPathName.gdrive_id
else:
currentFolderId=getFolderInFolder(currentFolderId, x, drive)['id']
gDriveId=GdriveId()
gDriveId.gdrive_id=currentFolderId
gDriveId.path=currentPath
currentFolderId = getFolderInFolder(currentFolderId, x, drive)['id']
gDriveId = GdriveId()
gDriveId.gdrive_id = currentFolderId
gDriveId.path = currentPath
session.merge(gDriveId)
dbChange=True
dbChange = True
if dbChange:
session.commit()
else:
currentFolderId=storedPathName.gdrive_id
currentFolderId = storedPathName.gdrive_id
return currentFolderId
def getFileFromEbooksFolder(drive, path, fileName):
if not drive:
drive=getDrive()
drive = getDrive()
if drive.auth.access_token_expired:
drive.auth.Refresh()
if path:
# sqlCheckPath=path if path[-1] =='/' else path + '/'
folderId=getFolderId(path, drive)
folderId = getFolderId(path, drive)
else:
folderId=getEbooksFolderId(drive)
folderId = getEbooksFolderId(drive)
return getFile(folderId, fileName, drive)
def copyDriveFileRemote(drive, origin_file_id, copy_title):
if not drive:
drive=getDrive()
drive = getDrive()
if drive.auth.access_token_expired:
drive.auth.Refresh()
copied_file = {'title': copy_title}
try:
file_data = drive.auth.service.files().copy(
fileId=origin_file_id, body=copied_file).execute()
fileId = origin_file_id, body=copied_file).execute()
return drive.CreateFile({'id': file_data['id']})
except errors.HttpError as error:
print ('An error occurred: %s' % error)
return None
def downloadFile(drive, path, filename, output):
if not drive:
drive=getDrive()
drive = getDrive()
if drive.auth.access_token_expired:
drive.auth.Refresh()
f=getFileFromEbooksFolder(drive, path, filename)
f = getFileFromEbooksFolder(drive, path, filename)
f.GetContentFile(output)
def backupCalibreDbAndOptionalDownload(drive, f=None):
if not drive:
drive=getDrive()
drive = getDrive()
if drive.auth.access_token_expired:
drive.auth.Refresh()
metaDataFile="'%s' in parents and title = 'metadata.db' and trashed = false" % getEbooksFolderId()
metaDataFile = "'%s' in parents and title = 'metadata.db' and trashed = false" % getEbooksFolderId()
fileList = drive.ListFile({'q': metaDataFile}).GetList()
databaseFile=fileList[0]
databaseFile = fileList[0]
if f:
databaseFile.GetContentFile(f)
@ -212,64 +224,65 @@ def copyToDrive(drive, uploadFile, createRoot, replaceFiles,
ignoreFiles=[],
parent=None, prevDir=''):
if not drive:
drive=getDrive()
drive = getDrive()
if drive.auth.access_token_expired:
drive.auth.Refresh()
isInitial=not bool(parent)
isInitial = not bool(parent)
if not parent:
parent=getEbooksFolder(drive)
parent = getEbooksFolder(drive)
if os.path.isdir(os.path.join(prevDir,uploadFile)):
existingFolder=drive.ListFile({'q' : "title = '%s' and '%s' in parents and trashed = false" % (os.path.basename(uploadFile), parent['id'])}).GetList()
existingFolder = drive.ListFile({'q': "title = '%s' and '%s' in parents and trashed = false" % (os.path.basename(uploadFile), parent['id'])}).GetList()
if len(existingFolder) == 0 and (not isInitial or createRoot):
parent = drive.CreateFile({'title': os.path.basename(uploadFile), 'parents' : [{"kind": "drive#fileLink", 'id' : parent['id']}],
"mimeType": "application/vnd.google-apps.folder" })
parent = drive.CreateFile({'title': os.path.basename(uploadFile), 'parents': [{"kind": "drive#fileLink", 'id': parent['id']}],
"mimeType": "application/vnd.google-apps.folder"})
parent.Upload()
else:
if (not isInitial or createRoot) and len(existingFolder) > 0:
parent=existingFolder[0]
for f in os.listdir(os.path.join(prevDir,uploadFile)):
parent = existingFolder[0]
for f in os.listdir(os.path.join(prevDir, uploadFile)):
if f not in ignoreFiles:
copyToDrive(drive, f, True, replaceFiles, ignoreFiles, parent, os.path.join(prevDir,uploadFile))
copyToDrive(drive, f, True, replaceFiles, ignoreFiles, parent, os.path.join(prevDir, uploadFile))
else:
if os.path.basename(uploadFile) not in ignoreFiles:
existingFiles=drive.ListFile({'q' : "title = '%s' and '%s' in parents and trashed = false" % (os.path.basename(uploadFile), parent['id'])}).GetList()
existingFiles = drive.ListFile({'q': "title = '%s' and '%s' in parents and trashed = false" % (os.path.basename(uploadFile), parent['id'])}).GetList()
if len(existingFiles) > 0:
driveFile=existingFiles[0]
driveFile = existingFiles[0]
else:
driveFile = drive.CreateFile({'title': os.path.basename(uploadFile), 'parents' : [{"kind": "drive#fileLink", 'id' : parent['id']}], })
driveFile.SetContentFile(os.path.join(prevDir,uploadFile))
driveFile = drive.CreateFile({'title': os.path.basename(uploadFile), 'parents': [{"kind":"drive#fileLink", 'id': parent['id']}], })
driveFile.SetContentFile(os.path.join(prevDir, uploadFile))
driveFile.Upload()
def uploadFileToEbooksFolder(drive, destFile, f):
if not drive:
drive=getDrive()
drive = getDrive()
if drive.auth.access_token_expired:
drive.auth.Refresh()
parent=getEbooksFolder(drive)
splitDir=destFile.split('/')
parent = getEbooksFolder(drive)
splitDir = destFile.split('/')
for i, x in enumerate(splitDir):
if i == len(splitDir)-1:
existingFiles=drive.ListFile({'q' : "title = '%s' and '%s' in parents and trashed = false" % (x, parent['id'])}).GetList()
existingFiles = drive.ListFile({'q': "title = '%s' and '%s' in parents and trashed = false" % (x, parent['id'])}).GetList()
if len(existingFiles) > 0:
driveFile=existingFiles[0]
driveFile = existingFiles[0]
else:
driveFile = drive.CreateFile({'title': x, 'parents' : [{"kind": "drive#fileLink", 'id' : parent['id']}], })
driveFile = drive.CreateFile({'title': x, 'parents': [{"kind": "drive#fileLink", 'id': parent['id']}],})
driveFile.SetContentFile(f)
driveFile.Upload()
else:
existingFolder=drive.ListFile({'q' : "title = '%s' and '%s' in parents and trashed = false" % (x, parent['id'])}).GetList()
existingFolder = drive.ListFile({'q': "title = '%s' and '%s' in parents and trashed = false" % (x, parent['id'])}).GetList()
if len(existingFolder) == 0:
parent = drive.CreateFile({'title': x, 'parents' : [{"kind": "drive#fileLink", 'id' : parent['id']}],
"mimeType": "application/vnd.google-apps.folder" })
parent = drive.CreateFile({'title': x, 'parents': [{"kind": "drive#fileLink", 'id': parent['id']}],
"mimeType": "application/vnd.google-apps.folder"})
parent.Upload()
else:
parent=existingFolder[0]
parent = existingFolder[0]
def watchChange(drive, channel_id, channel_type, channel_address,
channel_token=None, expiration=None):
if not drive:
drive=getDrive()
drive = getDrive()
if drive.auth.access_token_expired:
drive.auth.Refresh()
# Watch for all changes to a user's Drive.
@ -286,15 +299,16 @@ def watchChange(drive, channel_id, channel_type, channel_address,
# Raises:
# apiclient.errors.HttpError: if http request to create channel fails.
body = {
'id': channel_id,
'type': channel_type,
'address': channel_address
'id': channel_id,
'type': channel_type,
'address': channel_address
}
if channel_token:
body['token'] = channel_token
if expiration:
body['expiration'] = expiration
return drive.auth.service.changes().watch(body=body).execute()
return drive.auth.service.changes().watch(body=body).execute()
def watchFile(drive, file_id, channel_id, channel_type, channel_address,
channel_token=None, expiration=None):
@ -314,7 +328,7 @@ def watchFile(drive, file_id, channel_id, channel_type, channel_address,
apiclient.errors.HttpError: if http request to create channel fails.
"""
if not drive:
drive=getDrive()
drive = getDrive()
if drive.auth.access_token_expired:
drive.auth.Refresh()
@ -329,6 +343,7 @@ def watchFile(drive, file_id, channel_id, channel_type, channel_address,
body['expiration'] = expiration
return drive.auth.service.files().watch(fileId=file_id, body=body).execute()
def stopChannel(drive, channel_id, resource_id):
"""Stop watching to a specific channel.
Args:
@ -339,19 +354,20 @@ def stopChannel(drive, channel_id, resource_id):
apiclient.errors.HttpError: if http request to create channel fails.
"""
if not drive:
drive=getDrive()
drive = getDrive()
if drive.auth.access_token_expired:
drive.auth.Refresh()
# service=drive.auth.service
body = {
'id': channel_id,
'resourceId': resource_id
'id': channel_id,
'resourceId': resource_id
}
return drive.auth.service.channels().stop(body=body).execute()
def getChangeById (drive, change_id):
if not drive:
drive=getDrive()
drive = getDrive()
if drive.auth.access_token_expired:
drive.auth.Refresh()
# Print a single Change resource information.

@ -38,6 +38,7 @@ span.glyphicon.glyphicon-tags {padding-right: 5px;color: #999;vertical-align: te
}
.navbar-default .navbar-toggle .icon-bar {background-color: #000;}
.navbar-default .navbar-toggle {border-color: #000;}
.cover { margin-bottom: 10px;}
.btn-file {position: relative; overflow: hidden;}
.btn-file input[type=file] {position: absolute; top: 0; right: 0; min-width: 100%; min-height: 100%; font-size: 100px; text-align: right; filter: alpha(opacity=0); opacity: 0; outline: none; background: white; cursor: inherit; display: block;}

@ -1,17 +1,23 @@
{% extends "layout.html" %}
{% block body %}
{% if book %}
<div class="col-sm-3 col-lg-3 col-xs-12">
<div class="cover">
{% if book.has_cover %}
<img src="{{ url_for('get_cover', cover_path=book.path.replace('\\','/')) }}" />
{% else %}
<img src="{{ url_for('static', filename='generic_cover.jpg') }}" />
{% endif %}
<form role="form" action="{{ url_for('edit_book', book_id=book.id) }}" method="post">
<div class="col-sm-3 col-lg-3 col-xs-12">
<div class="cover">
{% if book.has_cover %}
<img src="{{ url_for('get_cover', cover_path=book.path.replace('\\','/')) }}" />
{% else %}
<img src="{{ url_for('static', filename='generic_cover.jpg') }}" />
{% endif %}
</div>
{% if g.user.role_delete_books() %}
<div class="text-center">
<button type="button" class="btn btn-danger" id="delete" data-toggle="modal" data-target="#deleteModal">{{_("Delete Book")}}</button>
</div>
{% endif %}
</div>
</div>
<div class="col-sm-8">
<form role="form" action="{{ url_for('edit_book', book_id=book.id) }}" method="post">
<div class="col-sm-9 col-xs-12">
<div class="form-group">
<label for="book_title">{{_('Book Title')}}</label>
<input type="text" class="form-control" name="book_title" id="book_title" value="{{book.title}}">
@ -107,9 +113,31 @@
<a href="#" id="get_meta" class="btn btn-default" data-toggle="modal" data-target="#metaModal">{{_('Get metadata')}}</a>
<button type="submit" class="btn btn-default">{{_('Submit')}}</button>
<a href="{{ url_for('show_book', book_id=book.id) }}" class="btn btn-default">{{_('Back')}}</a>
</form>
</div>
</form>
{% endif %}
{% if g.user.role_delete_books() %}
<div class="modal fade" id="deleteModal" role="dialog" aria-labelledby="metaDeleteLabel">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header bg-danger text-center">
<span>{{_('Are really you sure?')}}</span>
</div>
<div class="modal-body text-center" id="meta-info">
<span>{{_('Book will be deleted from Calibre database')}}</span>
<span>{{_('and from hard disk')}}</span>
</div>
<div class="modal-footer">
<a href="{{ url_for('delete_book', book_id=book.id) }}" class="btn btn-danger">{{_('Delete')}}</a>
<button type="button" class="btn btn-default" data-dismiss="modal">{{_('Back')}}</button>
</div>
</div>
</div>
</div>
{% endif %}
<div class="modal fade" id="metaModal" tabindex="-1" role="dialog" aria-labelledby="metaModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">

@ -110,6 +110,10 @@
<input type="checkbox" name="edit_role" id="edit_role" {% if content.role_edit() %}checked{% endif %}>
<label for="edit_role">{{_('Allow Edit')}}</label>
</div>
<div class="form-group">
<input type="checkbox" name="delete_role" id="delete_role" {% if content.role_delete_books() %}checked{% endif %}>
<label for="delete_role">{{_('Allow Delete books')}}</label>
</div>
<div class="form-group">
<input type="checkbox" name="passwd_role" id="passwd_role" {% if content.role_passwd() %}checked{% endif %}>
<label for="passwd_role">{{_('Allow Changing Password')}}</label>

@ -98,6 +98,10 @@
<div class="form-group">
<input type="checkbox" name="edit_role" id="edit_role" {% if content.role_edit() %}checked{% endif %}>
<label for="edit_role">{{_('Allow Edit')}}</label>
</div>
<div class="form-group">
<input type="checkbox" name="delete_role" id="delete_role" {% if content.role_delete_books() %}checked{% endif %}>
<label for="delete_role">{{_('Allow Delete books')}}</label>
</div>
{% if not content.role_anonymous() %}
<div class="form-group">

@ -21,7 +21,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Calibre-web\n"
"Report-Msgid-Bugs-To: https://github.com/janeczku/calibre-web\n"
"POT-Creation-Date: 2017-04-14 09:38+0200\n"
"POT-Creation-Date: 2017-04-14 20:25+0200\n"
"PO-Revision-Date: 2016-07-12 19:54+0200\n"
"Last-Translator: Ozzie Isaacs\n"
"Language: de\n"
@ -32,7 +32,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.3.4\n"
#: cps/book_formats.py:113 cps/book_formats.py:117 cps/web.py:1235
#: cps/book_formats.py:113 cps/book_formats.py:117 cps/web.py:1258
msgid "not installed"
msgstr "Nicht installiert"
@ -63,329 +63,333 @@ msgstr ""
msgid "Could not convert epub to mobi"
msgstr "Konnte .epub nicht nach .mobi konvertieren"
#: cps/ub.py:471
#: cps/ub.py:481
msgid "Guest"
msgstr "Gast"
#: cps/web.py:894
#: cps/web.py:917
msgid "Requesting update package"
msgstr "Frage Update Paket an"
#: cps/web.py:895
#: cps/web.py:918
msgid "Downloading update package"
msgstr "Lade Update Paket herunter"
#: cps/web.py:896
#: cps/web.py:919
msgid "Unzipping update package"
msgstr "Entpacke Update Paket"
#: cps/web.py:897
#: cps/web.py:920
msgid "Files are replaced"
msgstr "Ersetze Dateien"
#: cps/web.py:898
#: cps/web.py:921
msgid "Database connections are closed"
msgstr "Schließe Datenbankverbindungen"
#: cps/web.py:899
#: cps/web.py:922
msgid "Server is stopped"
msgstr "Stoppe Server"
#: cps/web.py:900
#: cps/web.py:923
msgid "Update finished, please press okay and reload page"
msgstr "Update abgeschlossen, bitte okay drücken und Seite neu laden"
#: cps/web.py:974
#: cps/web.py:997
msgid "Latest Books"
msgstr "Letzte Bücher"
#: cps/web.py:1005
#: cps/web.py:1028
msgid "Hot Books (most downloaded)"
msgstr "Beliebte Bücher (die meisten Downloads)"
#: cps/web.py:1015
#: cps/web.py:1038
msgid "Best rated books"
msgstr "Best bewertete Bücher"
#: cps/templates/index.xml:36 cps/web.py:1024
#: cps/templates/index.xml:36 cps/web.py:1047
msgid "Random Books"
msgstr "Zufällige Bücher"
#: cps/web.py:1037
#: cps/web.py:1060
msgid "Author list"
msgstr "Autorenliste"
#: cps/web.py:1048
#: cps/web.py:1072
#, python-format
msgid "Author: %(name)s"
msgstr "Autor: %(name)s"
#: cps/web.py:1050 cps/web.py:1078 cps/web.py:1212 cps/web.py:1614
#: cps/web.py:2578
#: cps/web.py:1074 cps/web.py:1102 cps/web.py:1235 cps/web.py:1672
#: cps/web.py:2655
msgid "Error opening eBook. File does not exist or file is not accessible:"
msgstr ""
"Buch öffnen fehlgeschlagen. Datei existiert nicht, oder ist nicht "
"zugänglich."
#: cps/templates/index.xml:71 cps/web.py:1064
#: cps/templates/index.xml:71 cps/web.py:1088
msgid "Series list"
msgstr "Liste Serien"
#: cps/web.py:1076
#: cps/web.py:1100
#, python-format
msgid "Series: %(serie)s"
msgstr "Serie: %(serie)s"
#: cps/web.py:1109
#: cps/web.py:1133
msgid "Available languages"
msgstr "Verfügbare Sprachen"
#: cps/web.py:1124
#: cps/web.py:1148
#, python-format
msgid "Language: %(name)s"
msgstr "Sprache: %(name)s"
#: cps/templates/index.xml:64 cps/web.py:1137
#: cps/templates/index.xml:64 cps/web.py:1161
msgid "Category list"
msgstr "Kategorieliste"
#: cps/web.py:1149
#: cps/web.py:1173
#, python-format
msgid "Category: %(name)s"
msgstr "Kategorie: %(name)s"
#: cps/web.py:1257
#: cps/web.py:1280
msgid "Statistics"
msgstr "Statistiken"
#: cps/web.py:1365
#: cps/web.py:1415
msgid "Server restarted, please reload page"
msgstr "Server neu gestartet,bitte Seite neu laden"
#: cps/web.py:1367
#: cps/web.py:1417
msgid "Performing shutdown of server, please close window"
msgstr "Server wird runtergefahren, bitte Fenster schließen"
#: cps/web.py:1382
#: cps/web.py:1433
msgid "Update done"
msgstr "Update durchgeführt"
#: cps/web.py:1460 cps/web.py:1473
#: cps/web.py:1511 cps/web.py:1524
msgid "search"
msgstr "Suche"
#: cps/web.py:1590 cps/web.py:1597 cps/web.py:1604 cps/web.py:1611
#: cps/web.py:1648 cps/web.py:1655 cps/web.py:1662 cps/web.py:1669
msgid "Read a Book"
msgstr "Lese ein Buch"
#: cps/web.py:1664 cps/web.py:2144
#: cps/web.py:1725 cps/web.py:2207
msgid "Please fill out all fields!"
msgstr "Bitte alle Felder ausfüllen!"
#: cps/web.py:1665 cps/web.py:1681 cps/web.py:1686 cps/web.py:1688
#: cps/web.py:1726 cps/web.py:1742 cps/web.py:1747 cps/web.py:1749
msgid "register"
msgstr "Registieren"
#: cps/web.py:1680
#: cps/web.py:1741
msgid "An unknown error occured. Please try again later."
msgstr "Es ist ein unbekannter Fehler aufgetreten. Bitte später erneut versuchen."
#: cps/web.py:1685
#: cps/web.py:1746
msgid "This username or email address is already in use."
msgstr "Der Benutzername oder die E-Mailadresse ist in bereits in Benutzung."
#: cps/web.py:1703
#: cps/web.py:1764
#, python-format
msgid "you are now logged in as: '%(nickname)s'"
msgstr "Du bist nun eingeloggt als '%(nickname)s'"
#: cps/web.py:1708
#: cps/web.py:1769
msgid "Wrong Username or Password"
msgstr "Falscher Benutzername oder Passwort"
#: cps/web.py:1710
#: cps/web.py:1771
msgid "login"
msgstr "Login"
#: cps/web.py:1727
#: cps/web.py:1788
msgid "Please configure the SMTP mail settings first..."
msgstr "Bitte zuerst die SMTP Mail Einstellung konfigurieren ..."
#: cps/web.py:1731
#: cps/web.py:1792
#, python-format
msgid "Book successfully send to %(kindlemail)s"
msgstr "Buch erfolgreich versandt an %(kindlemail)s"
#: cps/web.py:1735
#: cps/web.py:1796
#, python-format
msgid "There was an error sending this book: %(res)s"
msgstr "Beim Senden des Buchs trat ein Fehler auf: %(res)s"
#: cps/web.py:1737 cps/web.py:2226
#: cps/web.py:1798 cps/web.py:2291
msgid "Please configure your kindle email address first..."
msgstr "Bitte die Kindle E-Mail Adresse zuuerst konfigurieren..."
#: cps/web.py:1762
#: cps/web.py:1823
#, python-format
msgid "Book has been added to shelf: %(sname)s"
msgstr "Das Buch wurde dem Bücherregal: %(sname)s hinzugefügt"
#: cps/web.py:1782
#: cps/web.py:1843
#, python-format
msgid "Book has been removed from shelf: %(sname)s"
msgstr "Das Buch wurde aus dem Bücherregal: %(sname)s entfernt"
#: cps/web.py:1800 cps/web.py:1824
#: cps/web.py:1861 cps/web.py:1885
#, python-format
msgid "A shelf with the name '%(title)s' already exists."
msgstr "Es existiert bereits ein Bücheregal mit dem Titel '%(title)s'"
#: cps/web.py:1805
#: cps/web.py:1866
#, python-format
msgid "Shelf %(title)s created"
msgstr "Bücherregal %(title)s erzeugt"
#: cps/web.py:1807 cps/web.py:1835
#: cps/web.py:1868 cps/web.py:1896
msgid "There was an error"
msgstr "Es trat ein Fehler auf"
#: cps/web.py:1808 cps/web.py:1810
#: cps/web.py:1869 cps/web.py:1871
msgid "create a shelf"
msgstr "Bücherregal erzeugen"
#: cps/web.py:1833
#: cps/web.py:1894
#, python-format
msgid "Shelf %(title)s changed"
msgstr "Bücherregal %(title)s verändert"
#: cps/web.py:1836 cps/web.py:1838
#: cps/web.py:1897 cps/web.py:1899
msgid "Edit a shelf"
msgstr "Bücherregal editieren"
#: cps/web.py:1858
#: cps/web.py:1919
#, python-format
msgid "successfully deleted shelf %(name)s"
msgstr "Bücherregal %(name)s erfolgreich gelöscht"
#: cps/web.py:1880
#: cps/web.py:1941
#, python-format
msgid "Shelf: '%(name)s'"
msgstr "Bücherregal: '%(name)s'"
#: cps/web.py:1911
#: cps/web.py:1972
#, python-format
msgid "Change order of Shelf: '%(name)s'"
msgstr "Reihenfolge in Bücherregal '%(name)s' verändern"
#: cps/web.py:1975
#: cps/web.py:2036
msgid "Found an existing account for this email address."
msgstr "Es existiert ein Benutzerkonto für diese E-Mailadresse"
#: cps/web.py:1977 cps/web.py:1981
#: cps/web.py:2038 cps/web.py:2042
#, python-format
msgid "%(name)s's profile"
msgstr "%(name)s's Profil"
#: cps/web.py:1978
#: cps/web.py:2039
msgid "Profile updated"
msgstr "Profil aktualisiert"
#: cps/web.py:1992
#: cps/web.py:2053
msgid "Admin page"
msgstr "Admin Seite"
#: cps/web.py:2098
#: cps/web.py:2161
msgid "Calibre-web configuration updated"
msgstr "Calibre-web Konfiguration wurde aktualisiert"
#: cps/web.py:2105 cps/web.py:2111 cps/web.py:2125
#: cps/web.py:2168 cps/web.py:2174 cps/web.py:2188
msgid "Basic Configuration"
msgstr "Basis Konfiguration"
#: cps/web.py:2109
#: cps/web.py:2172
msgid "DB location is not valid, please enter correct path"
msgstr "DB Speicherort ist ungültig, bitte Pfad korrigieren"
#: cps/templates/admin.html:34 cps/web.py:2146 cps/web.py:2196
#: cps/templates/admin.html:34 cps/web.py:2209 cps/web.py:2261
msgid "Add new user"
msgstr "Neuen Benutzer hinzufügen"
#: cps/web.py:2188
#: cps/web.py:2253
#, python-format
msgid "User '%(user)s' created"
msgstr "Benutzer '%(user)s' angelegt"
#: cps/web.py:2192
#: cps/web.py:2257
msgid "Found an existing account for this email address or nickname."
msgstr ""
"Es existiert ein Benutzerkonto für diese Emailadresse oder den "
"Benutzernamen."
#: cps/web.py:2214
#: cps/web.py:2279
msgid "Mail settings updated"
msgstr "E-Mail Einstellungen aktualisiert"
#: cps/web.py:2221
#: cps/web.py:2286
#, python-format
msgid "Test E-Mail successfully send to %(kindlemail)s"
msgstr "Test E-Mail erfolgreich an %(kindlemail)s versendet"
#: cps/web.py:2224
#: cps/web.py:2289
#, 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:2228
#: cps/web.py:2293
msgid "E-Mail settings updated"
msgstr "E-Mail Einstellungen wurde aktualisiert"
#: cps/web.py:2229
#: cps/web.py:2294
msgid "Edit mail settings"
msgstr "E-Mail Einstellungen editieren"
#: cps/web.py:2257
#: cps/web.py:2322
#, python-format
msgid "User '%(nick)s' deleted"
msgstr "Benutzer '%(nick)s' gelöscht"
#: cps/web.py:2348
#: cps/web.py:2418
#, python-format
msgid "User '%(nick)s' updated"
msgstr "Benutzer '%(nick)s' aktualisiert"
#: cps/web.py:2351
#: cps/web.py:2421
msgid "An unknown error occured."
msgstr "Es ist ein unbekanter Fehler aufgetreten"
#: cps/web.py:2354
#: cps/web.py:2424
#, python-format
msgid "Edit User %(nick)s"
msgstr "Benutzer %(nick)s bearbeiten"
#: cps/web.py:2573 cps/web.py:2576 cps/web.py:2688
#: cps/web.py:2459 cps/web.py:2463
msgid "unknown"
msgstr "Unbekannt"
#: cps/web.py:2650 cps/web.py:2653 cps/web.py:2763
msgid "edit metadata"
msgstr "Metadaten editieren"
#: cps/web.py:2597
#: cps/web.py:2674
#, python-format
msgid "File extension \"%s\" is not allowed to be uploaded to this server"
msgstr "Die Dateiendung \"%s\" kann nicht auf diesen Server hochgeladen werden"
#: cps/web.py:2603
#: cps/web.py:2680
msgid "File to be uploaded must have an extension"
msgstr "Datei müssen eine Erweiterung haben, um hochgeladen zu werden"
#: cps/web.py:2620
#: cps/web.py:2697
#, python-format
msgid "Failed to create path %s (Permission denied)."
msgstr "Fehler beim Erzeugen des Pfads %s (Zugriff verweigert)"
#: cps/web.py:2625
#: cps/web.py:2702
#, python-format
msgid "Failed to store file %s (Permission denied)."
msgstr "Fehler beim speichern der Datei %s (Zugriff verweigert)"
#: cps/web.py:2630
#: cps/web.py:2707
#, python-format
msgid "Failed to delete file %s (Permission denied)."
msgstr "Fehler beim Löschen von Datei %s (Zugriff verweigert)"
@ -536,10 +540,10 @@ msgid "Ok"
msgstr "Ok"
#: cps/templates/admin.html:103 cps/templates/admin.html:117
#: cps/templates/book_edit.html:109 cps/templates/config_edit.html:123
#: cps/templates/email_edit.html:36 cps/templates/shelf.html:53
#: cps/templates/shelf_edit.html:19 cps/templates/shelf_order.html:12
#: cps/templates/user_edit.html:124
#: cps/templates/book_edit.html:115 cps/templates/book_edit.html:134
#: cps/templates/config_edit.html:127 cps/templates/email_edit.html:36
#: cps/templates/shelf.html:53 cps/templates/shelf_edit.html:19
#: cps/templates/shelf_order.html:12 cps/templates/user_edit.html:128
msgid "Back"
msgstr "Zurück"
@ -551,104 +555,124 @@ msgstr "Calibre-web wirklich stoppen"
msgid "Updating, please do not reload page"
msgstr "Updatevorgang, bitte Seite nicht neu laden"
#: cps/templates/book_edit.html:16 cps/templates/search_form.html:6
#: cps/templates/book_edit.html:16
msgid "Delete Book"
msgstr "Buch löschen"
#: cps/templates/book_edit.html:22 cps/templates/search_form.html:6
msgid "Book Title"
msgstr "Buchtitel"
#: cps/templates/book_edit.html:20 cps/templates/book_edit.html:145
#: cps/templates/book_edit.html:26 cps/templates/book_edit.html:173
#: cps/templates/search_form.html:10
msgid "Author"
msgstr "Autor"
#: cps/templates/book_edit.html:24 cps/templates/book_edit.html:147
#: cps/templates/book_edit.html:30 cps/templates/book_edit.html:175
msgid "Description"
msgstr "Beschreibung"
#: cps/templates/book_edit.html:28 cps/templates/search_form.html:17
#: cps/templates/book_edit.html:34 cps/templates/search_form.html:17
msgid "Tags"
msgstr "Tags"
#: cps/templates/book_edit.html:33 cps/templates/layout.html:142
#: cps/templates/book_edit.html:39 cps/templates/layout.html:142
#: cps/templates/search_form.html:37
msgid "Series"
msgstr "Serien"
#: cps/templates/book_edit.html:37
#: cps/templates/book_edit.html:43
msgid "Series id"
msgstr "Serien ID"
#: cps/templates/book_edit.html:41
#: cps/templates/book_edit.html:47
msgid "Rating"
msgstr "Bewertung"
#: cps/templates/book_edit.html:45
#: cps/templates/book_edit.html:51
msgid "Cover URL (jpg)"
msgstr "Cover URL (jpg)"
#: cps/templates/book_edit.html:50 cps/templates/user_edit.html:27
#: cps/templates/book_edit.html:56 cps/templates/user_edit.html:27
msgid "Language"
msgstr "Sprache"
#: cps/templates/book_edit.html:61
#: cps/templates/book_edit.html:67
msgid "Yes"
msgstr "Ja"
#: cps/templates/book_edit.html:62
#: cps/templates/book_edit.html:68
msgid "No"
msgstr "Nein"
#: cps/templates/book_edit.html:104
#: cps/templates/book_edit.html:110
msgid "view book after edit"
msgstr "Buch nach Bearbeitung ansehen"
#: cps/templates/book_edit.html:107 cps/templates/book_edit.html:118
#: cps/templates/book_edit.html:113 cps/templates/book_edit.html:146
msgid "Get metadata"
msgstr "Metadaten laden"
#: cps/templates/book_edit.html:108 cps/templates/config_edit.html:121
#: cps/templates/book_edit.html:114 cps/templates/config_edit.html:125
#: cps/templates/login.html:19 cps/templates/search_form.html:79
#: cps/templates/shelf_edit.html:17 cps/templates/user_edit.html:122
#: cps/templates/shelf_edit.html:17 cps/templates/user_edit.html:126
msgid "Submit"
msgstr "Abschicken"
#: cps/templates/book_edit.html:121
#: cps/templates/book_edit.html:125
msgid "Are really you sure?"
msgstr "Sicher?"
#: cps/templates/book_edit.html:128
msgid "Book will be deleted from Calibre database"
msgstr "Das Buch wird aus der Calibre Datenbank"
#: cps/templates/book_edit.html:129
msgid "and from hard disk"
msgstr "und der Festplatte gelöscht"
#: cps/templates/book_edit.html:133
msgid "Delete"
msgstr "Löschen"
#: cps/templates/book_edit.html:149
msgid "Keyword"
msgstr "Suchbegriff"
#: cps/templates/book_edit.html:122
#: cps/templates/book_edit.html:150
msgid " Search keyword "
msgstr "Suchbegriff"
#: cps/templates/book_edit.html:124 cps/templates/layout.html:60
#: cps/templates/book_edit.html:152 cps/templates/layout.html:60
msgid "Go!"
msgstr "Los!"
#: cps/templates/book_edit.html:125
#: cps/templates/book_edit.html:153
msgid "Click the cover to load metadata to the form"
msgstr "Klicke auf das Bild um die Metadaten zu übertragen"
#: cps/templates/book_edit.html:129 cps/templates/book_edit.html:142
#: cps/templates/book_edit.html:157 cps/templates/book_edit.html:170
msgid "Loading..."
msgstr "Lade..."
#: cps/templates/book_edit.html:132
#: cps/templates/book_edit.html:160
msgid "Close"
msgstr "Schließen"
#: cps/templates/book_edit.html:143
#: cps/templates/book_edit.html:171
msgid "Search error!"
msgstr "Fehler bei Suche!"
#: cps/templates/book_edit.html:144
#: cps/templates/book_edit.html:172
msgid "No Result! Please try anonther keyword."
msgstr "Kein Ergebniss! Bitte anderen Begriff versuchen"
#: cps/templates/book_edit.html:146 cps/templates/detail.html:76
#: cps/templates/book_edit.html:174 cps/templates/detail.html:76
#: cps/templates/search_form.html:14
msgid "Publisher"
msgstr "Herausgeber"
#: cps/templates/book_edit.html:148
#: cps/templates/book_edit.html:176
msgid "Source"
msgstr "Quelle"
@ -732,15 +756,19 @@ msgstr "Uploads erlauben"
msgid "Allow Edit"
msgstr "Bearbeiten erlauben"
#: cps/templates/config_edit.html:115 cps/templates/user_edit.html:105
#: cps/templates/config_edit.html:115 cps/templates/user_edit.html:104
msgid "Allow Delete books"
msgstr "Bücher löschen erlauben"
#: cps/templates/config_edit.html:119 cps/templates/user_edit.html:109
msgid "Allow Changing Password"
msgstr "Passwort ändern erlauben"
#: cps/templates/config_edit.html:119 cps/templates/user_edit.html:109
#: cps/templates/config_edit.html:123 cps/templates/user_edit.html:113
msgid "Allow Editing Public Shelfs"
msgstr ""
msgstr "Öffentliche Bücherregale editieren erlauben"
#: cps/templates/config_edit.html:126 cps/templates/layout.html:93
#: cps/templates/config_edit.html:130 cps/templates/layout.html:93
#: cps/templates/login.html:4
msgid "Login"
msgstr "Login"
@ -1021,11 +1049,11 @@ msgstr "Reihenfolge ändern"
#: cps/templates/shelf.html:47
msgid "Do you really want to delete the shelf?"
msgstr ""
msgstr "Wirklich das Bücherregal löschen?"
#: cps/templates/shelf.html:50
msgid "Shelf will be lost for everybody and forever!"
msgstr ""
msgstr "Das Bücherregal wird für alle und für immer gelöscht"
#: cps/templates/shelf_edit.html:13
msgid "should the shelf be public?"
@ -1115,11 +1143,11 @@ msgstr "Zeige Gelesen/Ungelesen Auswahl"
msgid "Show random books in detail view"
msgstr "Zeige zufällige Bücher in der Detailansicht"
#: cps/templates/user_edit.html:116
#: cps/templates/user_edit.html:120
msgid "Delete this user"
msgstr "Benutzer löschen"
#: cps/templates/user_edit.html:131
#: cps/templates/user_edit.html:135
msgid "Recent Downloads"
msgstr "Letzte Downloads"

@ -14,7 +14,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Calibre-web\n"
"Report-Msgid-Bugs-To: https://github.com/janeczku/calibre-web\n"
"POT-Creation-Date: 2017-04-14 09:38+0200\n"
"POT-Creation-Date: 2017-04-14 20:25+0200\n"
"PO-Revision-Date: 2017-04-04 15:09+0200\n"
"Last-Translator: Juan F. Villa <juan.villa@paisdelconocimiento.org>\n"
"Language: es\n"
@ -25,7 +25,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.3.4\n"
#: cps/book_formats.py:113 cps/book_formats.py:117 cps/web.py:1235
#: cps/book_formats.py:113 cps/book_formats.py:117 cps/web.py:1258
msgid "not installed"
msgstr "No instalado"
@ -54,327 +54,331 @@ msgstr "Formato no compatible para enviar por correo electronico"
msgid "Could not convert epub to mobi"
msgstr "No fue posible convertir de epub a mobi"
#: cps/ub.py:471
#: cps/ub.py:481
msgid "Guest"
msgstr "Invitado"
#: cps/web.py:894
#: cps/web.py:917
msgid "Requesting update package"
msgstr "Solicitando paquete de actualización"
#: cps/web.py:895
#: cps/web.py:918
msgid "Downloading update package"
msgstr "Descargando paquete de actualización"
#: cps/web.py:896
#: cps/web.py:919
msgid "Unzipping update package"
msgstr "Descomprimiendo paquete de actualización"
#: cps/web.py:897
#: cps/web.py:920
msgid "Files are replaced"
msgstr "Ficheros sustituidos"
#: cps/web.py:898
#: cps/web.py:921
msgid "Database connections are closed"
msgstr "Los conexiones de base datos están cerradas"
#: cps/web.py:899
#: cps/web.py:922
msgid "Server is stopped"
msgstr "El servidor está detenido"
#: cps/web.py:900
#: cps/web.py:923
msgid "Update finished, please press okay and reload page"
msgstr "Actualización finalizada. Por favor, pulse OK y recargue la página"
#: cps/web.py:974
#: cps/web.py:997
msgid "Latest Books"
msgstr "Libros recientes"
#: cps/web.py:1005
#: cps/web.py:1028
msgid "Hot Books (most downloaded)"
msgstr "Libros populares (los mas descargados)"
#: cps/web.py:1015
#: cps/web.py:1038
msgid "Best rated books"
msgstr "Libros mejor valorados"
#: cps/templates/index.xml:36 cps/web.py:1024
#: cps/templates/index.xml:36 cps/web.py:1047
msgid "Random Books"
msgstr "Libros al azar"
#: cps/web.py:1037
#: cps/web.py:1060
msgid "Author list"
msgstr "Lista de autores"
#: cps/web.py:1048
#: cps/web.py:1072
#, python-format
msgid "Author: %(name)s"
msgstr "Autor:%(name)s"
#: cps/web.py:1050 cps/web.py:1078 cps/web.py:1212 cps/web.py:1614
#: cps/web.py:2578
#: cps/web.py:1074 cps/web.py:1102 cps/web.py:1235 cps/web.py:1672
#: cps/web.py:2655
msgid "Error opening eBook. File does not exist or file is not accessible:"
msgstr "Error en la apertura del eBook. El archivo no existe o no es accesible:"
#: cps/templates/index.xml:71 cps/web.py:1064
#: cps/templates/index.xml:71 cps/web.py:1088
msgid "Series list"
msgstr "Lista de series"
#: cps/web.py:1076
#: cps/web.py:1100
#, python-format
msgid "Series: %(serie)s"
msgstr "Series : %(serie)s"
#: cps/web.py:1109
#: cps/web.py:1133
msgid "Available languages"
msgstr "Lenguajes disponibles"
#: cps/web.py:1124
#: cps/web.py:1148
#, python-format
msgid "Language: %(name)s"
msgstr "Lenguaje: %(name)s"
#: cps/templates/index.xml:64 cps/web.py:1137
#: cps/templates/index.xml:64 cps/web.py:1161
msgid "Category list"
msgstr "Lista de categorias"
#: cps/web.py:1149
#: cps/web.py:1173
#, python-format
msgid "Category: %(name)s"
msgstr "Categoría : %(name)s"
#: cps/web.py:1257
#: cps/web.py:1280
msgid "Statistics"
msgstr "Estadisticas"
#: cps/web.py:1365
#: cps/web.py:1415
msgid "Server restarted, please reload page"
msgstr "Servidor reiniciado. Por favor, recargue la página"
#: cps/web.py:1367
#: cps/web.py:1417
msgid "Performing shutdown of server, please close window"
msgstr "Servidor en proceso de apagado. Por favor, cierre la ventana."
#: cps/web.py:1382
#: cps/web.py:1433
msgid "Update done"
msgstr "Actualización realizada"
#: cps/web.py:1460 cps/web.py:1473
#: cps/web.py:1511 cps/web.py:1524
msgid "search"
msgstr "búsqueda"
#: cps/web.py:1590 cps/web.py:1597 cps/web.py:1604 cps/web.py:1611
#: cps/web.py:1648 cps/web.py:1655 cps/web.py:1662 cps/web.py:1669
msgid "Read a Book"
msgstr "Leer un libro"
#: cps/web.py:1664 cps/web.py:2144
#: cps/web.py:1725 cps/web.py:2207
msgid "Please fill out all fields!"
msgstr "¡Por favor completar todos los campos!"
#: cps/web.py:1665 cps/web.py:1681 cps/web.py:1686 cps/web.py:1688
#: cps/web.py:1726 cps/web.py:1742 cps/web.py:1747 cps/web.py:1749
msgid "register"
msgstr "registrarse"
#: cps/web.py:1680
#: cps/web.py:1741
msgid "An unknown error occured. Please try again later."
msgstr "Error desconocido. Por favor, inténtelo de nuevo mas tarde."
#: cps/web.py:1685
#: cps/web.py:1746
msgid "This username or email address is already in use."
msgstr "Usuario o dirección de correo en uso."
#: cps/web.py:1703
#: cps/web.py:1764
#, python-format
msgid "you are now logged in as: '%(nickname)s'"
msgstr "Sesion iniciada como : '%(nickname)s'"
#: cps/web.py:1708
#: cps/web.py:1769
msgid "Wrong Username or Password"
msgstr "Usuario o contraseña invalido"
#: cps/web.py:1710
#: cps/web.py:1771
msgid "login"
msgstr "Iniciar sesión"
#: cps/web.py:1727
#: cps/web.py:1788
msgid "Please configure the SMTP mail settings first..."
msgstr "Configurar primero los parametros SMTP por favor..."
#: cps/web.py:1731
#: cps/web.py:1792
#, python-format
msgid "Book successfully send to %(kindlemail)s"
msgstr "Envio de Libro a %(kindlemail)s correctamente"
#: cps/web.py:1735
#: cps/web.py:1796
#, python-format
msgid "There was an error sending this book: %(res)s"
msgstr "Ha sucedido un error en el envio del Libro: %(res)s"
#: cps/web.py:1737 cps/web.py:2226
#: cps/web.py:1798 cps/web.py:2291
msgid "Please configure your kindle email address first..."
msgstr "Configurar primero la dirección de correo Kindle por favor..."
#: cps/web.py:1762
#: cps/web.py:1823
#, python-format
msgid "Book has been added to shelf: %(sname)s"
msgstr "El libro fue agregado a el estante: %(sname)s"
#: cps/web.py:1782
#: cps/web.py:1843
#, python-format
msgid "Book has been removed from shelf: %(sname)s"
msgstr "El libro fue removido del estante: %(sname)s"
#: cps/web.py:1800 cps/web.py:1824
#: cps/web.py:1861 cps/web.py:1885
#, python-format
msgid "A shelf with the name '%(title)s' already exists."
msgstr "Une étagère de ce nom '%(title)s' existe déjà."
#: cps/web.py:1805
#: cps/web.py:1866
#, python-format
msgid "Shelf %(title)s created"
msgstr "Estante %(title)s creado"
#: cps/web.py:1807 cps/web.py:1835
#: cps/web.py:1868 cps/web.py:1896
msgid "There was an error"
msgstr "Ha sucedido un error"
#: cps/web.py:1808 cps/web.py:1810
#: cps/web.py:1869 cps/web.py:1871
msgid "create a shelf"
msgstr "crear un estante"
#: cps/web.py:1833
#: cps/web.py:1894
#, python-format
msgid "Shelf %(title)s changed"
msgstr "Estante %(title)s cambiado"
#: cps/web.py:1836 cps/web.py:1838
#: cps/web.py:1897 cps/web.py:1899
msgid "Edit a shelf"
msgstr "Editar un estante"
#: cps/web.py:1858
#: cps/web.py:1919
#, python-format
msgid "successfully deleted shelf %(name)s"
msgstr "Estante %(name)s fue borrado correctamente"
#: cps/web.py:1880
#: cps/web.py:1941
#, python-format
msgid "Shelf: '%(name)s'"
msgstr "Estante: '%(name)s'"
#: cps/web.py:1911
#: cps/web.py:1972
#, python-format
msgid "Change order of Shelf: '%(name)s'"
msgstr "Cambiar orden del estante: '%(name)s'"
#: cps/web.py:1975
#: cps/web.py:2036
msgid "Found an existing account for this email address."
msgstr "Existe una cuenta vinculada a esta dirección de correo."
#: cps/web.py:1977 cps/web.py:1981
#: cps/web.py:2038 cps/web.py:2042
#, python-format
msgid "%(name)s's profile"
msgstr "Perfil de %(name)s"
#: cps/web.py:1978
#: cps/web.py:2039
msgid "Profile updated"
msgstr "Perfil actualizado"
#: cps/web.py:1992
#: cps/web.py:2053
msgid "Admin page"
msgstr "Página de administración"
#: cps/web.py:2098
#: cps/web.py:2161
msgid "Calibre-web configuration updated"
msgstr "Configuración de Calibre-web actualizada"
#: cps/web.py:2105 cps/web.py:2111 cps/web.py:2125
#: cps/web.py:2168 cps/web.py:2174 cps/web.py:2188
msgid "Basic Configuration"
msgstr "Configuración básica"
#: cps/web.py:2109
#: cps/web.py:2172
msgid "DB location is not valid, please enter correct path"
msgstr "Localicación de la BD inválida. Por favor, introduzca la ruta correcta."
#: cps/templates/admin.html:34 cps/web.py:2146 cps/web.py:2196
#: cps/templates/admin.html:34 cps/web.py:2209 cps/web.py:2261
msgid "Add new user"
msgstr "Agregar un nuevo usuario"
#: cps/web.py:2188
#: cps/web.py:2253
#, python-format
msgid "User '%(user)s' created"
msgstr "Usuario '%(user)s' creado"
#: cps/web.py:2192
#: cps/web.py:2257
msgid "Found an existing account for this email address or nickname."
msgstr ""
"Se ha encontrado una cuenta vinculada a esta dirección de correo o nombre"
" de usuario."
#: cps/web.py:2214
#: cps/web.py:2279
msgid "Mail settings updated"
msgstr "Parámetros de correo actualizados"
#: cps/web.py:2221
#: cps/web.py:2286
#, python-format
msgid "Test E-Mail successfully send to %(kindlemail)s"
msgstr "Exito al realizar envio de prueba a %(kindlemail)s"
#: cps/web.py:2224
#: cps/web.py:2289
#, python-format
msgid "There was an error sending the Test E-Mail: %(res)s"
msgstr "Error al realizar envio de prueba a E-Mail: %(res)s"
#: cps/web.py:2228
#: cps/web.py:2293
msgid "E-Mail settings updated"
msgstr "Ajustes de correo electrónico actualizados"
#: cps/web.py:2229
#: cps/web.py:2294
msgid "Edit mail settings"
msgstr "Editar parametros de correo"
#: cps/web.py:2257
#: cps/web.py:2322
#, python-format
msgid "User '%(nick)s' deleted"
msgstr "Usuario '%(nick)s' borrado"
#: cps/web.py:2348
#: cps/web.py:2418
#, python-format
msgid "User '%(nick)s' updated"
msgstr "Usuario '%(nick)s' actualizado"
#: cps/web.py:2351
#: cps/web.py:2421
msgid "An unknown error occured."
msgstr "Error inesperado."
#: cps/web.py:2354
#: cps/web.py:2424
#, python-format
msgid "Edit User %(nick)s"
msgstr "Editar Usuario %(nick)s"
#: cps/web.py:2573 cps/web.py:2576 cps/web.py:2688
#: cps/web.py:2459 cps/web.py:2463
msgid "unknown"
msgstr ""
#: cps/web.py:2650 cps/web.py:2653 cps/web.py:2763
msgid "edit metadata"
msgstr "editar metainformación"
#: cps/web.py:2597
#: cps/web.py:2674
#, python-format
msgid "File extension \"%s\" is not allowed to be uploaded to this server"
msgstr "No se permite subir archivos con la extensión \"%s\" a este servidor"
#: cps/web.py:2603
#: cps/web.py:2680
msgid "File to be uploaded must have an extension"
msgstr "El archivo a subir debe tener una extensión"
#: cps/web.py:2620
#: cps/web.py:2697
#, python-format
msgid "Failed to create path %s (Permission denied)."
msgstr "Fallo al crear la ruta %s (permiso negado)"
#: cps/web.py:2625
#: cps/web.py:2702
#, python-format
msgid "Failed to store file %s (Permission denied)."
msgstr "Fallo al almacenar el archivo %s (permiso negado)"
#: cps/web.py:2630
#: cps/web.py:2707
#, python-format
msgid "Failed to delete file %s (Permission denied)."
msgstr "Fallo al borrar el archivo %s (permiso negado)"
@ -525,10 +529,10 @@ msgid "Ok"
msgstr "Ok"
#: cps/templates/admin.html:103 cps/templates/admin.html:117
#: cps/templates/book_edit.html:109 cps/templates/config_edit.html:123
#: cps/templates/email_edit.html:36 cps/templates/shelf.html:53
#: cps/templates/shelf_edit.html:19 cps/templates/shelf_order.html:12
#: cps/templates/user_edit.html:124
#: cps/templates/book_edit.html:115 cps/templates/book_edit.html:134
#: cps/templates/config_edit.html:127 cps/templates/email_edit.html:36
#: cps/templates/shelf.html:53 cps/templates/shelf_edit.html:19
#: cps/templates/shelf_order.html:12 cps/templates/user_edit.html:128
msgid "Back"
msgstr "Regresar"
@ -540,104 +544,124 @@ msgstr "¿Seguro que quiere detener Calibre-web?"
msgid "Updating, please do not reload page"
msgstr "Actualizando. Por favor, no recargue la página."
#: cps/templates/book_edit.html:16 cps/templates/search_form.html:6
#: cps/templates/book_edit.html:16
msgid "Delete Book"
msgstr ""
#: cps/templates/book_edit.html:22 cps/templates/search_form.html:6
msgid "Book Title"
msgstr "Titulo del Libro"
#: cps/templates/book_edit.html:20 cps/templates/book_edit.html:145
#: cps/templates/book_edit.html:26 cps/templates/book_edit.html:173
#: cps/templates/search_form.html:10
msgid "Author"
msgstr "Autor"
#: cps/templates/book_edit.html:24 cps/templates/book_edit.html:147
#: cps/templates/book_edit.html:30 cps/templates/book_edit.html:175
msgid "Description"
msgstr "Descripcion"
#: cps/templates/book_edit.html:28 cps/templates/search_form.html:17
#: cps/templates/book_edit.html:34 cps/templates/search_form.html:17
msgid "Tags"
msgstr "Etiqueta"
#: cps/templates/book_edit.html:33 cps/templates/layout.html:142
#: cps/templates/book_edit.html:39 cps/templates/layout.html:142
#: cps/templates/search_form.html:37
msgid "Series"
msgstr "Series"
#: cps/templates/book_edit.html:37
#: cps/templates/book_edit.html:43
msgid "Series id"
msgstr "Id de la serie"
#: cps/templates/book_edit.html:41
#: cps/templates/book_edit.html:47
msgid "Rating"
msgstr "Puntaje"
#: cps/templates/book_edit.html:45
#: cps/templates/book_edit.html:51
msgid "Cover URL (jpg)"
msgstr "URL de la Cubierta (jpg)"
#: cps/templates/book_edit.html:50 cps/templates/user_edit.html:27
#: cps/templates/book_edit.html:56 cps/templates/user_edit.html:27
msgid "Language"
msgstr "Lenguaje"
#: cps/templates/book_edit.html:61
#: cps/templates/book_edit.html:67
msgid "Yes"
msgstr "Si"
#: cps/templates/book_edit.html:62
#: cps/templates/book_edit.html:68
msgid "No"
msgstr "No"
#: cps/templates/book_edit.html:104
#: cps/templates/book_edit.html:110
msgid "view book after edit"
msgstr "Ver libro tras la edicion"
#: cps/templates/book_edit.html:107 cps/templates/book_edit.html:118
#: cps/templates/book_edit.html:113 cps/templates/book_edit.html:146
msgid "Get metadata"
msgstr "Obtener metainformación"
#: cps/templates/book_edit.html:108 cps/templates/config_edit.html:121
#: cps/templates/book_edit.html:114 cps/templates/config_edit.html:125
#: cps/templates/login.html:19 cps/templates/search_form.html:79
#: cps/templates/shelf_edit.html:17 cps/templates/user_edit.html:122
#: cps/templates/shelf_edit.html:17 cps/templates/user_edit.html:126
msgid "Submit"
msgstr "Enviar"
#: cps/templates/book_edit.html:121
#: cps/templates/book_edit.html:125
msgid "Are really you sure?"
msgstr ""
#: cps/templates/book_edit.html:128
msgid "Book will be deleted from Calibre database"
msgstr ""
#: cps/templates/book_edit.html:129
msgid "and from hard disk"
msgstr ""
#: cps/templates/book_edit.html:133
msgid "Delete"
msgstr ""
#: cps/templates/book_edit.html:149
msgid "Keyword"
msgstr "Palabra clave"
#: cps/templates/book_edit.html:122
#: cps/templates/book_edit.html:150
msgid " Search keyword "
msgstr "Buscar palabras clave"
#: cps/templates/book_edit.html:124 cps/templates/layout.html:60
#: cps/templates/book_edit.html:152 cps/templates/layout.html:60
msgid "Go!"
msgstr "¡Vamos!"
#: cps/templates/book_edit.html:125
#: cps/templates/book_edit.html:153
msgid "Click the cover to load metadata to the form"
msgstr "Haga clic en la portada para cargar la metainformación en el formulario"
#: cps/templates/book_edit.html:129 cps/templates/book_edit.html:142
#: cps/templates/book_edit.html:157 cps/templates/book_edit.html:170
msgid "Loading..."
msgstr "Cargando..."
#: cps/templates/book_edit.html:132
#: cps/templates/book_edit.html:160
msgid "Close"
msgstr "Cerrar"
#: cps/templates/book_edit.html:143
#: cps/templates/book_edit.html:171
msgid "Search error!"
msgstr "¡Error en la búsqueda!"
#: cps/templates/book_edit.html:144
#: cps/templates/book_edit.html:172
msgid "No Result! Please try anonther keyword."
msgstr "¡Sin resultados! Por favor, pruebe otra palabra clave."
#: cps/templates/book_edit.html:146 cps/templates/detail.html:76
#: cps/templates/book_edit.html:174 cps/templates/detail.html:76
#: cps/templates/search_form.html:14
msgid "Publisher"
msgstr "Editor"
#: cps/templates/book_edit.html:148
#: cps/templates/book_edit.html:176
msgid "Source"
msgstr "Origen"
@ -721,15 +745,19 @@ msgstr "Permitir subidas de archivos"
msgid "Allow Edit"
msgstr "Permitir editar"
#: cps/templates/config_edit.html:115 cps/templates/user_edit.html:105
#: cps/templates/config_edit.html:115 cps/templates/user_edit.html:104
msgid "Allow Delete books"
msgstr ""
#: cps/templates/config_edit.html:119 cps/templates/user_edit.html:109
msgid "Allow Changing Password"
msgstr "Permitir cambiar la clave"
#: cps/templates/config_edit.html:119 cps/templates/user_edit.html:109
#: cps/templates/config_edit.html:123 cps/templates/user_edit.html:113
msgid "Allow Editing Public Shelfs"
msgstr ""
#: cps/templates/config_edit.html:126 cps/templates/layout.html:93
#: cps/templates/config_edit.html:130 cps/templates/layout.html:93
#: cps/templates/login.html:4
msgid "Login"
msgstr "Inicio de Sesion"
@ -1104,11 +1132,11 @@ msgstr "Mostrar leídos y no leídos"
msgid "Show random books in detail view"
msgstr "Mostrar libro aleatorios con vista detallada"
#: cps/templates/user_edit.html:116
#: cps/templates/user_edit.html:120
msgid "Delete this user"
msgstr "Borrar este usuario"
#: cps/templates/user_edit.html:131
#: cps/templates/user_edit.html:135
msgid "Recent Downloads"
msgstr "Descargas Recientes"

@ -20,7 +20,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Calibre-web\n"
"Report-Msgid-Bugs-To: https://github.com/janeczku/calibre-web\n"
"POT-Creation-Date: 2017-04-14 09:38+0200\n"
"POT-Creation-Date: 2017-04-14 20:25+0200\n"
"PO-Revision-Date: 2016-11-13 18:35+0100\n"
"Last-Translator: Nicolas Roudninski <nicoroud@gmail.com>\n"
"Language: fr\n"
@ -31,7 +31,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.3.4\n"
#: cps/book_formats.py:113 cps/book_formats.py:117 cps/web.py:1235
#: cps/book_formats.py:113 cps/book_formats.py:117 cps/web.py:1258
msgid "not installed"
msgstr ""
@ -60,327 +60,331 @@ msgstr "Impossible de trouver un format adapté à envoyer par courriel"
msgid "Could not convert epub to mobi"
msgstr "Impossible de convertir epub vers mobi"
#: cps/ub.py:471
#: cps/ub.py:481
msgid "Guest"
msgstr ""
#: cps/web.py:894
#: cps/web.py:917
msgid "Requesting update package"
msgstr ""
#: cps/web.py:895
#: cps/web.py:918
msgid "Downloading update package"
msgstr ""
#: cps/web.py:896
#: cps/web.py:919
msgid "Unzipping update package"
msgstr ""
#: cps/web.py:897
#: cps/web.py:920
msgid "Files are replaced"
msgstr ""
#: cps/web.py:898
#: cps/web.py:921
msgid "Database connections are closed"
msgstr ""
#: cps/web.py:899
#: cps/web.py:922
msgid "Server is stopped"
msgstr ""
#: cps/web.py:900
#: cps/web.py:923
msgid "Update finished, please press okay and reload page"
msgstr ""
#: cps/web.py:974
#: cps/web.py:997
msgid "Latest Books"
msgstr "Derniers livres"
#: cps/web.py:1005
#: cps/web.py:1028
msgid "Hot Books (most downloaded)"
msgstr "Livres populaires (les plus téléchargés)"
#: cps/web.py:1015
#: cps/web.py:1038
msgid "Best rated books"
msgstr ""
#: cps/templates/index.xml:36 cps/web.py:1024
#: cps/templates/index.xml:36 cps/web.py:1047
msgid "Random Books"
msgstr "Livres au hasard"
#: cps/web.py:1037
#: cps/web.py:1060
msgid "Author list"
msgstr "Liste des auteurs"
#: cps/web.py:1048
#: cps/web.py:1072
#, python-format
msgid "Author: %(name)s"
msgstr ""
#: cps/web.py:1050 cps/web.py:1078 cps/web.py:1212 cps/web.py:1614
#: cps/web.py:2578
#: cps/web.py:1074 cps/web.py:1102 cps/web.py:1235 cps/web.py:1672
#: cps/web.py:2655
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 :"
#: cps/templates/index.xml:71 cps/web.py:1064
#: cps/templates/index.xml:71 cps/web.py:1088
msgid "Series list"
msgstr "Liste des séries"
#: cps/web.py:1076
#: cps/web.py:1100
#, python-format
msgid "Series: %(serie)s"
msgstr "Séries : %(serie)s"
#: cps/web.py:1109
#: cps/web.py:1133
msgid "Available languages"
msgstr "Langues disponibles"
#: cps/web.py:1124
#: cps/web.py:1148
#, python-format
msgid "Language: %(name)s"
msgstr "Langue : %(name)s"
#: cps/templates/index.xml:64 cps/web.py:1137
#: cps/templates/index.xml:64 cps/web.py:1161
msgid "Category list"
msgstr "Liste des catégories"
#: cps/web.py:1149
#: cps/web.py:1173
#, python-format
msgid "Category: %(name)s"
msgstr "Catégorie : %(name)s"
#: cps/web.py:1257
#: cps/web.py:1280
msgid "Statistics"
msgstr "Statistiques"
#: cps/web.py:1365
#: cps/web.py:1415
msgid "Server restarted, please reload page"
msgstr ""
#: cps/web.py:1367
#: cps/web.py:1417
msgid "Performing shutdown of server, please close window"
msgstr ""
#: cps/web.py:1382
#: cps/web.py:1433
msgid "Update done"
msgstr ""
#: cps/web.py:1460 cps/web.py:1473
#: cps/web.py:1511 cps/web.py:1524
msgid "search"
msgstr ""
#: cps/web.py:1590 cps/web.py:1597 cps/web.py:1604 cps/web.py:1611
#: cps/web.py:1648 cps/web.py:1655 cps/web.py:1662 cps/web.py:1669
msgid "Read a Book"
msgstr "Lire un livre"
#: cps/web.py:1664 cps/web.py:2144
#: cps/web.py:1725 cps/web.py:2207
msgid "Please fill out all fields!"
msgstr "SVP, complétez tous les champs !"
#: cps/web.py:1665 cps/web.py:1681 cps/web.py:1686 cps/web.py:1688
#: cps/web.py:1726 cps/web.py:1742 cps/web.py:1747 cps/web.py:1749
msgid "register"
msgstr "S'enregistrer"
#: cps/web.py:1680
#: cps/web.py:1741
msgid "An unknown error occured. Please try again later."
msgstr "Une erreur a eu lieu. Merci de réessayez plus tard."
#: cps/web.py:1685
#: cps/web.py:1746
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."
#: cps/web.py:1703
#: cps/web.py:1764
#, python-format
msgid "you are now logged in as: '%(nickname)s'"
msgstr "Vous êtes maintenant connecté sous : '%(nickname)s'"
#: cps/web.py:1708
#: cps/web.py:1769
msgid "Wrong Username or Password"
msgstr "Mauvais nom d'utilisateur ou mot de passe"
#: cps/web.py:1710
#: cps/web.py:1771
msgid "login"
msgstr "Connexion"
#: cps/web.py:1727
#: cps/web.py:1788
msgid "Please configure the SMTP mail settings first..."
msgstr "Veillez configurer les paramètres smtp d'abord..."
#: cps/web.py:1731
#: cps/web.py:1792
#, python-format
msgid "Book successfully send to %(kindlemail)s"
msgstr "Livres envoyés à %(kindlemail)s avec succès"
#: cps/web.py:1735
#: cps/web.py:1796
#, python-format
msgid "There was an error sending this book: %(res)s"
msgstr "Il y a eu une erreur en envoyant ce livre : %(res)s"
#: cps/web.py:1737 cps/web.py:2226
#: cps/web.py:1798 cps/web.py:2291
msgid "Please configure your kindle email address first..."
msgstr "Veuillez configurer votre adresse kindle d'abord..."
#: cps/web.py:1762
#: cps/web.py:1823
#, python-format
msgid "Book has been added to shelf: %(sname)s"
msgstr "Le livre a bien été ajouté à l'étagère : %(sname)s"
#: cps/web.py:1782
#: cps/web.py:1843
#, python-format
msgid "Book has been removed from shelf: %(sname)s"
msgstr "Le livre a été supprimé de l'étagère %(sname)s"
#: cps/web.py:1800 cps/web.py:1824
#: cps/web.py:1861 cps/web.py:1885
#, python-format
msgid "A shelf with the name '%(title)s' already exists."
msgstr "Une étagère de ce nom '%(title)s' existe déjà."
#: cps/web.py:1805
#: cps/web.py:1866
#, python-format
msgid "Shelf %(title)s created"
msgstr "Étagère %(title)s créée"
#: cps/web.py:1807 cps/web.py:1835
#: cps/web.py:1868 cps/web.py:1896
msgid "There was an error"
msgstr "Il y a eu une erreur"
#: cps/web.py:1808 cps/web.py:1810
#: cps/web.py:1869 cps/web.py:1871
msgid "create a shelf"
msgstr "Créer une étagère"
#: cps/web.py:1833
#: cps/web.py:1894
#, python-format
msgid "Shelf %(title)s changed"
msgstr ""
#: cps/web.py:1836 cps/web.py:1838
#: cps/web.py:1897 cps/web.py:1899
msgid "Edit a shelf"
msgstr ""
#: cps/web.py:1858
#: cps/web.py:1919
#, python-format
msgid "successfully deleted shelf %(name)s"
msgstr "L'étagère %(name)s a été supprimé avec succès"
#: cps/web.py:1880
#: cps/web.py:1941
#, python-format
msgid "Shelf: '%(name)s'"
msgstr "Étagère : '%(name)s'"
#: cps/web.py:1911
#: cps/web.py:1972
#, python-format
msgid "Change order of Shelf: '%(name)s'"
msgstr ""
#: cps/web.py:1975
#: cps/web.py:2036
msgid "Found an existing account for this email address."
msgstr "Un compte avec cette adresse de courriel existe déjà."
#: cps/web.py:1977 cps/web.py:1981
#: cps/web.py:2038 cps/web.py:2042
#, python-format
msgid "%(name)s's profile"
msgstr "Profil de %(name)s"
#: cps/web.py:1978
#: cps/web.py:2039
msgid "Profile updated"
msgstr "Profil mis à jour"
#: cps/web.py:1992
#: cps/web.py:2053
msgid "Admin page"
msgstr ""
#: cps/web.py:2098
#: cps/web.py:2161
msgid "Calibre-web configuration updated"
msgstr ""
#: cps/web.py:2105 cps/web.py:2111 cps/web.py:2125
#: cps/web.py:2168 cps/web.py:2174 cps/web.py:2188
msgid "Basic Configuration"
msgstr ""
#: cps/web.py:2109
#: cps/web.py:2172
msgid "DB location is not valid, please enter correct path"
msgstr ""
#: cps/templates/admin.html:34 cps/web.py:2146 cps/web.py:2196
#: cps/templates/admin.html:34 cps/web.py:2209 cps/web.py:2261
msgid "Add new user"
msgstr "Ajouter un nouvel utilisateur"
#: cps/web.py:2188
#: cps/web.py:2253
#, python-format
msgid "User '%(user)s' created"
msgstr "Utilisateur '%(user)s' créé"
#: cps/web.py:2192
#: cps/web.py:2257
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à."
#: cps/web.py:2214
#: cps/web.py:2279
msgid "Mail settings updated"
msgstr "Paramètres de courriel mis à jour"
#: cps/web.py:2221
#: cps/web.py:2286
#, python-format
msgid "Test E-Mail successfully send to %(kindlemail)s"
msgstr ""
#: cps/web.py:2224
#: cps/web.py:2289
#, python-format
msgid "There was an error sending the Test E-Mail: %(res)s"
msgstr ""
#: cps/web.py:2228
#: cps/web.py:2293
msgid "E-Mail settings updated"
msgstr ""
#: cps/web.py:2229
#: cps/web.py:2294
msgid "Edit mail settings"
msgstr "Éditer les paramètres de courriel"
#: cps/web.py:2257
#: cps/web.py:2322
#, python-format
msgid "User '%(nick)s' deleted"
msgstr "Utilisateur '%(nick)s' supprimé"
#: cps/web.py:2348
#: cps/web.py:2418
#, python-format
msgid "User '%(nick)s' updated"
msgstr "Utilisateur '%(nick)s' mis à jour"
#: cps/web.py:2351
#: cps/web.py:2421
msgid "An unknown error occured."
msgstr "Oups ! Une erreur inconnue a eu lieu."
#: cps/web.py:2354
#: cps/web.py:2424
#, python-format
msgid "Edit User %(nick)s"
msgstr "Éditer l'utilisateur %(nick)s"
#: cps/web.py:2573 cps/web.py:2576 cps/web.py:2688
#: cps/web.py:2459 cps/web.py:2463
msgid "unknown"
msgstr ""
#: cps/web.py:2650 cps/web.py:2653 cps/web.py:2763
msgid "edit metadata"
msgstr ""
#: cps/web.py:2597
#: cps/web.py:2674
#, python-format
msgid "File extension \"%s\" is not allowed to be uploaded to this server"
msgstr ""
#: cps/web.py:2603
#: cps/web.py:2680
msgid "File to be uploaded must have an extension"
msgstr ""
#: cps/web.py:2620
#: cps/web.py:2697
#, python-format
msgid "Failed to create path %s (Permission denied)."
msgstr "Impossible de créer le chemin %s (permission refusée)"
#: cps/web.py:2625
#: cps/web.py:2702
#, python-format
msgid "Failed to store file %s (Permission denied)."
msgstr "Impossible d'enregistrer le fichier %s (permission refusée)"
#: cps/web.py:2630
#: cps/web.py:2707
#, python-format
msgid "Failed to delete file %s (Permission denied)."
msgstr "Impossible de supprimer le fichier %s (permission refusée)"
@ -531,10 +535,10 @@ msgid "Ok"
msgstr ""
#: cps/templates/admin.html:103 cps/templates/admin.html:117
#: cps/templates/book_edit.html:109 cps/templates/config_edit.html:123
#: cps/templates/email_edit.html:36 cps/templates/shelf.html:53
#: cps/templates/shelf_edit.html:19 cps/templates/shelf_order.html:12
#: cps/templates/user_edit.html:124
#: cps/templates/book_edit.html:115 cps/templates/book_edit.html:134
#: cps/templates/config_edit.html:127 cps/templates/email_edit.html:36
#: cps/templates/shelf.html:53 cps/templates/shelf_edit.html:19
#: cps/templates/shelf_order.html:12 cps/templates/user_edit.html:128
msgid "Back"
msgstr "Retour"
@ -546,104 +550,124 @@ msgstr ""
msgid "Updating, please do not reload page"
msgstr ""
#: cps/templates/book_edit.html:16 cps/templates/search_form.html:6
#: cps/templates/book_edit.html:16
msgid "Delete Book"
msgstr ""
#: cps/templates/book_edit.html:22 cps/templates/search_form.html:6
msgid "Book Title"
msgstr "Titre du livre"
#: cps/templates/book_edit.html:20 cps/templates/book_edit.html:145
#: cps/templates/book_edit.html:26 cps/templates/book_edit.html:173
#: cps/templates/search_form.html:10
msgid "Author"
msgstr "Auteur"
#: cps/templates/book_edit.html:24 cps/templates/book_edit.html:147
#: cps/templates/book_edit.html:30 cps/templates/book_edit.html:175
msgid "Description"
msgstr "Description"
#: cps/templates/book_edit.html:28 cps/templates/search_form.html:17
#: cps/templates/book_edit.html:34 cps/templates/search_form.html:17
msgid "Tags"
msgstr "Étiquette"
#: cps/templates/book_edit.html:33 cps/templates/layout.html:142
#: cps/templates/book_edit.html:39 cps/templates/layout.html:142
#: cps/templates/search_form.html:37
msgid "Series"
msgstr "Séries"
#: cps/templates/book_edit.html:37
#: cps/templates/book_edit.html:43
msgid "Series id"
msgstr "Id de série"
#: cps/templates/book_edit.html:41
#: cps/templates/book_edit.html:47
msgid "Rating"
msgstr "Évaluation"
#: cps/templates/book_edit.html:45
#: cps/templates/book_edit.html:51
msgid "Cover URL (jpg)"
msgstr "Adresse de la couverture (jpg)"
#: cps/templates/book_edit.html:50 cps/templates/user_edit.html:27
#: cps/templates/book_edit.html:56 cps/templates/user_edit.html:27
msgid "Language"
msgstr "Langue"
#: cps/templates/book_edit.html:61
#: cps/templates/book_edit.html:67
msgid "Yes"
msgstr "Oui"
#: cps/templates/book_edit.html:62
#: cps/templates/book_edit.html:68
msgid "No"
msgstr "Non"
#: cps/templates/book_edit.html:104
#: cps/templates/book_edit.html:110
msgid "view book after edit"
msgstr "Voir le livre après l'édition"
#: cps/templates/book_edit.html:107 cps/templates/book_edit.html:118
#: cps/templates/book_edit.html:113 cps/templates/book_edit.html:146
msgid "Get metadata"
msgstr ""
#: cps/templates/book_edit.html:108 cps/templates/config_edit.html:121
#: cps/templates/book_edit.html:114 cps/templates/config_edit.html:125
#: cps/templates/login.html:19 cps/templates/search_form.html:79
#: cps/templates/shelf_edit.html:17 cps/templates/user_edit.html:122
#: cps/templates/shelf_edit.html:17 cps/templates/user_edit.html:126
msgid "Submit"
msgstr "Soumettre"
#: cps/templates/book_edit.html:121
#: cps/templates/book_edit.html:125
msgid "Are really you sure?"
msgstr ""
#: cps/templates/book_edit.html:128
msgid "Book will be deleted from Calibre database"
msgstr ""
#: cps/templates/book_edit.html:129
msgid "and from hard disk"
msgstr ""
#: cps/templates/book_edit.html:133
msgid "Delete"
msgstr ""
#: cps/templates/book_edit.html:149
msgid "Keyword"
msgstr ""
#: cps/templates/book_edit.html:122
#: cps/templates/book_edit.html:150
msgid " Search keyword "
msgstr ""
#: cps/templates/book_edit.html:124 cps/templates/layout.html:60
#: cps/templates/book_edit.html:152 cps/templates/layout.html:60
msgid "Go!"
msgstr "Allez !"
#: cps/templates/book_edit.html:125
#: cps/templates/book_edit.html:153
msgid "Click the cover to load metadata to the form"
msgstr ""
#: cps/templates/book_edit.html:129 cps/templates/book_edit.html:142
#: cps/templates/book_edit.html:157 cps/templates/book_edit.html:170
msgid "Loading..."
msgstr ""
#: cps/templates/book_edit.html:132
#: cps/templates/book_edit.html:160
msgid "Close"
msgstr ""
#: cps/templates/book_edit.html:143
#: cps/templates/book_edit.html:171
msgid "Search error!"
msgstr ""
#: cps/templates/book_edit.html:144
#: cps/templates/book_edit.html:172
msgid "No Result! Please try anonther keyword."
msgstr ""
#: cps/templates/book_edit.html:146 cps/templates/detail.html:76
#: cps/templates/book_edit.html:174 cps/templates/detail.html:76
#: cps/templates/search_form.html:14
msgid "Publisher"
msgstr ""
#: cps/templates/book_edit.html:148
#: cps/templates/book_edit.html:176
msgid "Source"
msgstr ""
@ -727,15 +751,19 @@ msgstr "Permettre les téléversements"
msgid "Allow Edit"
msgstr "Permettre l'édition"
#: cps/templates/config_edit.html:115 cps/templates/user_edit.html:105
#: cps/templates/config_edit.html:115 cps/templates/user_edit.html:104
msgid "Allow Delete books"
msgstr ""
#: cps/templates/config_edit.html:119 cps/templates/user_edit.html:109
msgid "Allow Changing Password"
msgstr "Permettre le changement de mot de passe"
#: cps/templates/config_edit.html:119 cps/templates/user_edit.html:109
#: cps/templates/config_edit.html:123 cps/templates/user_edit.html:113
msgid "Allow Editing Public Shelfs"
msgstr ""
#: cps/templates/config_edit.html:126 cps/templates/layout.html:93
#: cps/templates/config_edit.html:130 cps/templates/layout.html:93
#: cps/templates/login.html:4
msgid "Login"
msgstr "Connexion"
@ -1108,11 +1136,11 @@ msgstr ""
msgid "Show random books in detail view"
msgstr ""
#: cps/templates/user_edit.html:116
#: cps/templates/user_edit.html:120
msgid "Delete this user"
msgstr "Supprimer cet utilisateur"
#: cps/templates/user_edit.html:131
#: cps/templates/user_edit.html:135
msgid "Recent Downloads"
msgstr "Téléchargements récents"

@ -12,7 +12,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Calibre Web - polski (POT: 2017-04-11 22:51)\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2017-04-14 09:38+0200\n"
"POT-Creation-Date: 2017-04-14 20:25+0200\n"
"PO-Revision-Date: 2017-04-11 22:51+0200\n"
"Last-Translator: Radosław Kierznowski <radek.kierznowski@outlook.com>\n"
"Language: pl\n"
@ -24,7 +24,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.3.4\n"
#: cps/book_formats.py:113 cps/book_formats.py:117 cps/web.py:1235
#: cps/book_formats.py:113 cps/book_formats.py:117 cps/web.py:1258
msgid "not installed"
msgstr "nie zainstalowane"
@ -55,325 +55,329 @@ msgstr ""
msgid "Could not convert epub to mobi"
msgstr "Nie można konwertować epub do mobi"
#: cps/ub.py:471
#: cps/ub.py:481
msgid "Guest"
msgstr "Gość"
#: cps/web.py:894
#: cps/web.py:917
msgid "Requesting update package"
msgstr "Żądanie o pakiet aktualizacji"
#: cps/web.py:895
#: cps/web.py:918
msgid "Downloading update package"
msgstr "Pobieranie pakietu aktualizacji"
#: cps/web.py:896
#: cps/web.py:919
msgid "Unzipping update package"
msgstr "Rozpakowywanie pakietu aktualizacji"
#: cps/web.py:897
#: cps/web.py:920
msgid "Files are replaced"
msgstr "Pliki zostały zastąpione"
#: cps/web.py:898
#: cps/web.py:921
msgid "Database connections are closed"
msgstr "Połączenia z bazą danych zostały zakończone"
#: cps/web.py:899
#: cps/web.py:922
msgid "Server is stopped"
msgstr "Serwer jest zatrzymany"
#: cps/web.py:900
#: cps/web.py:923
msgid "Update finished, please press okay and reload page"
msgstr "Aktualizacja zakończona, proszę nacisnąć OK i odświeżyć stronę"
#: cps/web.py:974
#: cps/web.py:997
msgid "Latest Books"
msgstr "Ostatnie książki"
#: cps/web.py:1005
#: cps/web.py:1028
msgid "Hot Books (most downloaded)"
msgstr "Najpopularniejsze książki (najczęściej pobierane)"
#: cps/web.py:1015
#: cps/web.py:1038
msgid "Best rated books"
msgstr "Najlepiej oceniane książki"
#: cps/templates/index.xml:36 cps/web.py:1024
#: cps/templates/index.xml:36 cps/web.py:1047
msgid "Random Books"
msgstr "Losowe książki"
#: cps/web.py:1037
#: cps/web.py:1060
msgid "Author list"
msgstr "Lista autorów"
#: cps/web.py:1048
#: cps/web.py:1072
#, python-format
msgid "Author: %(name)s"
msgstr "Autor: %(name)s"
#: cps/web.py:1050 cps/web.py:1078 cps/web.py:1212 cps/web.py:1614
#: cps/web.py:2578
#: cps/web.py:1074 cps/web.py:1102 cps/web.py:1235 cps/web.py:1672
#: cps/web.py:2655
msgid "Error opening eBook. File does not exist or file is not accessible:"
msgstr "Błąd otwierania e-booka. Plik nie istnieje lub plik nie jest dostępny:"
#: cps/templates/index.xml:71 cps/web.py:1064
#: cps/templates/index.xml:71 cps/web.py:1088
msgid "Series list"
msgstr "Lista serii"
#: cps/web.py:1076
#: cps/web.py:1100
#, python-format
msgid "Series: %(serie)s"
msgstr "Seria: %(serie)s"
#: cps/web.py:1109
#: cps/web.py:1133
msgid "Available languages"
msgstr "Dostępne języki"
#: cps/web.py:1124
#: cps/web.py:1148
#, python-format
msgid "Language: %(name)s"
msgstr "Język: %(name)s"
#: cps/templates/index.xml:64 cps/web.py:1137
#: cps/templates/index.xml:64 cps/web.py:1161
msgid "Category list"
msgstr "Lista kategorii"
#: cps/web.py:1149
#: cps/web.py:1173
#, python-format
msgid "Category: %(name)s"
msgstr "Kategoria: %(name)s"
#: cps/web.py:1257
#: cps/web.py:1280
msgid "Statistics"
msgstr "Statystyki"
#: cps/web.py:1365
#: cps/web.py:1415
msgid "Server restarted, please reload page"
msgstr "Serwer uruchomiony ponownie, proszę odświeżyć stronę"
#: cps/web.py:1367
#: cps/web.py:1417
msgid "Performing shutdown of server, please close window"
msgstr "Wykonano wyłączenie serwera, proszę zamknąć okno"
#: cps/web.py:1382
#: cps/web.py:1433
msgid "Update done"
msgstr "Aktualizacja zakończona"
#: cps/web.py:1460 cps/web.py:1473
#: cps/web.py:1511 cps/web.py:1524
msgid "search"
msgstr "szukaj"
#: cps/web.py:1590 cps/web.py:1597 cps/web.py:1604 cps/web.py:1611
#: cps/web.py:1648 cps/web.py:1655 cps/web.py:1662 cps/web.py:1669
msgid "Read a Book"
msgstr "Czytaj książkę"
#: cps/web.py:1664 cps/web.py:2144
#: cps/web.py:1725 cps/web.py:2207
msgid "Please fill out all fields!"
msgstr "Proszę wypełnić wszystkie pola!"
#: cps/web.py:1665 cps/web.py:1681 cps/web.py:1686 cps/web.py:1688
#: cps/web.py:1726 cps/web.py:1742 cps/web.py:1747 cps/web.py:1749
msgid "register"
msgstr "rejestracja"
#: cps/web.py:1680
#: cps/web.py:1741
msgid "An unknown error occured. Please try again later."
msgstr "Wystąpił nieznany błąd. Spróbuj ponownie później."
#: cps/web.py:1685
#: cps/web.py:1746
msgid "This username or email address is already in use."
msgstr "Nazwa użytkownika lub adres e-mail jest już w użyciu."
#: cps/web.py:1703
#: cps/web.py:1764
#, python-format
msgid "you are now logged in as: '%(nickname)s'"
msgstr "Zalogowałeś się jako: '%(nickname)s'"
#: cps/web.py:1708
#: cps/web.py:1769
msgid "Wrong Username or Password"
msgstr "Błędna nazwa użytkownika lub hasło"
#: cps/web.py:1710
#: cps/web.py:1771
msgid "login"
msgstr "logowanie"
#: cps/web.py:1727
#: cps/web.py:1788
msgid "Please configure the SMTP mail settings first..."
msgstr "Proszę najpierw skonfigurować ustawienia SMTP poczty e-mail..."
#: cps/web.py:1731
#: cps/web.py:1792
#, python-format
msgid "Book successfully send to %(kindlemail)s"
msgstr "Książka została pomyślnie wysłana do %(kindlemail)s"
#: cps/web.py:1735
#: cps/web.py:1796
#, python-format
msgid "There was an error sending this book: %(res)s"
msgstr "Wystąpił błąd podczas wysyłania tej książki: %(res)s"
#: cps/web.py:1737 cps/web.py:2226
#: cps/web.py:1798 cps/web.py:2291
msgid "Please configure your kindle email address first..."
msgstr "Proszę najpierw skonfigurować adres e-mail swojego kindla..."
#: cps/web.py:1762
#: cps/web.py:1823
#, python-format
msgid "Book has been added to shelf: %(sname)s"
msgstr "Książka została dodana do półki: %(sname)s"
#: cps/web.py:1782
#: cps/web.py:1843
#, python-format
msgid "Book has been removed from shelf: %(sname)s"
msgstr "Książka została usunięta z półki: %(sname)s"
#: cps/web.py:1800 cps/web.py:1824
#: cps/web.py:1861 cps/web.py:1885
#, python-format
msgid "A shelf with the name '%(title)s' already exists."
msgstr "Półka o nazwie '%(title)s' już istnieje."
#: cps/web.py:1805
#: cps/web.py:1866
#, python-format
msgid "Shelf %(title)s created"
msgstr "Półka %(title)s została utworzona"
#: cps/web.py:1807 cps/web.py:1835
#: cps/web.py:1868 cps/web.py:1896
msgid "There was an error"
msgstr "Wystąpił błąd"
#: cps/web.py:1808 cps/web.py:1810
#: cps/web.py:1869 cps/web.py:1871
msgid "create a shelf"
msgstr "utwórz półkę"
#: cps/web.py:1833
#: cps/web.py:1894
#, python-format
msgid "Shelf %(title)s changed"
msgstr "Półka %(title)s została zmieniona"
#: cps/web.py:1836 cps/web.py:1838
#: cps/web.py:1897 cps/web.py:1899
msgid "Edit a shelf"
msgstr "Edytuj półkę"
#: cps/web.py:1858
#: cps/web.py:1919
#, python-format
msgid "successfully deleted shelf %(name)s"
msgstr "pomyślnie usunięto półkę %(name)s"
#: cps/web.py:1880
#: cps/web.py:1941
#, python-format
msgid "Shelf: '%(name)s'"
msgstr "Półka: '%(name)s'"
#: cps/web.py:1911
#: cps/web.py:1972
#, python-format
msgid "Change order of Shelf: '%(name)s'"
msgstr "Zmieniono kolejność półki: '%(name)s'"
#: cps/web.py:1975
#: cps/web.py:2036
msgid "Found an existing account for this email address."
msgstr "Znaleziono istniejące konto dla tego adresu e-mail."
#: cps/web.py:1977 cps/web.py:1981
#: cps/web.py:2038 cps/web.py:2042
#, python-format
msgid "%(name)s's profile"
msgstr "Profil użytkownika %(name)s"
#: cps/web.py:1978
#: cps/web.py:2039
msgid "Profile updated"
msgstr "Zaktualizowano profil"
#: cps/web.py:1992
#: cps/web.py:2053
msgid "Admin page"
msgstr "Portal administracyjny"
#: cps/web.py:2098
#: cps/web.py:2161
msgid "Calibre-web configuration updated"
msgstr "Konfiguracja Calibre-web została zaktualizowana"
#: cps/web.py:2105 cps/web.py:2111 cps/web.py:2125
#: cps/web.py:2168 cps/web.py:2174 cps/web.py:2188
msgid "Basic Configuration"
msgstr "Podstawowa konfiguracja"
#: cps/web.py:2109
#: cps/web.py:2172
msgid "DB location is not valid, please enter correct path"
msgstr "Lokalizacja bazy danych jest nieprawidłowa, wpisz poprawną ścieżkę"
#: cps/templates/admin.html:34 cps/web.py:2146 cps/web.py:2196
#: cps/templates/admin.html:34 cps/web.py:2209 cps/web.py:2261
msgid "Add new user"
msgstr "Dodaj nowego użytkownika"
#: cps/web.py:2188
#: cps/web.py:2253
#, python-format
msgid "User '%(user)s' created"
msgstr "Użytkownik '%(user)s' został utworzony"
#: cps/web.py:2192
#: cps/web.py:2257
msgid "Found an existing account for this email address or nickname."
msgstr "Znaleziono istniejące konto dla tego adresu e-mail lub nazwy użytkownika."
#: cps/web.py:2214
#: cps/web.py:2279
msgid "Mail settings updated"
msgstr "Zaktualizowano ustawienia poczty e-mail"
#: cps/web.py:2221
#: cps/web.py:2286
#, python-format
msgid "Test E-Mail successfully send to %(kindlemail)s"
msgstr "Testowy e-mail został pomyślnie wysłany do %(kindlemail)s"
#: cps/web.py:2224
#: cps/web.py:2289
#, python-format
msgid "There was an error sending the Test E-Mail: %(res)s"
msgstr "Wystąpił błąd podczas wysyłania testowej wiadomości e-mail: %(res)s"
#: cps/web.py:2228
#: cps/web.py:2293
msgid "E-Mail settings updated"
msgstr "Zaktualizowano ustawienia e-mail"
#: cps/web.py:2229
#: cps/web.py:2294
msgid "Edit mail settings"
msgstr "Edytuj ustawienia poczty e-mail"
#: cps/web.py:2257
#: cps/web.py:2322
#, python-format
msgid "User '%(nick)s' deleted"
msgstr "Użytkownik '%(nick)s' został usunięty"
#: cps/web.py:2348
#: cps/web.py:2418
#, python-format
msgid "User '%(nick)s' updated"
msgstr "Użytkownik '%(nick)s' został zaktualizowany"
#: cps/web.py:2351
#: cps/web.py:2421
msgid "An unknown error occured."
msgstr "Wystąpił nieznany błąd."
#: cps/web.py:2354
#: cps/web.py:2424
#, python-format
msgid "Edit User %(nick)s"
msgstr "Edytuj użytkownika %(nick)s"
#: cps/web.py:2573 cps/web.py:2576 cps/web.py:2688
#: cps/web.py:2459 cps/web.py:2463
msgid "unknown"
msgstr ""
#: cps/web.py:2650 cps/web.py:2653 cps/web.py:2763
msgid "edit metadata"
msgstr "edytuj metadane"
#: cps/web.py:2597
#: cps/web.py:2674
#, python-format
msgid "File extension \"%s\" is not allowed to be uploaded to this server"
msgstr "Rozszerzenie pliku \"%s\" nie jest dozwolone do przesłania na ten serwer"
#: cps/web.py:2603
#: cps/web.py:2680
msgid "File to be uploaded must have an extension"
msgstr "Plik do przesłania musi mieć rozszerzenie"
#: cps/web.py:2620
#: cps/web.py:2697
#, python-format
msgid "Failed to create path %s (Permission denied)."
msgstr "Nie udało się utworzyć łącza %s (Odmowa dostępu)."
#: cps/web.py:2625
#: cps/web.py:2702
#, python-format
msgid "Failed to store file %s (Permission denied)."
msgstr "Nie można przechowywać pliku %s (Odmowa dostępu)."
#: cps/web.py:2630
#: cps/web.py:2707
#, python-format
msgid "Failed to delete file %s (Permission denied)."
msgstr "Nie udało się usunąć pliku %s (Odmowa dostępu)."
@ -524,10 +528,10 @@ msgid "Ok"
msgstr "OK"
#: cps/templates/admin.html:103 cps/templates/admin.html:117
#: cps/templates/book_edit.html:109 cps/templates/config_edit.html:123
#: cps/templates/email_edit.html:36 cps/templates/shelf.html:53
#: cps/templates/shelf_edit.html:19 cps/templates/shelf_order.html:12
#: cps/templates/user_edit.html:124
#: cps/templates/book_edit.html:115 cps/templates/book_edit.html:134
#: cps/templates/config_edit.html:127 cps/templates/email_edit.html:36
#: cps/templates/shelf.html:53 cps/templates/shelf_edit.html:19
#: cps/templates/shelf_order.html:12 cps/templates/user_edit.html:128
msgid "Back"
msgstr "Wróć"
@ -539,104 +543,124 @@ msgstr "Na pewno chcesz zatrzymać Calibre Web?"
msgid "Updating, please do not reload page"
msgstr "Aktualizowanie, proszę nie odświeżać strony"
#: cps/templates/book_edit.html:16 cps/templates/search_form.html:6
#: cps/templates/book_edit.html:16
msgid "Delete Book"
msgstr ""
#: cps/templates/book_edit.html:22 cps/templates/search_form.html:6
msgid "Book Title"
msgstr "Tytuł książki"
#: cps/templates/book_edit.html:20 cps/templates/book_edit.html:145
#: cps/templates/book_edit.html:26 cps/templates/book_edit.html:173
#: cps/templates/search_form.html:10
msgid "Author"
msgstr "Autor"
#: cps/templates/book_edit.html:24 cps/templates/book_edit.html:147
#: cps/templates/book_edit.html:30 cps/templates/book_edit.html:175
msgid "Description"
msgstr "Opis"
#: cps/templates/book_edit.html:28 cps/templates/search_form.html:17
#: cps/templates/book_edit.html:34 cps/templates/search_form.html:17
msgid "Tags"
msgstr "Tagi"
#: cps/templates/book_edit.html:33 cps/templates/layout.html:142
#: cps/templates/book_edit.html:39 cps/templates/layout.html:142
#: cps/templates/search_form.html:37
msgid "Series"
msgstr "Seria"
#: cps/templates/book_edit.html:37
#: cps/templates/book_edit.html:43
msgid "Series id"
msgstr "ID serii"
#: cps/templates/book_edit.html:41
#: cps/templates/book_edit.html:47
msgid "Rating"
msgstr "Ocena"
#: cps/templates/book_edit.html:45
#: cps/templates/book_edit.html:51
msgid "Cover URL (jpg)"
msgstr "Adres URL okładki (jpg)"
#: cps/templates/book_edit.html:50 cps/templates/user_edit.html:27
#: cps/templates/book_edit.html:56 cps/templates/user_edit.html:27
msgid "Language"
msgstr "Język"
#: cps/templates/book_edit.html:61
#: cps/templates/book_edit.html:67
msgid "Yes"
msgstr "Tak"
#: cps/templates/book_edit.html:62
#: cps/templates/book_edit.html:68
msgid "No"
msgstr "Nie"
#: cps/templates/book_edit.html:104
#: cps/templates/book_edit.html:110
msgid "view book after edit"
msgstr "wyświetl książkę po edycji"
#: cps/templates/book_edit.html:107 cps/templates/book_edit.html:118
#: cps/templates/book_edit.html:113 cps/templates/book_edit.html:146
msgid "Get metadata"
msgstr "Uzyskaj metadane"
#: cps/templates/book_edit.html:108 cps/templates/config_edit.html:121
#: cps/templates/book_edit.html:114 cps/templates/config_edit.html:125
#: cps/templates/login.html:19 cps/templates/search_form.html:79
#: cps/templates/shelf_edit.html:17 cps/templates/user_edit.html:122
#: cps/templates/shelf_edit.html:17 cps/templates/user_edit.html:126
msgid "Submit"
msgstr "Wyślij"
#: cps/templates/book_edit.html:121
#: cps/templates/book_edit.html:125
msgid "Are really you sure?"
msgstr ""
#: cps/templates/book_edit.html:128
msgid "Book will be deleted from Calibre database"
msgstr ""
#: cps/templates/book_edit.html:129
msgid "and from hard disk"
msgstr ""
#: cps/templates/book_edit.html:133
msgid "Delete"
msgstr ""
#: cps/templates/book_edit.html:149
msgid "Keyword"
msgstr "Słowo kluczowe"
#: cps/templates/book_edit.html:122
#: cps/templates/book_edit.html:150
msgid " Search keyword "
msgstr " Szukaj słowa kluczowego "
#: cps/templates/book_edit.html:124 cps/templates/layout.html:60
#: cps/templates/book_edit.html:152 cps/templates/layout.html:60
msgid "Go!"
msgstr "Idź!"
#: cps/templates/book_edit.html:125
#: cps/templates/book_edit.html:153
msgid "Click the cover to load metadata to the form"
msgstr "Kliknij okładkę, aby załadować metadane do formularza"
#: cps/templates/book_edit.html:129 cps/templates/book_edit.html:142
#: cps/templates/book_edit.html:157 cps/templates/book_edit.html:170
msgid "Loading..."
msgstr "Ładowanie..."
#: cps/templates/book_edit.html:132
#: cps/templates/book_edit.html:160
msgid "Close"
msgstr "Zamknij"
#: cps/templates/book_edit.html:143
#: cps/templates/book_edit.html:171
msgid "Search error!"
msgstr "Błąd wyszukiwania!"
#: cps/templates/book_edit.html:144
#: cps/templates/book_edit.html:172
msgid "No Result! Please try anonther keyword."
msgstr "Brak wyników! Spróbuj innego słowa kluczowego."
#: cps/templates/book_edit.html:146 cps/templates/detail.html:76
#: cps/templates/book_edit.html:174 cps/templates/detail.html:76
#: cps/templates/search_form.html:14
msgid "Publisher"
msgstr "Wydawca"
#: cps/templates/book_edit.html:148
#: cps/templates/book_edit.html:176
msgid "Source"
msgstr "Źródło"
@ -721,15 +745,19 @@ msgstr "Zezwalaj na wysyłanie"
msgid "Allow Edit"
msgstr "Zezwalaj na edycję"
#: cps/templates/config_edit.html:115 cps/templates/user_edit.html:105
#: cps/templates/config_edit.html:115 cps/templates/user_edit.html:104
msgid "Allow Delete books"
msgstr ""
#: cps/templates/config_edit.html:119 cps/templates/user_edit.html:109
msgid "Allow Changing Password"
msgstr "Zezwalaj na zmianę hasła"
#: cps/templates/config_edit.html:119 cps/templates/user_edit.html:109
#: cps/templates/config_edit.html:123 cps/templates/user_edit.html:113
msgid "Allow Editing Public Shelfs"
msgstr ""
#: cps/templates/config_edit.html:126 cps/templates/layout.html:93
#: cps/templates/config_edit.html:130 cps/templates/layout.html:93
#: cps/templates/login.html:4
msgid "Login"
msgstr "Zaloguj się"
@ -1105,11 +1133,11 @@ msgstr "Pokaż przeczytane i nieprzeczytane"
msgid "Show random books in detail view"
msgstr "Pokaz losowe książki w widoku szczegółowym"
#: cps/templates/user_edit.html:116
#: cps/templates/user_edit.html:120
msgid "Delete this user"
msgstr "Usuń tego użytkownika"
#: cps/templates/user_edit.html:131
#: cps/templates/user_edit.html:135
msgid "Recent Downloads"
msgstr "Ostatnio pobierane"

@ -15,7 +15,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Calibre-web\n"
"Report-Msgid-Bugs-To: https://github.com/janeczku/calibre-web\n"
"POT-Creation-Date: 2017-04-14 09:38+0200\n"
"POT-Creation-Date: 2017-04-14 20:25+0200\n"
"PO-Revision-Date: 2017-01-06 17:00+0000\n"
"Last-Translator: dalin <dalin.lin@gmail.com>\n"
"Language: zh_Hans_CN\n"
@ -26,7 +26,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.3.4\n"
#: cps/book_formats.py:113 cps/book_formats.py:117 cps/web.py:1235
#: cps/book_formats.py:113 cps/book_formats.py:117 cps/web.py:1258
msgid "not installed"
msgstr "未安装"
@ -55,325 +55,329 @@ msgstr "无法找到适合邮件发送的格式"
msgid "Could not convert epub to mobi"
msgstr "无法转换epub到mobi"
#: cps/ub.py:471
#: cps/ub.py:481
msgid "Guest"
msgstr "游客"
#: cps/web.py:894
#: cps/web.py:917
msgid "Requesting update package"
msgstr "正在请求更新包"
#: cps/web.py:895
#: cps/web.py:918
msgid "Downloading update package"
msgstr "正在下载更新包"
#: cps/web.py:896
#: cps/web.py:919
msgid "Unzipping update package"
msgstr "正在解压更新包"
#: cps/web.py:897
#: cps/web.py:920
msgid "Files are replaced"
msgstr "文件已替换"
#: cps/web.py:898
#: cps/web.py:921
msgid "Database connections are closed"
msgstr "数据库连接已关闭"
#: cps/web.py:899
#: cps/web.py:922
msgid "Server is stopped"
msgstr "服务器已停止"
#: cps/web.py:900
#: cps/web.py:923
msgid "Update finished, please press okay and reload page"
msgstr "更新完成,请按确定并刷新页面"
#: cps/web.py:974
#: cps/web.py:997
msgid "Latest Books"
msgstr "最新书籍"
#: cps/web.py:1005
#: cps/web.py:1028
msgid "Hot Books (most downloaded)"
msgstr "热门书籍(最多下载)"
#: cps/web.py:1015
#: cps/web.py:1038
msgid "Best rated books"
msgstr "最高评分书籍"
#: cps/templates/index.xml:36 cps/web.py:1024
#: cps/templates/index.xml:36 cps/web.py:1047
msgid "Random Books"
msgstr "随机书籍"
#: cps/web.py:1037
#: cps/web.py:1060
msgid "Author list"
msgstr "作者列表"
#: cps/web.py:1048
#: cps/web.py:1072
#, python-forma, python-format
msgid "Author: %(name)s"
msgstr "作者: %(name)s"
#: cps/web.py:1050 cps/web.py:1078 cps/web.py:1212 cps/web.py:1614
#: cps/web.py:2578
#: cps/web.py:1074 cps/web.py:1102 cps/web.py:1235 cps/web.py:1672
#: cps/web.py:2655
msgid "Error opening eBook. File does not exist or file is not accessible:"
msgstr "无法打开电子书。 文件不存在或者文件不可访问:"
#: cps/templates/index.xml:71 cps/web.py:1064
#: cps/templates/index.xml:71 cps/web.py:1088
msgid "Series list"
msgstr "丛书列表"
#: cps/web.py:1076
#: cps/web.py:1100
#, python-format
msgid "Series: %(serie)s"
msgstr "丛书: %(serie)s"
#: cps/web.py:1109
#: cps/web.py:1133
msgid "Available languages"
msgstr "可用语言"
#: cps/web.py:1124
#: cps/web.py:1148
#, python-format
msgid "Language: %(name)s"
msgstr "语言: %(name)s"
#: cps/templates/index.xml:64 cps/web.py:1137
#: cps/templates/index.xml:64 cps/web.py:1161
msgid "Category list"
msgstr "分类列表"
#: cps/web.py:1149
#: cps/web.py:1173
#, python-format
msgid "Category: %(name)s"
msgstr "分类: %(name)s"
#: cps/web.py:1257
#: cps/web.py:1280
msgid "Statistics"
msgstr "统计"
#: cps/web.py:1365
#: cps/web.py:1415
msgid "Server restarted, please reload page"
msgstr "服务器已重启,请刷新页面"
#: cps/web.py:1367
#: cps/web.py:1417
msgid "Performing shutdown of server, please close window"
msgstr "正在关闭服务器,请关闭窗口"
#: cps/web.py:1382
#: cps/web.py:1433
msgid "Update done"
msgstr "更新完成"
#: cps/web.py:1460 cps/web.py:1473
#: cps/web.py:1511 cps/web.py:1524
msgid "search"
msgstr "搜索"
#: cps/web.py:1590 cps/web.py:1597 cps/web.py:1604 cps/web.py:1611
#: cps/web.py:1648 cps/web.py:1655 cps/web.py:1662 cps/web.py:1669
msgid "Read a Book"
msgstr "阅读一本书"
#: cps/web.py:1664 cps/web.py:2144
#: cps/web.py:1725 cps/web.py:2207
msgid "Please fill out all fields!"
msgstr "请填写所有字段"
#: cps/web.py:1665 cps/web.py:1681 cps/web.py:1686 cps/web.py:1688
#: cps/web.py:1726 cps/web.py:1742 cps/web.py:1747 cps/web.py:1749
msgid "register"
msgstr "注册"
#: cps/web.py:1680
#: cps/web.py:1741
msgid "An unknown error occured. Please try again later."
msgstr "发生一个未知错误。请稍后再试。"
#: cps/web.py:1685
#: cps/web.py:1746
msgid "This username or email address is already in use."
msgstr "此用户名或邮箱已被使用。"
#: cps/web.py:1703
#: cps/web.py:1764
#, python-format
msgid "you are now logged in as: '%(nickname)s'"
msgstr "您现在已以'%(nickname)s'身份登录"
#: cps/web.py:1708
#: cps/web.py:1769
msgid "Wrong Username or Password"
msgstr "用户名或密码错误"
#: cps/web.py:1710
#: cps/web.py:1771
msgid "login"
msgstr "登录"
#: cps/web.py:1727
#: cps/web.py:1788
msgid "Please configure the SMTP mail settings first..."
msgstr "请先配置SMTP邮箱..."
#: cps/web.py:1731
#: cps/web.py:1792
#, python-format
msgid "Book successfully send to %(kindlemail)s"
msgstr "此书已被成功发给 %(kindlemail)s"
#: cps/web.py:1735
#: cps/web.py:1796
#, python-format
msgid "There was an error sending this book: %(res)s"
msgstr "发送这本书的时候出现错误: %(res)s"
#: cps/web.py:1737 cps/web.py:2226
#: cps/web.py:1798 cps/web.py:2291
msgid "Please configure your kindle email address first..."
msgstr "请先配置您的kindle电子邮箱地址..."
#: cps/web.py:1762
#: cps/web.py:1823
#, python-format
msgid "Book has been added to shelf: %(sname)s"
msgstr "此书已被添加到书架: %(sname)s"
#: cps/web.py:1782
#: cps/web.py:1843
#, python-format
msgid "Book has been removed from shelf: %(sname)s"
msgstr "此书已从书架 %(sname)s 中删除"
#: cps/web.py:1800 cps/web.py:1824
#: cps/web.py:1861 cps/web.py:1885
#, python-format
msgid "A shelf with the name '%(title)s' already exists."
msgstr "已存在书架 '%(title)s'。"
#: cps/web.py:1805
#: cps/web.py:1866
#, python-format
msgid "Shelf %(title)s created"
msgstr "书架 %(title)s 已被创建"
#: cps/web.py:1807 cps/web.py:1835
#: cps/web.py:1868 cps/web.py:1896
msgid "There was an error"
msgstr "发生错误"
#: cps/web.py:1808 cps/web.py:1810
#: cps/web.py:1869 cps/web.py:1871
msgid "create a shelf"
msgstr "创建书架"
#: cps/web.py:1833
#: cps/web.py:1894
#, python-format
msgid "Shelf %(title)s changed"
msgstr "书架 %(title)s 已被修改"
#: cps/web.py:1836 cps/web.py:1838
#: cps/web.py:1897 cps/web.py:1899
msgid "Edit a shelf"
msgstr "编辑书架"
#: cps/web.py:1858
#: cps/web.py:1919
#, python-format
msgid "successfully deleted shelf %(name)s"
msgstr "成功删除书架 %(name)s"
#: cps/web.py:1880
#: cps/web.py:1941
#, python-format
msgid "Shelf: '%(name)s'"
msgstr "书架: '%(name)s'"
#: cps/web.py:1911
#: cps/web.py:1972
#, python-format
msgid "Change order of Shelf: '%(name)s'"
msgstr "修改书架 '%(name)s' 顺序"
#: cps/web.py:1975
#: cps/web.py:2036
msgid "Found an existing account for this email address."
msgstr "找到已使用此邮箱的账号。"
#: cps/web.py:1977 cps/web.py:1981
#: cps/web.py:2038 cps/web.py:2042
#, python-format
msgid "%(name)s's profile"
msgstr "%(name)s 的资料"
#: cps/web.py:1978
#: cps/web.py:2039
msgid "Profile updated"
msgstr "资料已更新"
#: cps/web.py:1992
#: cps/web.py:2053
msgid "Admin page"
msgstr "管理页"
#: cps/web.py:2098
#: cps/web.py:2161
msgid "Calibre-web configuration updated"
msgstr "Calibre-web配置已更新"
#: cps/web.py:2105 cps/web.py:2111 cps/web.py:2125
#: cps/web.py:2168 cps/web.py:2174 cps/web.py:2188
msgid "Basic Configuration"
msgstr "基本配置"
#: cps/web.py:2109
#: cps/web.py:2172
msgid "DB location is not valid, please enter correct path"
msgstr "DB位置无效请输入正确路径"
#: cps/templates/admin.html:34 cps/web.py:2146 cps/web.py:2196
#: cps/templates/admin.html:34 cps/web.py:2209 cps/web.py:2261
msgid "Add new user"
msgstr "添加新用户"
#: cps/web.py:2188
#: cps/web.py:2253
#, python-format
msgid "User '%(user)s' created"
msgstr "用户 '%(user)s' 已被创建"
#: cps/web.py:2192
#: cps/web.py:2257
msgid "Found an existing account for this email address or nickname."
msgstr "已存在使用此邮箱或昵称的账号。"
#: cps/web.py:2214
#: cps/web.py:2279
msgid "Mail settings updated"
msgstr "邮箱设置已更新"
#: cps/web.py:2221
#: cps/web.py:2286
#, python-format
msgid "Test E-Mail successfully send to %(kindlemail)s"
msgstr "测试邮件已成功发送到 %(kindlemail)s"
#: cps/web.py:2224
#: cps/web.py:2289
#, python-format
msgid "There was an error sending the Test E-Mail: %(res)s"
msgstr "发送测试邮件时发生错误: %(res)s"
#: cps/web.py:2228
#: cps/web.py:2293
msgid "E-Mail settings updated"
msgstr "E-Mail 设置已更新"
#: cps/web.py:2229
#: cps/web.py:2294
msgid "Edit mail settings"
msgstr "编辑邮箱设置"
#: cps/web.py:2257
#: cps/web.py:2322
#, python-format
msgid "User '%(nick)s' deleted"
msgstr "用户 '%(nick)s' 已被删除"
#: cps/web.py:2348
#: cps/web.py:2418
#, python-format
msgid "User '%(nick)s' updated"
msgstr "用户 '%(nick)s' 已被更新"
#: cps/web.py:2351
#: cps/web.py:2421
msgid "An unknown error occured."
msgstr "发生未知错误。"
#: cps/web.py:2354
#: cps/web.py:2424
#, python-format
msgid "Edit User %(nick)s"
msgstr "编辑用户 %(nick)s"
#: cps/web.py:2573 cps/web.py:2576 cps/web.py:2688
#: cps/web.py:2459 cps/web.py:2463
msgid "unknown"
msgstr ""
#: cps/web.py:2650 cps/web.py:2653 cps/web.py:2763
msgid "edit metadata"
msgstr "编辑元数据"
#: cps/web.py:2597
#: cps/web.py:2674
#, python-format
msgid "File extension \"%s\" is not allowed to be uploaded to this server"
msgstr "不能上传后缀为 \"%s\" 的文件到此服务器"
#: cps/web.py:2603
#: cps/web.py:2680
msgid "File to be uploaded must have an extension"
msgstr "要上传的文件必须有一个后缀"
#: cps/web.py:2620
#: cps/web.py:2697
#, python-format
msgid "Failed to create path %s (Permission denied)."
msgstr "创建路径 %s 失败(权限拒绝)。"
#: cps/web.py:2625
#: cps/web.py:2702
#, python-format
msgid "Failed to store file %s (Permission denied)."
msgstr "存储文件 %s 失败(权限拒绝)。"
#: cps/web.py:2630
#: cps/web.py:2707
#, python-format
msgid "Failed to delete file %s (Permission denied)."
msgstr "删除文件 %s 失败(权限拒绝)。"
@ -524,10 +528,10 @@ msgid "Ok"
msgstr "确定"
#: cps/templates/admin.html:103 cps/templates/admin.html:117
#: cps/templates/book_edit.html:109 cps/templates/config_edit.html:123
#: cps/templates/email_edit.html:36 cps/templates/shelf.html:53
#: cps/templates/shelf_edit.html:19 cps/templates/shelf_order.html:12
#: cps/templates/user_edit.html:124
#: cps/templates/book_edit.html:115 cps/templates/book_edit.html:134
#: cps/templates/config_edit.html:127 cps/templates/email_edit.html:36
#: cps/templates/shelf.html:53 cps/templates/shelf_edit.html:19
#: cps/templates/shelf_order.html:12 cps/templates/user_edit.html:128
msgid "Back"
msgstr "后退"
@ -539,104 +543,124 @@ msgstr "您确定要关闭 Calibre-web 吗?"
msgid "Updating, please do not reload page"
msgstr "正在更新,请不要刷新页面"
#: cps/templates/book_edit.html:16 cps/templates/search_form.html:6
#: cps/templates/book_edit.html:16
msgid "Delete Book"
msgstr ""
#: cps/templates/book_edit.html:22 cps/templates/search_form.html:6
msgid "Book Title"
msgstr "书名"
#: cps/templates/book_edit.html:20 cps/templates/book_edit.html:145
#: cps/templates/book_edit.html:26 cps/templates/book_edit.html:173
#: cps/templates/search_form.html:10
msgid "Author"
msgstr "作者"
#: cps/templates/book_edit.html:24 cps/templates/book_edit.html:147
#: cps/templates/book_edit.html:30 cps/templates/book_edit.html:175
msgid "Description"
msgstr "简介"
#: cps/templates/book_edit.html:28 cps/templates/search_form.html:17
#: cps/templates/book_edit.html:34 cps/templates/search_form.html:17
msgid "Tags"
msgstr "标签"
#: cps/templates/book_edit.html:33 cps/templates/layout.html:142
#: cps/templates/book_edit.html:39 cps/templates/layout.html:142
#: cps/templates/search_form.html:37
msgid "Series"
msgstr "丛书"
#: cps/templates/book_edit.html:37
#: cps/templates/book_edit.html:43
msgid "Series id"
msgstr "丛书ID"
#: cps/templates/book_edit.html:41
#: cps/templates/book_edit.html:47
msgid "Rating"
msgstr "评分"
#: cps/templates/book_edit.html:45
#: cps/templates/book_edit.html:51
msgid "Cover URL (jpg)"
msgstr "封面URL (jpg)"
#: cps/templates/book_edit.html:50 cps/templates/user_edit.html:27
#: cps/templates/book_edit.html:56 cps/templates/user_edit.html:27
msgid "Language"
msgstr "语言"
#: cps/templates/book_edit.html:61
#: cps/templates/book_edit.html:67
msgid "Yes"
msgstr "确认"
#: cps/templates/book_edit.html:62
#: cps/templates/book_edit.html:68
msgid "No"
msgstr ""
#: cps/templates/book_edit.html:104
#: cps/templates/book_edit.html:110
msgid "view book after edit"
msgstr "编辑后查看书籍"
#: cps/templates/book_edit.html:107 cps/templates/book_edit.html:118
#: cps/templates/book_edit.html:113 cps/templates/book_edit.html:146
msgid "Get metadata"
msgstr "获取元数据"
#: cps/templates/book_edit.html:108 cps/templates/config_edit.html:121
#: cps/templates/book_edit.html:114 cps/templates/config_edit.html:125
#: cps/templates/login.html:19 cps/templates/search_form.html:79
#: cps/templates/shelf_edit.html:17 cps/templates/user_edit.html:122
#: cps/templates/shelf_edit.html:17 cps/templates/user_edit.html:126
msgid "Submit"
msgstr "提交"
#: cps/templates/book_edit.html:121
#: cps/templates/book_edit.html:125
msgid "Are really you sure?"
msgstr ""
#: cps/templates/book_edit.html:128
msgid "Book will be deleted from Calibre database"
msgstr ""
#: cps/templates/book_edit.html:129
msgid "and from hard disk"
msgstr ""
#: cps/templates/book_edit.html:133
msgid "Delete"
msgstr ""
#: cps/templates/book_edit.html:149
msgid "Keyword"
msgstr "关键字"
#: cps/templates/book_edit.html:122
#: cps/templates/book_edit.html:150
msgid " Search keyword "
msgstr "搜索关键字"
#: cps/templates/book_edit.html:124 cps/templates/layout.html:60
#: cps/templates/book_edit.html:152 cps/templates/layout.html:60
msgid "Go!"
msgstr "走起!"
#: cps/templates/book_edit.html:125
#: cps/templates/book_edit.html:153
msgid "Click the cover to load metadata to the form"
msgstr "点击封面加载元数据到表单"
#: cps/templates/book_edit.html:129 cps/templates/book_edit.html:142
#: cps/templates/book_edit.html:157 cps/templates/book_edit.html:170
msgid "Loading..."
msgstr "加载中..."
#: cps/templates/book_edit.html:132
#: cps/templates/book_edit.html:160
msgid "Close"
msgstr "关闭"
#: cps/templates/book_edit.html:143
#: cps/templates/book_edit.html:171
msgid "Search error!"
msgstr "搜索错误"
#: cps/templates/book_edit.html:144
#: cps/templates/book_edit.html:172
msgid "No Result! Please try anonther keyword."
msgstr "没有结果!请尝试别的关键字."
#: cps/templates/book_edit.html:146 cps/templates/detail.html:76
#: cps/templates/book_edit.html:174 cps/templates/detail.html:76
#: cps/templates/search_form.html:14
msgid "Publisher"
msgstr "出版社"
#: cps/templates/book_edit.html:148
#: cps/templates/book_edit.html:176
msgid "Source"
msgstr "来源"
@ -720,15 +744,19 @@ msgstr "允许上传"
msgid "Allow Edit"
msgstr "允许编辑"
#: cps/templates/config_edit.html:115 cps/templates/user_edit.html:105
#: cps/templates/config_edit.html:115 cps/templates/user_edit.html:104
msgid "Allow Delete books"
msgstr ""
#: cps/templates/config_edit.html:119 cps/templates/user_edit.html:109
msgid "Allow Changing Password"
msgstr "允许修改密码"
#: cps/templates/config_edit.html:119 cps/templates/user_edit.html:109
#: cps/templates/config_edit.html:123 cps/templates/user_edit.html:113
msgid "Allow Editing Public Shelfs"
msgstr ""
#: cps/templates/config_edit.html:126 cps/templates/layout.html:93
#: cps/templates/config_edit.html:130 cps/templates/layout.html:93
#: cps/templates/login.html:4
msgid "Login"
msgstr "登录"
@ -1101,11 +1129,11 @@ msgstr "显示已读和未读"
msgid "Show random books in detail view"
msgstr "在详情页显示随机书籍"
#: cps/templates/user_edit.html:116
#: cps/templates/user_edit.html:120
msgid "Delete this user"
msgstr "删除此用户"
#: cps/templates/user_edit.html:131
#: cps/templates/user_edit.html:135
msgid "Recent Downloads"
msgstr "最近下载"

@ -25,6 +25,8 @@ ROLE_EDIT = 8
ROLE_PASSWD = 16
ROLE_ANONYMOUS = 32
ROLE_EDIT_SHELFS = 64
ROLE_DELETE_BOOKS = 128
DETAIL_RANDOM = 1
SIDEBAR_LANGUAGE = 2
@ -90,6 +92,9 @@ class UserBase:
else:
return False
def role_delete_books(self):
return bool((self.role is not None)and(self.role & ROLE_DELETE_BOOKS == ROLE_DELETE_BOOKS))
@classmethod
def is_active(self):
return True
@ -336,6 +341,11 @@ class Config:
else:
return False
def role_delete_books(self):
return bool((self.config_default_role is not None) and
(self.config_default_role & ROLE_DELETE_BOOKS == ROLE_DELETE_BOOKS))
def get_Log_Level(self):
ret_value=""
if self.config_log_level == logging.INFO:
@ -484,7 +494,7 @@ def create_anonymous_user():
def create_admin_user():
user = User()
user.nickname = "admin"
user.role = ROLE_USER + ROLE_ADMIN + ROLE_DOWNLOAD + ROLE_UPLOAD + ROLE_EDIT + ROLE_PASSWD
user.role = ROLE_USER + ROLE_ADMIN + ROLE_DOWNLOAD + ROLE_UPLOAD + ROLE_EDIT + ROLE_DELETE_BOOKS + ROLE_PASSWD
user.sidebar_view = DETAIL_RANDOM + SIDEBAR_LANGUAGE + SIDEBAR_SERIES + SIDEBAR_CATEGORY + SIDEBAR_HOT + \
SIDEBAR_RANDOM + SIDEBAR_AUTHOR + SIDEBAR_BEST_RATED + SIDEBAR_READ_AND_UNREAD

@ -137,12 +137,14 @@ class Singleton:
@Singleton
class Gauth:
def __init__(self):
self.auth=GoogleAuth(settings_file='settings.yaml')
self.auth = GoogleAuth(settings_file='settings.yaml')
@Singleton
class Gdrive:
def __init__(self):
self.drive=gdriveutils.getDrive(Gauth.Instance().auth)
self.drive = gdriveutils.getDrive(Gauth.Instance().auth)
class ReverseProxied(object):
"""Wrap the application in this middleware and configure the
@ -223,7 +225,7 @@ lm.anonymous_user = ub.Anonymous
app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'
db.setup_db()
if config.config_log_level == logging.DEBUG :
if config.config_log_level == logging.DEBUG:
logging.getLogger("sqlalchemy.engine").addHandler(file_handler)
logging.getLogger("sqlalchemy.engine").setLevel(logging.INFO)
logging.getLogger("sqlalchemy.pool").addHandler(file_handler)
@ -235,6 +237,7 @@ if config.config_log_level == logging.DEBUG :
def is_gdrive_ready():
return os.path.exists('settings.yaml') and os.path.exists('gdrive_credentials')
@babel.localeselector
def get_locale():
# if a user is logged in, use the locale from the user settings
@ -274,22 +277,26 @@ def load_user_from_header(header_val):
return user
return
def check_auth(username, password):
user = ub.session.query(ub.User).filter(ub.User.nickname == username).first()
return bool(user and check_password_hash(user.password, password))
def authenticate():
return Response(
'Could not verify your access level for that URL.\n'
'You have to login with proper credentials', 401,
{'WWW-Authenticate': 'Basic realm="Login Required"'})
def updateGdriveCalibreFromLocal():
gdriveutils.backupCalibreDbAndOptionalDownload(Gdrive.Instance().drive)
gdriveutils.copyToDrive(Gdrive.Instance().drive, config.config_calibre_dir, False, True)
for x in os.listdir(config.config_calibre_dir):
if os.path.isdir(os.path.join(config.config_calibre_dir,x)):
shutil.rmtree(os.path.join(config.config_calibre_dir,x))
if os.path.isdir(os.path.join(config.config_calibre_dir, x)):
shutil.rmtree(os.path.join(config.config_calibre_dir, x))
def requires_basic_auth_if_no_ano(f):
@wraps(f)
@ -383,24 +390,27 @@ def mimetype_filter(val):
s = 'application/octet-stream'
return s
@app.template_filter('formatdate')
def formatdate(val):
conformed_timestamp = re.sub(r"[:]|([-](?!((\d{2}[:]\d{2})|(\d{4}))$))", '', val)
formatdate = datetime.datetime.strptime(conformed_timestamp[:15], "%Y%m%d %H%M%S")
return format_date(formatdate, format='medium',locale=get_locale())
return format_date(formatdate, format='medium', locale=get_locale())
@app.template_filter('strftime')
def timestamptodate(date, fmt=None):
date=datetime.datetime.fromtimestamp(
date = datetime.datetime.fromtimestamp(
int(date)/1000
)
native = date.replace(tzinfo=None)
if fmt:
time_format=fmt
time_format = fmt
else:
time_format='%d %m %Y - %H:%S'
time_format = '%d %m %Y - %H:%S'
return native.strftime(time_format)
def admin_required(f):
"""
Checks if current_user.role == 1
@ -484,19 +494,27 @@ def modify_database_object(input_elements, db_book_object, db_object, db_session
del_elements = []
for c_elements in db_book_object:
found = False
if db_type == 'custom':
type_elements=c_elements.value
else:
type_elements=c_elements.name
for inp_element in input_elements:
if inp_element == c_elements.name:
if inp_element == type_elements:
found = True
break
# if the element was not found in the new list, add it to remove list
if not found:
del_elements.append(c_elements)
# 2. search for elements that need to be added
# 2. search for elements that need to be added
add_elements = []
for inp_element in input_elements:
found = False
for c_elements in db_book_object:
if inp_element == c_elements.name:
if db_type == 'custom':
type_elements = c_elements.value
else:
type_elements = c_elements.name
if inp_element == type_elements:
found = True
break
if not found:
@ -511,6 +529,8 @@ def modify_database_object(input_elements, db_book_object, db_object, db_session
if len(add_elements) > 0:
if db_type == 'languages':
db_filter = db_object.lang_code
elif db_type == 'custom':
db_filter = db_object.value
else:
db_filter = db_object.name
for add_element in add_elements:
@ -520,17 +540,17 @@ def modify_database_object(input_elements, db_book_object, db_object, db_session
if new_element is None:
if db_type == 'author':
new_element = db_object(add_element, add_element, "")
else:
if db_type == 'series':
new_element = db_object(add_element, add_element)
else: # db_type should be tag, or languages
new_element = db_object(add_element)
elif db_type == 'series':
new_element = db_object(add_element, add_element)
elif db_type == 'custom':
new_element = db_object(value=add_element)
else: # db_type should be tag, or languages
new_element = db_object(add_element)
db_session.add(new_element)
new_element = db.session.query(db_object).filter(db_filter == add_element).first()
# add element to book
db_book_object.append(new_element)
def render_title_template(*args, **kwargs):
return render_template(instance=config.config_calibre_web_title, *args, **kwargs)
@ -642,6 +662,7 @@ def feed_best_rated():
response.headers["Content-Type"] = "application/xml"
return response
@app.route("/opds/hot")
@requires_basic_auth_if_no_ano
def feed_hot():
@ -781,47 +802,49 @@ def partial(total_byte_len, part_size_limit):
s.append([p, last])
return s
def do_gdrive_download(df, headers):
total_size = int(df.metadata.get('fileSize'))
download_url = df.metadata.get('downloadUrl')
s = partial(total_size, 1024 * 1024) # I'm downloading BIG files, so 100M chunk size is fine for me
s = partial(total_size, 1024 * 1024) # I'm downloading BIG files, so 100M chunk size is fine for me
def stream():
for byte in s:
headers = {"Range" : 'bytes=%s-%s' % (byte[0], byte[1])}
headers = {"Range": 'bytes=%s-%s' % (byte[0], byte[1])}
resp, content = df.auth.Get_Http_Object().request(download_url, headers=headers)
if resp.status == 206 :
if resp.status == 206:
yield content
else:
app.logger.info('An error occurred: %s' % resp)
return
return Response(stream_with_context(stream()), headers=headers)
@app.route("/opds/download/<book_id>/<book_format>/")
@requires_basic_auth_if_no_ano
@download_required
def get_opds_download_link(book_id, book_format):
startTime=time.time()
startTime = time.time()
book_format = book_format.split(".")[0]
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).filter(db.Data.format == book_format.upper()).first()
app.logger.info (data.name)
app.logger.info(data.name)
if current_user.is_authenticated:
helper.update_download(book_id, int(current_user.id))
file_name = book.title
if len(book.authors) > 0:
file_name = book.authors[0].name + '_' + file_name
file_name = helper.get_valid_filename(file_name)
headers = Headers ()
headers = Headers()
headers["Content-Disposition"] = "attachment; filename*=UTF-8''%s.%s" % (quote(file_name.encode('utf8')), book_format)
app.logger.info (time.time()-startTime)
startTime=time.time()
app.logger.info(time.time()-startTime)
startTime = time.time()
if config.config_use_google_drive:
app.logger.info(time.time() - startTime)
df=gdriveutils.getFileFromEbooksFolder(Gdrive.Instance().drive, book.path, data.name + "." + book_format)
df = gdriveutils.getFileFromEbooksFolder(Gdrive.Instance().drive, book.path, data.name + "." + book_format)
return do_gdrive_download(df, headers)
else:
response = make_response(send_from_directory(os.path.join(config.config_calibre_dir, book.path), data.name + "." + book_format))
response.headers=headers
response.headers = headers
return response
@ -856,11 +879,12 @@ def get_tags_json():
query = request.args.get('q')
# entries = db.session.execute("select name from tags where name like '%" + query + "%'")
entries = db.session.query(db.Tags).filter(db.Tags.name.like("%" + query + "%")).all()
#for x in entries:
# for x in entries:
# alfa = dict(name=x.name)
json_dumps = json.dumps([dict(name=r.name) for r in entries])
return json_dumps
@app.route("/get_update_status", methods=['GET'])
@login_required_if_no_ano
def get_update_status():
@ -880,7 +904,8 @@ def get_update_status():
status['status'] = False
return json.dumps(status)
@app.route("/get_updater_status", methods=['GET','POST'])
@app.route("/get_updater_status", methods=['GET', 'POST'])
@login_required
@admin_required
def get_updater_status():
@ -888,7 +913,7 @@ def get_updater_status():
if request.method == "POST":
commit = request.form.to_dict()
if "start" in commit and commit['start'] == 'True':
text={
text = {
"1": _(u'Requesting update package'),
"2": _(u'Downloading update package'),
"3": _(u'Unzipping update package'),
@ -1038,7 +1063,7 @@ def author_list():
@app.route("/author/<int:book_id>", defaults={'page': 1})
@app.route("/author/<int:book_id>/<int:page>'")
@login_required_if_no_ano
def author(book_id,page):
def author(book_id, page):
entries, random, pagination = fill_indexpage(page, db.Books, db.Books.authors.any(db.Authors.id == book_id),
db.Books.timestamp.desc())
name = db.session.query(db.Authors).filter(db.Authors.id == book_id).first().name
@ -1069,7 +1094,7 @@ def series_list():
def series(book_id, page):
entries, random, pagination = fill_indexpage(page, db.Books, db.Books.series.any(db.Series.id == book_id),
db.Books.series_index)
name=db.session.query(db.Series).filter(db.Series.id == book_id).first().name
name = db.session.query(db.Series).filter(db.Series.id == book_id).first().name
if entries:
return render_title_template('index.html', random=random, pagination=pagination, entries=entries,
title=_(u"Series: %(serie)s", serie=name))
@ -1143,7 +1168,7 @@ def category(book_id, page):
entries, random, pagination = fill_indexpage(page, db.Books, db.Books.tags.any(db.Tags.id == book_id),
db.Books.timestamp.desc())
name=db.session.query(db.Tags).filter(db.Tags.id == book_id).first().name
name = db.session.query(db.Tags).filter(db.Tags.id == book_id).first().name
return render_title_template('index.html', random=random, entries=entries, pagination=pagination,
title=_(u"Category: %(name)s", name=name))
@ -1154,17 +1179,18 @@ def toggle_read(book_id):
book = ub.session.query(ub.ReadBook).filter(ub.and_(ub.ReadBook.user_id == int(current_user.id),
ub.ReadBook.book_id == book_id)).first()
if book:
book.is_read=not book.is_read
book.is_read = not book.is_read
else:
readBook=ub.ReadBook()
readBook.user_id=int(current_user.id)
readBook = ub.ReadBook()
readBook.user_id = int(current_user.id)
readBook.book_id = book_id
readBook.is_read=True
book=readBook
readBook.is_read = True
book = readBook
ub.session.merge(book)
ub.session.commit()
return ""
@app.route("/book/<int:book_id>")
@login_required_if_no_ano
def show_book(book_id):
@ -1184,26 +1210,24 @@ def show_book(book_id):
tmpcc = db.session.query(db.Custom_Columns).filter(db.Custom_Columns.datatype.notin_(db.cc_exceptions)).all()
if config.config_columns_to_ignore:
cc=[]
cc = []
for col in tmpcc:
r= re.compile(config.config_columns_to_ignore)
r = re.compile(config.config_columns_to_ignore)
if r.match(col.label):
cc.append(col)
else:
cc=tmpcc
cc = tmpcc
book_in_shelfs = []
shelfs = ub.session.query(ub.BookShelf).filter(ub.BookShelf.book_id == book_id).all()
for entry in shelfs:
book_in_shelfs.append(entry.shelf)
#return render_title_template('detail.html', entry=entries, cc=cc,
# title=entries.title, books_shelfs=book_in_shelfs)
if not current_user.is_anonymous():
matching_have_read_book=ub.session.query(ub.ReadBook).filter(ub.and_(ub.ReadBook.user_id == int(current_user.id),
matching_have_read_book = ub.session.query(ub.ReadBook).filter(ub.and_(ub.ReadBook.user_id == int(current_user.id),
ub.ReadBook.book_id == book_id)).all()
have_read=len(matching_have_read_book) > 0 and matching_have_read_book[0].is_read
have_read = len(matching_have_read_book) > 0 and matching_have_read_book[0].is_read
else:
have_read=None
have_read = None
return render_title_template('detail.html', entry=entries, cc=cc,
title=entries.title, books_shelfs=book_in_shelfs, have_read=have_read)
@ -1255,33 +1279,58 @@ def stats():
return render_title_template('stats.html', bookcounter=counter, authorcounter=authors, versions=versions,
categorycounter=categorys, seriecounter=series, title=_(u"Statistics"))
@app.route("/delete/<int:book_id>/")
@login_required
def delete_book(book_id):
if current_user.role_delete_books():
book = db.session.query(db.Books).filter(db.Books.id == book_id).first()
if book:
# check if only this book links to:
# author, language, series, tags,
modify_database_object([u''], book.authors, db.Authors, db.session, 'author')
modify_database_object([u''], book.tags, db.Tags, db.session, 'tags')
modify_database_object([u''], book.series, db.Series, db.session, 'series')
modify_database_object([u''], book.languages, db.Languages, db.session, 'languages')
modify_database_object([u''], book.publishers, db.Publishers, db.session, 'series')
# custom colums open
ub.session.query(db.Books).filter(db.Books.id == book_id).delete()
#return redirect(url_for('index'))
else:
app.logger.info('Book with id "'+book_id+'" could not be deleted')
# book not found
return redirect(url_for('index'))
@app.route("/gdrive/authenticate")
@login_required
@admin_required
def authenticate_google_drive():
authUrl=Gauth.Instance().auth.GetAuthUrl()
authUrl = Gauth.Instance().auth.GetAuthUrl()
return redirect(authUrl)
@app.route("/gdrive/callback")
def google_drive_callback():
auth_code = request.args.get('code')
credentials = Gauth.Instance().auth.flow.step2_exchange(auth_code)
with open('gdrive_credentials' ,'w') as f:
with open('gdrive_credentials', 'w') as f:
f.write(credentials.to_json())
return redirect(url_for('configuration'))
@app.route("/gdrive/watch/subscribe")
@login_required
@admin_required
def watch_gdrive():
if not config.config_google_drive_watch_changes_response:
address = '%sgdrive/watch/callback' % config.config_google_drive_calibre_url_base
notification_id=str(uuid4())
notification_id = str(uuid4())
result = gdriveutils.watchChange(Gdrive.Instance().drive, notification_id,
'web_hook', address, gdrive_watch_callback_token, current_milli_time() + 604800*1000)
print (result)
settings = ub.session.query(ub.Settings).first()
settings.config_google_drive_watch_changes_response=json.dumps(result)
settings.config_google_drive_watch_changes_response = json.dumps(result)
ub.session.merge(settings)
ub.session.commit()
settings = ub.session.query(ub.Settings).first()
@ -1291,49 +1340,51 @@ def watch_gdrive():
return redirect(url_for('configuration'))
@app.route("/gdrive/watch/revoke")
@login_required
@admin_required
def revoke_watch_gdrive():
last_watch_response=config.config_google_drive_watch_changes_response
last_watch_response = config.config_google_drive_watch_changes_response
if last_watch_response:
try:
gdriveutils.stopChannel(Gdrive.Instance().drive, last_watch_response['id'], last_watch_response['resourceId'])
except HttpError:
pass
settings = ub.session.query(ub.Settings).first()
settings.config_google_drive_watch_changes_response=None
settings.config_google_drive_watch_changes_response = None
ub.session.merge(settings)
ub.session.commit()
config.loadSettings()
return redirect(url_for('configuration'))
@app.route("/gdrive/watch/callback", methods=['GET', 'POST'])
def on_received_watch_confirmation():
app.logger.info (request.headers)
app.logger.info(request.headers)
if request.headers.get('X-Goog-Channel-Token') == gdrive_watch_callback_token \
and request.headers.get('X-Goog-Resource-State') == 'change' \
and request.data:
and request.headers.get('X-Goog-Resource-State') == 'change' \
and request.data:
data=request.data
data = request.data
def updateMetaData():
app.logger.info ('Change received from gdrive')
app.logger.info (data)
app.logger.info('Change received from gdrive')
app.logger.info(data)
try:
j=json.loads(data)
app.logger.info ('Getting change details')
response=gdriveutils.getChangeById(Gdrive.Instance().drive, j['id'])
app.logger.info (response)
j = json.loads(data)
app.logger.info('Getting change details')
response = gdriveutils.getChangeById(Gdrive.Instance().drive, j['id'])
app.logger.info(response)
if response:
dbpath = os.path.join(config.config_calibre_dir, "metadata.db")
if not response['deleted'] and response['file']['title'] == 'metadata.db' and response['file']['md5Checksum'] != md5(dbpath):
tmpDir=tempfile.gettempdir()
app.logger.info ('Database file updated')
copyfile (dbpath, os.path.join(tmpDir, "metadata.db_" + str(current_milli_time())))
app.logger.info ('Backing up existing and downloading updated metadata.db')
tmpDir = tempfile.gettempdir()
app.logger.info('Database file updated')
copyfile(dbpath, os.path.join(tmpDir, "metadata.db_" + str(current_milli_time())))
app.logger.info('Backing up existing and downloading updated metadata.db')
gdriveutils.downloadFile(Gdrive.Instance().drive, None, "metadata.db", os.path.join(tmpDir, "tmp_metadata.db"))
app.logger.info ('Setting up new DB')
app.logger.info('Setting up new DB')
os.rename(os.path.join(tmpDir, "tmp_metadata.db"), dbpath)
db.setup_db()
except Exception as e:
@ -1373,6 +1424,7 @@ def shutdown():
return json.dumps({})
abort(404)
@app.route("/update")
@login_required
@admin_required
@ -1473,20 +1525,21 @@ def advanced_search():
def get_cover_via_gdrive(cover_path):
df=gdriveutils.getFileFromEbooksFolder(Gdrive.Instance().drive, cover_path, 'cover.jpg')
df = gdriveutils.getFileFromEbooksFolder(Gdrive.Instance().drive, cover_path, 'cover.jpg')
if not gdriveutils.session.query(gdriveutils.PermissionAdded).filter(gdriveutils.PermissionAdded.gdrive_id == df['id']).first():
df.GetPermissions()
df.InsertPermission({
'type': 'anyone',
'value': 'anyone',
'role': 'reader',
'withLink' : True})
permissionAdded=gdriveutils.PermissionAdded()
permissionAdded.gdrive_id=df['id']
'withLink': True})
permissionAdded = gdriveutils.PermissionAdded()
permissionAdded.gdrive_id = df['id']
gdriveutils.session.add(permissionAdded)
gdriveutils.session.commit()
return df.metadata.get('webContentLink')
@app.route("/cover/<path:cover_path>")
@login_required_if_no_ano
def get_cover(cover_path):
@ -1508,9 +1561,10 @@ def feed_get_cover(book_id):
else:
return send_from_directory(os.path.join(config.config_calibre_dir, book.path), "cover.jpg")
def render_read_books(page, are_read, as_xml=False):
readBooks=ub.session.query(ub.ReadBook).filter(ub.ReadBook.user_id == int(current_user.id)).filter(ub.ReadBook.is_read == True).all()
readBookIds=[x.book_id for x in readBooks]
readBooks = ub.session.query(ub.ReadBook).filter(ub.ReadBook.user_id == int(current_user.id)).filter(ub.ReadBook.is_read == True).all()
readBookIds = [x.book_id for x in readBooks]
if are_read:
db_filter = db.Books.id.in_(readBookIds)
else:
@ -1524,9 +1578,10 @@ def render_read_books(page, are_read, as_xml=False):
response.headers["Content-Type"] = "application/xml"
return response
else:
name=u'Read Books' if are_read else u'Unread Books'
name = u'Read Books' if are_read else u'Unread Books'
return render_title_template('index.html', random=random, entries=entries, pagination=pagination,
title=_(name, name=name))
title=_(name, name=name))
@app.route("/opds/readbooks/")
@login_required_if_no_ano
@ -1536,12 +1591,14 @@ def feed_read_books():
off = 0
return render_read_books(int(off) / (int(config.config_books_per_page)) + 1, True, True)
@app.route("/readbooks/", defaults={'page': 1})
@app.route("/readbooks/<int:page>'")
@login_required_if_no_ano
def read_books(page):
return render_read_books(page, True)
@app.route("/opds/unreadbooks/")
@login_required_if_no_ano
def feed_unread_books():
@ -1550,12 +1607,14 @@ def feed_unread_books():
off = 0
return render_read_books(int(off) / (int(config.config_books_per_page)) + 1, False, True)
@app.route("/unreadbooks/", defaults={'page': 1})
@app.route("/unreadbooks/<int:page>'")
@login_required_if_no_ano
def unread_books(page):
return render_read_books(page, False)
@app.route("/read/<int:book_id>/<book_format>")
@login_required_if_no_ano
def read_book(book_id, book_format):
@ -1579,7 +1638,7 @@ def read_book(book_id, book_format):
try:
os.makedirs(newDir)
except OSError as exception:
if not exception.errno == errno.EEXIST:
if not exception.errno == errno.EEXIST:
raise
if fileName:
fd = open(os.path.join(newDir, fileName), "wb")
@ -1613,6 +1672,7 @@ def read_book(book_id, book_format):
flash(_(u"Error opening eBook. File does not exist or file is not accessible:"), category="error")
return redirect(url_for("index"))
@app.route("/download/<int:book_id>/<book_format>")
@login_required_if_no_ano
@download_required
@ -1628,28 +1688,30 @@ def get_download_link(book_id, book_format):
if len(book.authors) > 0:
file_name = book.authors[0].name + '_' + file_name
file_name = helper.get_valid_filename(file_name)
headers = Headers ()
headers = Headers()
try:
headers["Content-Type"] = mimetypes.types_map['.' + book_format]
except KeyError:
headers["Content-Type"] = "application/octet-stream"
headers["Content-Disposition"] = "attachment; filename*=UTF-8''%s.%s" % (quote(file_name.encode('utf-8')), book_format)
if config.config_use_google_drive:
df=gdriveutils.getFileFromEbooksFolder(Gdrive.Instance().drive, book.path, '%s.%s' % (data.name, book_format))
df = gdriveutils.getFileFromEbooksFolder(Gdrive.Instance().drive, book.path, '%s.%s' % (data.name, book_format))
return do_gdrive_download(df, headers)
else:
response = make_response(send_from_directory(os.path.join(config.config_calibre_dir, book.path), data.name + "." + book_format))
response.headers=headers
response.headers = headers
return response
else:
abort(404)
@app.route("/download/<int:book_id>/<book_format>/<anyname>")
@login_required_if_no_ano
@download_required
def get_download_link_ext(book_id, book_format, anyname):
return get_download_link(book_id, book_format)
@app.route('/register', methods=['GET', 'POST'])
def register():
if not config.config_public_reg:
@ -1745,7 +1807,7 @@ def add_to_shelf(shelf_id, book_id):
app.logger.info("Sorry you are not allowed to add a book to the the shelf: %s" % shelf.name)
return redirect(url_for('index'))
maxOrder = ub.session.query(func.max(ub.BookShelf.order)).filter(ub.BookShelf.shelf == shelf_id).first()
book_in_shelf=ub.session.query(ub.BookShelf).filter(ub.BookShelf.shelf == shelf_id,
book_in_shelf = ub.session.query(ub.BookShelf).filter(ub.BookShelf.shelf == shelf_id,
ub.BookShelf.book_id == book_id).first()
if book_in_shelf:
app.logger.info("Book is already part of the shelf: %s" % shelf.name)
@ -1761,7 +1823,7 @@ def add_to_shelf(shelf_id, book_id):
flash(_(u"Book has been added to shelf: %(sname)s", sname=shelf.name), category="success")
return redirect(request.environ["HTTP_REFERER"])
else:
app.logger.info("User is not allowed to edit public shelfs" )
app.logger.info("User is not allowed to edit public shelfs")
return redirect(url_for('index'))
@ -2016,30 +2078,30 @@ def configuration_helper(origin):
if content.config_calibre_dir != to_save["config_calibre_dir"]:
content.config_calibre_dir = to_save["config_calibre_dir"]
db_change = True
##Google drive setup
create_new_yaml=False
# Google drive setup
create_new_yaml = False
if "config_google_drive_client_id" in to_save:
if content.config_google_drive_client_id != to_save["config_google_drive_client_id"]:
content.config_google_drive_client_id = to_save["config_google_drive_client_id"]
create_new_yaml=True
create_new_yaml = True
if "config_google_drive_client_secret" in to_save:
if content.config_google_drive_client_secret != to_save["config_google_drive_client_secret"]:
content.config_google_drive_client_secret = to_save["config_google_drive_client_secret"]
create_new_yaml=True
create_new_yaml = True
if "config_google_drive_calibre_url_base" in to_save:
if content.config_google_drive_calibre_url_base != to_save["config_google_drive_calibre_url_base"]:
content.config_google_drive_calibre_url_base = to_save["config_google_drive_calibre_url_base"]
create_new_yaml=True
create_new_yaml = True
if ("config_use_google_drive" in to_save and not content.config_use_google_drive) or ("config_use_google_drive" not in to_save and content.config_use_google_drive):
content.config_use_google_drive = "config_use_google_drive" in to_save
db_change = True
if not content.config_use_google_drive:
create_new_yaml=False
create_new_yaml = False
if create_new_yaml:
with open('settings.yaml', 'w') as f:
with open('gdrive_template.yaml' ,'r') as t:
f.write(t.read() % {'client_id' : content.config_google_drive_client_id, 'client_secret' : content.config_google_drive_client_secret,
"redirect_uri" : content.config_google_drive_calibre_url_base + 'gdrive/callback'})
with open('gdrive_template.yaml', 'r') as t:
f.write(t.read() % {'client_id': content.config_google_drive_client_id, 'client_secret': content.config_google_drive_client_secret,
"redirect_uri": content.config_google_drive_calibre_url_base + 'gdrive/callback'})
if "config_google_drive_folder" in to_save:
if content.config_google_drive_folder != to_save["config_google_drive_folder"]:
content.config_google_drive_folder = to_save["config_google_drive_folder"]
@ -2082,6 +2144,8 @@ def configuration_helper(origin):
content.config_default_role = content.config_default_role + ub.ROLE_UPLOAD
if "edit_role" in to_save:
content.config_default_role = content.config_default_role + ub.ROLE_EDIT
if "delete_role" in to_save:
content.config_default_role = content.config_default_role + ub.ROLE_DELETE_BOOKS
if "passwd_role" in to_save:
content.config_default_role = content.config_default_role + ub.ROLE_PASSWD
if "passwd_role" in to_save:
@ -2176,6 +2240,8 @@ def new_user():
if "upload_role" in to_save:
content.role = content.role + ub.ROLE_UPLOAD
if "edit_role" in to_save:
content.role = content.role + ub.ROLE_DELETE_BOOKS
if "delete_role" in to_save:
content.role = content.role + ub.ROLE_EDIT
if "passwd_role" in to_save:
content.role = content.role + ub.ROLE_PASSWD
@ -2190,7 +2256,7 @@ def new_user():
ub.session.rollback()
flash(_(u"Found an existing account for this email address or nickname."), category="error")
else:
content.role=config.config_default_role
content.role = config.config_default_role
return render_title_template("user_edit.html", new_user=1, content=content, translations=translations,
languages=languages, title=_(u"Add new user"))
@ -2279,6 +2345,11 @@ def edit_user(user_id):
elif "edit_role" not in to_save and content.role_edit():
content.role = content.role - ub.ROLE_EDIT
if "delete_role" in to_save and not content.role_delete_books():
content.role = content.role + ub.ROLE_DELETE_BOOKS
elif "delete_role" not in to_save and content.role_delete_books():
content.role = content.role - ub.ROLE_DELETE_BOOKS
if "passwd_role" in to_save and not content.role_passwd():
content.role = content.role + ub.ROLE_PASSWD
elif "passwd_role" not in to_save and content.role_passwd():
@ -2384,16 +2455,22 @@ def edit_book(book_id):
input_authors = to_save["author_name"].split('&')
input_authors = map(lambda it: it.strip(), input_authors)
# we have all author names now
author0_before_edit = book.authors[0].name
if input_authors == ['']:
input_authors = [_(u'unknown')] # prevent empty Author
if book.authors:
author0_before_edit = book.authors[0].name
else:
author0_before_edit = db.Authors(_(u'unknown'),'',0)
modify_database_object(input_authors, book.authors, db.Authors, db.session, 'author')
if author0_before_edit != book.authors[0].name:
edited_books_id.add(book.id)
book.author_sort=helper.get_sorted_author(input_authors[0])
if book.authors:
if author0_before_edit != book.authors[0].name:
edited_books_id.add(book.id)
book.author_sort = helper.get_sorted_author(input_authors[0])
if to_save["cover_url"] and os.path.splitext(to_save["cover_url"])[1].lower() == ".jpg":
img = requests.get(to_save["cover_url"])
if config.config_use_google_drive:
tmpDir=tempfile.gettempdir()
tmpDir = tempfile.gettempdir()
f = open(os.path.join(tmpDir, "uploaded_cover.jpg"), "wb")
f.write(img.content)
f.close()
@ -2402,7 +2479,7 @@ def edit_book(book_id):
f = open(os.path.join(config.config_calibre_dir, book.path, "cover.jpg"), "wb")
f.write(img.content)
f.close()
book.has_cover=1
book.has_cover = 1
if book.series_index != to_save["series_index"]:
book.series_index = to_save["series_index"]
@ -2510,7 +2587,8 @@ def edit_book(book_id):
else:
input_tags = to_save[cc_string].split(',')
input_tags = map(lambda it: it.strip(), input_tags)
input_tags = [x for x in input_tags if x != '']
modify_database_object(input_tags, getattr(book, cc_string),db.cc_classes[c.id], db.session, 'custom')
'''input_tags = [x for x in input_tags if x != '']
# we have all author names now
# 1. search for tags to remove
del_tags = []
@ -2552,7 +2630,7 @@ def edit_book(book_id):
new_tag = db.session.query(db.cc_classes[c.id]).filter(
db.cc_classes[c.id].value == add_tag).first()
# add tag to book
getattr(book, cc_string).append(new_tag)
getattr(book, cc_string).append(new_tag)'''
db.session.commit()
author_names = []
@ -2644,7 +2722,7 @@ def upload():
db_author = db.Authors(author, helper.get_sorted_author(author), "")
db.session.add(db_author)
#add language actually one value in list
# add language actually one value in list
input_language = meta.languages
db_language = None
if input_language != "":
@ -2656,7 +2734,7 @@ def upload():
db_language = db.Languages(input_language)
db.session.add(db_language)
# combine path and normalize path from windows systems
path = os.path.join(author_dir, title_dir).replace('\\','/')
path = os.path.join(author_dir, title_dir).replace('\\', '/')
db_book = db.Books(title, "", db_author.sort, datetime.datetime.now(), datetime.datetime(101, 1, 1), 1,
datetime.datetime.now(), path, has_cover, db_author, [], db_language)
db_book.authors.append(db_author)
@ -2666,15 +2744,13 @@ def upload():
db_book.data.append(db_data)
db.session.add(db_book)
db.session.flush()# flush content get db_book.id avalible
#add comment
db.session.flush() # flush content get db_book.id avalible
# add comment
upload_comment = Markup(meta.description).unescape()
db_comment = None
if upload_comment != "":
db_comment = db.Comments(upload_comment, db_book.id)
db.session.add(db_comment)
db.session.add(db.Comments(upload_comment, db_book.id))
db.session.commit()
if db_language is not None: #display Full name instead of iso639.part3
if db_language is not None: # display Full name instead of iso639.part3
db_book.languages[0].language_name = _(meta.languages)
author_names = []
for author in db_book.authors:
@ -2691,6 +2767,7 @@ def upload():
else:
return redirect(url_for("index"))
def start_gevent():
from gevent.wsgi import WSGIServer
global gevent_server

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2017-04-14 09:38+0200\n"
"POT-Creation-Date: 2017-04-14 20:25+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -17,7 +17,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.3.4\n"
#: cps/book_formats.py:113 cps/book_formats.py:117 cps/web.py:1235
#: cps/book_formats.py:113 cps/book_formats.py:117 cps/web.py:1258
msgid "not installed"
msgstr ""
@ -46,325 +46,329 @@ msgstr ""
msgid "Could not convert epub to mobi"
msgstr ""
#: cps/ub.py:471
#: cps/ub.py:481
msgid "Guest"
msgstr ""
#: cps/web.py:894
#: cps/web.py:917
msgid "Requesting update package"
msgstr ""
#: cps/web.py:895
#: cps/web.py:918
msgid "Downloading update package"
msgstr ""
#: cps/web.py:896
#: cps/web.py:919
msgid "Unzipping update package"
msgstr ""
#: cps/web.py:897
#: cps/web.py:920
msgid "Files are replaced"
msgstr ""
#: cps/web.py:898
#: cps/web.py:921
msgid "Database connections are closed"
msgstr ""
#: cps/web.py:899
#: cps/web.py:922
msgid "Server is stopped"
msgstr ""
#: cps/web.py:900
#: cps/web.py:923
msgid "Update finished, please press okay and reload page"
msgstr ""
#: cps/web.py:974
#: cps/web.py:997
msgid "Latest Books"
msgstr ""
#: cps/web.py:1005
#: cps/web.py:1028
msgid "Hot Books (most downloaded)"
msgstr ""
#: cps/web.py:1015
#: cps/web.py:1038
msgid "Best rated books"
msgstr ""
#: cps/templates/index.xml:36 cps/web.py:1024
#: cps/templates/index.xml:36 cps/web.py:1047
msgid "Random Books"
msgstr ""
#: cps/web.py:1037
#: cps/web.py:1060
msgid "Author list"
msgstr ""
#: cps/web.py:1048
#: cps/web.py:1072
#, python-format
msgid "Author: %(name)s"
msgstr ""
#: cps/web.py:1050 cps/web.py:1078 cps/web.py:1212 cps/web.py:1614
#: cps/web.py:2578
#: cps/web.py:1074 cps/web.py:1102 cps/web.py:1235 cps/web.py:1672
#: cps/web.py:2655
msgid "Error opening eBook. File does not exist or file is not accessible:"
msgstr ""
#: cps/templates/index.xml:71 cps/web.py:1064
#: cps/templates/index.xml:71 cps/web.py:1088
msgid "Series list"
msgstr ""
#: cps/web.py:1076
#: cps/web.py:1100
#, python-format
msgid "Series: %(serie)s"
msgstr ""
#: cps/web.py:1109
#: cps/web.py:1133
msgid "Available languages"
msgstr ""
#: cps/web.py:1124
#: cps/web.py:1148
#, python-format
msgid "Language: %(name)s"
msgstr ""
#: cps/templates/index.xml:64 cps/web.py:1137
#: cps/templates/index.xml:64 cps/web.py:1161
msgid "Category list"
msgstr ""
#: cps/web.py:1149
#: cps/web.py:1173
#, python-format
msgid "Category: %(name)s"
msgstr ""
#: cps/web.py:1257
#: cps/web.py:1280
msgid "Statistics"
msgstr ""
#: cps/web.py:1365
#: cps/web.py:1415
msgid "Server restarted, please reload page"
msgstr ""
#: cps/web.py:1367
#: cps/web.py:1417
msgid "Performing shutdown of server, please close window"
msgstr ""
#: cps/web.py:1382
#: cps/web.py:1433
msgid "Update done"
msgstr ""
#: cps/web.py:1460 cps/web.py:1473
#: cps/web.py:1511 cps/web.py:1524
msgid "search"
msgstr ""
#: cps/web.py:1590 cps/web.py:1597 cps/web.py:1604 cps/web.py:1611
#: cps/web.py:1648 cps/web.py:1655 cps/web.py:1662 cps/web.py:1669
msgid "Read a Book"
msgstr ""
#: cps/web.py:1664 cps/web.py:2144
#: cps/web.py:1725 cps/web.py:2207
msgid "Please fill out all fields!"
msgstr ""
#: cps/web.py:1665 cps/web.py:1681 cps/web.py:1686 cps/web.py:1688
#: cps/web.py:1726 cps/web.py:1742 cps/web.py:1747 cps/web.py:1749
msgid "register"
msgstr ""
#: cps/web.py:1680
#: cps/web.py:1741
msgid "An unknown error occured. Please try again later."
msgstr ""
#: cps/web.py:1685
#: cps/web.py:1746
msgid "This username or email address is already in use."
msgstr ""
#: cps/web.py:1703
#: cps/web.py:1764
#, python-format
msgid "you are now logged in as: '%(nickname)s'"
msgstr ""
#: cps/web.py:1708
#: cps/web.py:1769
msgid "Wrong Username or Password"
msgstr ""
#: cps/web.py:1710
#: cps/web.py:1771
msgid "login"
msgstr ""
#: cps/web.py:1727
#: cps/web.py:1788
msgid "Please configure the SMTP mail settings first..."
msgstr ""
#: cps/web.py:1731
#: cps/web.py:1792
#, python-format
msgid "Book successfully send to %(kindlemail)s"
msgstr ""
#: cps/web.py:1735
#: cps/web.py:1796
#, python-format
msgid "There was an error sending this book: %(res)s"
msgstr ""
#: cps/web.py:1737 cps/web.py:2226
#: cps/web.py:1798 cps/web.py:2291
msgid "Please configure your kindle email address first..."
msgstr ""
#: cps/web.py:1762
#: cps/web.py:1823
#, python-format
msgid "Book has been added to shelf: %(sname)s"
msgstr ""
#: cps/web.py:1782
#: cps/web.py:1843
#, python-format
msgid "Book has been removed from shelf: %(sname)s"
msgstr ""
#: cps/web.py:1800 cps/web.py:1824
#: cps/web.py:1861 cps/web.py:1885
#, python-format
msgid "A shelf with the name '%(title)s' already exists."
msgstr ""
#: cps/web.py:1805
#: cps/web.py:1866
#, python-format
msgid "Shelf %(title)s created"
msgstr ""
#: cps/web.py:1807 cps/web.py:1835
#: cps/web.py:1868 cps/web.py:1896
msgid "There was an error"
msgstr ""
#: cps/web.py:1808 cps/web.py:1810
#: cps/web.py:1869 cps/web.py:1871
msgid "create a shelf"
msgstr ""
#: cps/web.py:1833
#: cps/web.py:1894
#, python-format
msgid "Shelf %(title)s changed"
msgstr ""
#: cps/web.py:1836 cps/web.py:1838
#: cps/web.py:1897 cps/web.py:1899
msgid "Edit a shelf"
msgstr ""
#: cps/web.py:1858
#: cps/web.py:1919
#, python-format
msgid "successfully deleted shelf %(name)s"
msgstr ""
#: cps/web.py:1880
#: cps/web.py:1941
#, python-format
msgid "Shelf: '%(name)s'"
msgstr ""
#: cps/web.py:1911
#: cps/web.py:1972
#, python-format
msgid "Change order of Shelf: '%(name)s'"
msgstr ""
#: cps/web.py:1975
#: cps/web.py:2036
msgid "Found an existing account for this email address."
msgstr ""
#: cps/web.py:1977 cps/web.py:1981
#: cps/web.py:2038 cps/web.py:2042
#, python-format
msgid "%(name)s's profile"
msgstr ""
#: cps/web.py:1978
#: cps/web.py:2039
msgid "Profile updated"
msgstr ""
#: cps/web.py:1992
#: cps/web.py:2053
msgid "Admin page"
msgstr ""
#: cps/web.py:2098
#: cps/web.py:2161
msgid "Calibre-web configuration updated"
msgstr ""
#: cps/web.py:2105 cps/web.py:2111 cps/web.py:2125
#: cps/web.py:2168 cps/web.py:2174 cps/web.py:2188
msgid "Basic Configuration"
msgstr ""
#: cps/web.py:2109
#: cps/web.py:2172
msgid "DB location is not valid, please enter correct path"
msgstr ""
#: cps/templates/admin.html:34 cps/web.py:2146 cps/web.py:2196
#: cps/templates/admin.html:34 cps/web.py:2209 cps/web.py:2261
msgid "Add new user"
msgstr ""
#: cps/web.py:2188
#: cps/web.py:2253
#, python-format
msgid "User '%(user)s' created"
msgstr ""
#: cps/web.py:2192
#: cps/web.py:2257
msgid "Found an existing account for this email address or nickname."
msgstr ""
#: cps/web.py:2214
#: cps/web.py:2279
msgid "Mail settings updated"
msgstr ""
#: cps/web.py:2221
#: cps/web.py:2286
#, python-format
msgid "Test E-Mail successfully send to %(kindlemail)s"
msgstr ""
#: cps/web.py:2224
#: cps/web.py:2289
#, python-format
msgid "There was an error sending the Test E-Mail: %(res)s"
msgstr ""
#: cps/web.py:2228
#: cps/web.py:2293
msgid "E-Mail settings updated"
msgstr ""
#: cps/web.py:2229
#: cps/web.py:2294
msgid "Edit mail settings"
msgstr ""
#: cps/web.py:2257
#: cps/web.py:2322
#, python-format
msgid "User '%(nick)s' deleted"
msgstr ""
#: cps/web.py:2348
#: cps/web.py:2418
#, python-format
msgid "User '%(nick)s' updated"
msgstr ""
#: cps/web.py:2351
#: cps/web.py:2421
msgid "An unknown error occured."
msgstr ""
#: cps/web.py:2354
#: cps/web.py:2424
#, python-format
msgid "Edit User %(nick)s"
msgstr ""
#: cps/web.py:2573 cps/web.py:2576 cps/web.py:2688
#: cps/web.py:2459 cps/web.py:2463
msgid "unknown"
msgstr ""
#: cps/web.py:2650 cps/web.py:2653 cps/web.py:2763
msgid "edit metadata"
msgstr ""
#: cps/web.py:2597
#: cps/web.py:2674
#, python-format
msgid "File extension \"%s\" is not allowed to be uploaded to this server"
msgstr ""
#: cps/web.py:2603
#: cps/web.py:2680
msgid "File to be uploaded must have an extension"
msgstr ""
#: cps/web.py:2620
#: cps/web.py:2697
#, python-format
msgid "Failed to create path %s (Permission denied)."
msgstr ""
#: cps/web.py:2625
#: cps/web.py:2702
#, python-format
msgid "Failed to store file %s (Permission denied)."
msgstr ""
#: cps/web.py:2630
#: cps/web.py:2707
#, python-format
msgid "Failed to delete file %s (Permission denied)."
msgstr ""
@ -515,10 +519,10 @@ msgid "Ok"
msgstr ""
#: cps/templates/admin.html:103 cps/templates/admin.html:117
#: cps/templates/book_edit.html:109 cps/templates/config_edit.html:123
#: cps/templates/email_edit.html:36 cps/templates/shelf.html:53
#: cps/templates/shelf_edit.html:19 cps/templates/shelf_order.html:12
#: cps/templates/user_edit.html:124
#: cps/templates/book_edit.html:115 cps/templates/book_edit.html:134
#: cps/templates/config_edit.html:127 cps/templates/email_edit.html:36
#: cps/templates/shelf.html:53 cps/templates/shelf_edit.html:19
#: cps/templates/shelf_order.html:12 cps/templates/user_edit.html:128
msgid "Back"
msgstr ""
@ -530,104 +534,124 @@ msgstr ""
msgid "Updating, please do not reload page"
msgstr ""
#: cps/templates/book_edit.html:16 cps/templates/search_form.html:6
#: cps/templates/book_edit.html:16
msgid "Delete Book"
msgstr ""
#: cps/templates/book_edit.html:22 cps/templates/search_form.html:6
msgid "Book Title"
msgstr ""
#: cps/templates/book_edit.html:20 cps/templates/book_edit.html:145
#: cps/templates/book_edit.html:26 cps/templates/book_edit.html:173
#: cps/templates/search_form.html:10
msgid "Author"
msgstr ""
#: cps/templates/book_edit.html:24 cps/templates/book_edit.html:147
#: cps/templates/book_edit.html:30 cps/templates/book_edit.html:175
msgid "Description"
msgstr ""
#: cps/templates/book_edit.html:28 cps/templates/search_form.html:17
#: cps/templates/book_edit.html:34 cps/templates/search_form.html:17
msgid "Tags"
msgstr ""
#: cps/templates/book_edit.html:33 cps/templates/layout.html:142
#: cps/templates/book_edit.html:39 cps/templates/layout.html:142
#: cps/templates/search_form.html:37
msgid "Series"
msgstr ""
#: cps/templates/book_edit.html:37
#: cps/templates/book_edit.html:43
msgid "Series id"
msgstr ""
#: cps/templates/book_edit.html:41
#: cps/templates/book_edit.html:47
msgid "Rating"
msgstr ""
#: cps/templates/book_edit.html:45
#: cps/templates/book_edit.html:51
msgid "Cover URL (jpg)"
msgstr ""
#: cps/templates/book_edit.html:50 cps/templates/user_edit.html:27
#: cps/templates/book_edit.html:56 cps/templates/user_edit.html:27
msgid "Language"
msgstr ""
#: cps/templates/book_edit.html:61
#: cps/templates/book_edit.html:67
msgid "Yes"
msgstr ""
#: cps/templates/book_edit.html:62
#: cps/templates/book_edit.html:68
msgid "No"
msgstr ""
#: cps/templates/book_edit.html:104
#: cps/templates/book_edit.html:110
msgid "view book after edit"
msgstr ""
#: cps/templates/book_edit.html:107 cps/templates/book_edit.html:118
#: cps/templates/book_edit.html:113 cps/templates/book_edit.html:146
msgid "Get metadata"
msgstr ""
#: cps/templates/book_edit.html:108 cps/templates/config_edit.html:121
#: cps/templates/book_edit.html:114 cps/templates/config_edit.html:125
#: cps/templates/login.html:19 cps/templates/search_form.html:79
#: cps/templates/shelf_edit.html:17 cps/templates/user_edit.html:122
#: cps/templates/shelf_edit.html:17 cps/templates/user_edit.html:126
msgid "Submit"
msgstr ""
#: cps/templates/book_edit.html:121
#: cps/templates/book_edit.html:125
msgid "Are really you sure?"
msgstr ""
#: cps/templates/book_edit.html:128
msgid "Book will be deleted from Calibre database"
msgstr ""
#: cps/templates/book_edit.html:129
msgid "and from hard disk"
msgstr ""
#: cps/templates/book_edit.html:133
msgid "Delete"
msgstr ""
#: cps/templates/book_edit.html:149
msgid "Keyword"
msgstr ""
#: cps/templates/book_edit.html:122
#: cps/templates/book_edit.html:150
msgid " Search keyword "
msgstr ""
#: cps/templates/book_edit.html:124 cps/templates/layout.html:60
#: cps/templates/book_edit.html:152 cps/templates/layout.html:60
msgid "Go!"
msgstr ""
#: cps/templates/book_edit.html:125
#: cps/templates/book_edit.html:153
msgid "Click the cover to load metadata to the form"
msgstr ""
#: cps/templates/book_edit.html:129 cps/templates/book_edit.html:142
#: cps/templates/book_edit.html:157 cps/templates/book_edit.html:170
msgid "Loading..."
msgstr ""
#: cps/templates/book_edit.html:132
#: cps/templates/book_edit.html:160
msgid "Close"
msgstr ""
#: cps/templates/book_edit.html:143
#: cps/templates/book_edit.html:171
msgid "Search error!"
msgstr ""
#: cps/templates/book_edit.html:144
#: cps/templates/book_edit.html:172
msgid "No Result! Please try anonther keyword."
msgstr ""
#: cps/templates/book_edit.html:146 cps/templates/detail.html:76
#: cps/templates/book_edit.html:174 cps/templates/detail.html:76
#: cps/templates/search_form.html:14
msgid "Publisher"
msgstr ""
#: cps/templates/book_edit.html:148
#: cps/templates/book_edit.html:176
msgid "Source"
msgstr ""
@ -711,15 +735,19 @@ msgstr ""
msgid "Allow Edit"
msgstr ""
#: cps/templates/config_edit.html:115 cps/templates/user_edit.html:105
msgid "Allow Changing Password"
#: cps/templates/config_edit.html:115 cps/templates/user_edit.html:104
msgid "Allow Delete books"
msgstr ""
#: cps/templates/config_edit.html:119 cps/templates/user_edit.html:109
msgid "Allow Changing Password"
msgstr ""
#: cps/templates/config_edit.html:123 cps/templates/user_edit.html:113
msgid "Allow Editing Public Shelfs"
msgstr ""
#: cps/templates/config_edit.html:126 cps/templates/layout.html:93
#: cps/templates/config_edit.html:130 cps/templates/layout.html:93
#: cps/templates/login.html:4
msgid "Login"
msgstr ""
@ -1092,11 +1120,11 @@ msgstr ""
msgid "Show random books in detail view"
msgstr ""
#: cps/templates/user_edit.html:116
#: cps/templates/user_edit.html:120
msgid "Delete this user"
msgstr ""
#: cps/templates/user_edit.html:131
#: cps/templates/user_edit.html:135
msgid "Recent Downloads"
msgstr ""

Loading…
Cancel
Save