mirror of
https://github.com/janeczku/calibre-web
synced 2024-11-28 20:39:59 +00:00
Merge branch 'master' into Develop
# Conflicts: # cps/comic.py # cps/editbooks.py # cps/isoLanguages.py
This commit is contained in:
commit
7c8f6ce62f
1
.github/ISSUE_TEMPLATE/bug_report.md
vendored
1
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@ -6,6 +6,7 @@ labels: ''
|
|||||||
assignees: ''
|
assignees: ''
|
||||||
|
|
||||||
---
|
---
|
||||||
|
<!-- Please have a look at our [Contributing Guidelines](https://github.com/janeczku/calibre-web/blob/master/CONTRIBUTING.md) -->
|
||||||
|
|
||||||
**Describe the bug/problem**
|
**Describe the bug/problem**
|
||||||
A clear and concise description of what the bug is. If you are asking for support, please check our [Wiki](https://github.com/janeczku/calibre-web/wiki) if your question is already answered there.
|
A clear and concise description of what the bug is. If you are asking for support, please check our [Wiki](https://github.com/janeczku/calibre-web/wiki) if your question is already answered there.
|
||||||
|
2
.github/ISSUE_TEMPLATE/feature_request.md
vendored
2
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@ -7,6 +7,8 @@ assignees: ''
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
<!-- Please have a look at our [Contributing Guidelines](https://github.com/janeczku/calibre-web/blob/master/CONTRIBUTING.md) -->
|
||||||
|
|
||||||
**Is your feature request related to a problem? Please describe.**
|
**Is your feature request related to a problem? Please describe.**
|
||||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||||
|
|
||||||
|
@ -61,14 +61,14 @@ Optionally, to enable on-the-fly conversion from one ebook format to another whe
|
|||||||
Pre-built Docker images are available in these Docker Hub repositories:
|
Pre-built Docker images are available in these Docker Hub repositories:
|
||||||
|
|
||||||
#### **Technosoft2000 - x64**
|
#### **Technosoft2000 - x64**
|
||||||
+ Docker Hub - [https://hub.docker.com/r/technosoft2000/calibre-web/](https://hub.docker.com/r/technosoft2000/calibre-web/)
|
+ Docker Hub - [https://hub.docker.com/r/technosoft2000/calibre-web](https://hub.docker.com/r/technosoft2000/calibre-web)
|
||||||
+ Github - [https://github.com/Technosoft2000/docker-calibre-web](https://github.com/Technosoft2000/docker-calibre-web)
|
+ Github - [https://github.com/Technosoft2000/docker-calibre-web](https://github.com/Technosoft2000/docker-calibre-web)
|
||||||
|
|
||||||
Includes the Calibre `ebook-convert` binary.
|
Includes the Calibre `ebook-convert` binary.
|
||||||
+ The "path to convertertool" should be set to `/opt/calibre/ebook-convert`
|
+ The "path to convertertool" should be set to `/opt/calibre/ebook-convert`
|
||||||
|
|
||||||
#### **LinuxServer - x64, armhf, aarch64**
|
#### **LinuxServer - x64, armhf, aarch64**
|
||||||
+ Docker Hub - [https://hub.docker.com/r/linuxserver/calibre-web/](https://hub.docker.com/r/linuxserver/calibre-web/)
|
+ Docker Hub - [https://hub.docker.com/r/linuxserver/calibre-web](https://hub.docker.com/r/linuxserver/calibre-web)
|
||||||
+ Github - [https://github.com/linuxserver/docker-calibre-web](https://github.com/linuxserver/docker-calibre-web)
|
+ Github - [https://github.com/linuxserver/docker-calibre-web](https://github.com/linuxserver/docker-calibre-web)
|
||||||
+ Github - (Optional Calibre layer) - [https://github.com/linuxserver/docker-calibre-web/tree/calibre](https://github.com/linuxserver/docker-calibre-web/tree/calibre)
|
+ Github - (Optional Calibre layer) - [https://github.com/linuxserver/docker-calibre-web/tree/calibre](https://github.com/linuxserver/docker-calibre-web/tree/calibre)
|
||||||
|
|
||||||
@ -83,3 +83,7 @@ Pre-built Docker images are available in these Docker Hub repositories:
|
|||||||
# Wiki
|
# Wiki
|
||||||
|
|
||||||
For further information, How To's and FAQ please check the [Wiki](https://github.com/janeczku/calibre-web/wiki)
|
For further information, How To's and FAQ please check the [Wiki](https://github.com/janeczku/calibre-web/wiki)
|
||||||
|
|
||||||
|
# Contributing to Calibre-Web
|
||||||
|
|
||||||
|
Please have a look at our [Contributing Guidelines](https://github.com/janeczku/calibre-web/blob/master/CONTRIBUTING.md)
|
||||||
|
@ -134,7 +134,7 @@ def get_comic_info(tmp_file_path, original_file_name, original_file_extension, r
|
|||||||
# if style is not None:
|
# if style is not None:
|
||||||
loadedMetadata = archive.readMetadata(style)
|
loadedMetadata = archive.readMetadata(style)
|
||||||
|
|
||||||
lang = loadedMetadata.language
|
lang = loadedMetadata.language or ""
|
||||||
loadedMetadata.language = isoLanguages.get_lang3(lang)
|
loadedMetadata.language = isoLanguages.get_lang3(lang)
|
||||||
|
|
||||||
return BookMeta(
|
return BookMeta(
|
||||||
|
14
cps/db.py
14
cps/db.py
@ -120,6 +120,12 @@ class Identifiers(Base):
|
|||||||
return u"Google Books"
|
return u"Google Books"
|
||||||
elif format_type == "kobo":
|
elif format_type == "kobo":
|
||||||
return u"Kobo"
|
return u"Kobo"
|
||||||
|
elif format_type == "litres":
|
||||||
|
return u"ЛитРес"
|
||||||
|
elif format_type == "issn":
|
||||||
|
return u"ISSN"
|
||||||
|
elif format_type == "isfdb":
|
||||||
|
return u"ISFDB"
|
||||||
if format_type == "lubimyczytac":
|
if format_type == "lubimyczytac":
|
||||||
return u"Lubimyczytac"
|
return u"Lubimyczytac"
|
||||||
else:
|
else:
|
||||||
@ -144,7 +150,13 @@ class Identifiers(Base):
|
|||||||
elif format_type == "kobo":
|
elif format_type == "kobo":
|
||||||
return u"https://www.kobo.com/ebook/{0}".format(self.val)
|
return u"https://www.kobo.com/ebook/{0}".format(self.val)
|
||||||
elif format_type == "lubimyczytac":
|
elif format_type == "lubimyczytac":
|
||||||
return u" https://lubimyczytac.pl/ksiazka/{0}".format(self.val)
|
return u" https://lubimyczytac.pl/ksiazka/{0}/ksiazka".format(self.val)
|
||||||
|
elif format_type == "litres":
|
||||||
|
return u"https://www.litres.ru/{0}".format(self.val)
|
||||||
|
elif format_type == "issn":
|
||||||
|
return u"https://portal.issn.org/resource/ISSN/{0}".format(self.val)
|
||||||
|
elif format_type == "isfdb":
|
||||||
|
return u"http://www.isfdb.org/cgi-bin/pl.cgi?{0}".format(self.val)
|
||||||
elif format_type == "url":
|
elif format_type == "url":
|
||||||
return u"{0}".format(self.val)
|
return u"{0}".format(self.val)
|
||||||
else:
|
else:
|
||||||
|
@ -505,6 +505,8 @@ def upload_single_file(request, book, book_id):
|
|||||||
requested_file = request.files['btn-upload-format']
|
requested_file = request.files['btn-upload-format']
|
||||||
# check for empty request
|
# check for empty request
|
||||||
if requested_file.filename != '':
|
if requested_file.filename != '':
|
||||||
|
if not current_user.role_upload():
|
||||||
|
abort(403)
|
||||||
if '.' in requested_file.filename:
|
if '.' in requested_file.filename:
|
||||||
file_ext = requested_file.filename.rsplit('.', 1)[-1].lower()
|
file_ext = requested_file.filename.rsplit('.', 1)[-1].lower()
|
||||||
if file_ext not in constants.EXTENSIONS_UPLOAD and '' not in constants.EXTENSIONS_UPLOAD:
|
if file_ext not in constants.EXTENSIONS_UPLOAD and '' not in constants.EXTENSIONS_UPLOAD:
|
||||||
@ -555,9 +557,9 @@ def upload_single_file(request, book, book_id):
|
|||||||
WorkerThread.add(current_user.nickname, TaskUpload(
|
WorkerThread.add(current_user.nickname, TaskUpload(
|
||||||
"<a href=\"" + url_for('web.show_book', book_id=book.id) + "\">" + uploadText + "</a>"))
|
"<a href=\"" + url_for('web.show_book', book_id=book.id) + "\">" + uploadText + "</a>"))
|
||||||
|
|
||||||
return uploader.process(
|
return uploader.process(
|
||||||
saved_filename, *os.path.splitext(requested_file.filename),
|
saved_filename, *os.path.splitext(requested_file.filename),
|
||||||
rarExecutable=config.config_rarfile_location)
|
rarExecutable=config.config_rarfile_location)
|
||||||
|
|
||||||
|
|
||||||
def upload_cover(request, book):
|
def upload_cover(request, book):
|
||||||
@ -565,6 +567,8 @@ def upload_cover(request, book):
|
|||||||
requested_file = request.files['btn-upload-cover']
|
requested_file = request.files['btn-upload-cover']
|
||||||
# check for empty request
|
# check for empty request
|
||||||
if requested_file.filename != '':
|
if requested_file.filename != '':
|
||||||
|
if not current_user.role_upload():
|
||||||
|
abort(403)
|
||||||
ret, message = helper.save_cover(requested_file, book.path)
|
ret, message = helper.save_cover(requested_file, book.path)
|
||||||
if ret is True:
|
if ret is True:
|
||||||
return True
|
return True
|
||||||
@ -645,13 +649,16 @@ def edit_book(book_id):
|
|||||||
error = helper.update_dir_stucture(edited_books_id, config.config_calibre_dir, input_authors[0])
|
error = helper.update_dir_stucture(edited_books_id, config.config_calibre_dir, input_authors[0])
|
||||||
|
|
||||||
if not error:
|
if not error:
|
||||||
if to_save["cover_url"]:
|
if "cover_url" in to_save:
|
||||||
result, error = helper.save_cover_from_url(to_save["cover_url"], book.path)
|
if to_save["cover_url"]:
|
||||||
if result is True:
|
if not current_user.role_upload():
|
||||||
book.has_cover = 1
|
return "", (403)
|
||||||
modif_date = True
|
result, error = helper.save_cover_from_url(to_save["cover_url"], book.path)
|
||||||
else:
|
if result is True:
|
||||||
flash(error, category="error")
|
book.has_cover = 1
|
||||||
|
modif_date = True
|
||||||
|
else:
|
||||||
|
flash(error, category="error")
|
||||||
|
|
||||||
# Add default series_index to book
|
# Add default series_index to book
|
||||||
modif_date |= edit_book_series_index(to_save["series_index"], book)
|
modif_date |= edit_book_series_index(to_save["series_index"], book)
|
||||||
|
@ -69,6 +69,8 @@ def get_language_codes(locale, language_names, remainder=None):
|
|||||||
|
|
||||||
def get_valid_language_codes(locale, language_names, remainder=None):
|
def get_valid_language_codes(locale, language_names, remainder=None):
|
||||||
languages = list()
|
languages = list()
|
||||||
|
if "" in language_names:
|
||||||
|
language_names.remove("")
|
||||||
for k, v in get_language_names(locale).items():
|
for k, v in get_language_names(locale).items():
|
||||||
if k in language_names:
|
if k in language_names:
|
||||||
languages.append(k)
|
languages.append(k)
|
||||||
|
@ -90,15 +90,19 @@
|
|||||||
<label for="rating">{{_('Rating')}}</label>
|
<label for="rating">{{_('Rating')}}</label>
|
||||||
<input type="number" name="rating" id="rating" class="rating input-lg" data-clearable="" value="{% if book.ratings %}{{(book.ratings[0].rating / 2)|int}}{% endif %}">
|
<input type="number" name="rating" id="rating" class="rating input-lg" data-clearable="" value="{% if book.ratings %}{{(book.ratings[0].rating / 2)|int}}{% endif %}">
|
||||||
</div>
|
</div>
|
||||||
|
{% if g.user.role_upload() or g.user.role_admin()%}
|
||||||
|
{% if g.allow_upload %}
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="cover_url">{{_('Fetch Cover from URL (JPEG - Image will be downloaded and stored in database)')}}</label>
|
<label for="cover_url">{{_('Fetch Cover from URL (JPEG - Image will be downloaded and stored in database)')}}</label>
|
||||||
<input type="text" class="form-control" name="cover_url" id="cover_url" value="">
|
<input type="text" class="form-control" name="cover_url" id="cover_url" value="">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group" aria-label="Upload cover from local drive">
|
<div class="form-group" aria-label="Upload cover from local drive">
|
||||||
<label class="btn btn-primary btn-file" for="btn-upload-cover">{{ _('Upload Cover from Local Disk') }}</label>
|
<label class="btn btn-primary btn-file" for="btn-upload-cover">{{ _('Upload Cover from Local Disk') }}</label>
|
||||||
<div class="upload-cover-input-text" id="upload-cover"></div>
|
<div class="upload-cover-input-text" id="upload-cover"></div>
|
||||||
<input id="btn-upload-cover" name="btn-upload-cover" type="file" accept=".jpg, .jpeg, .png, .webp">
|
<input id="btn-upload-cover" name="btn-upload-cover" type="file" accept=".jpg, .jpeg, .png, .webp">
|
||||||
</div>
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="pubdate">{{_('Published Date')}}</label>
|
<label for="pubdate">{{_('Published Date')}}</label>
|
||||||
<div style="position: relative">
|
<div style="position: relative">
|
||||||
|
@ -81,7 +81,7 @@
|
|||||||
|
|
||||||
{% for format in entry.data %}
|
{% for format in entry.data %}
|
||||||
{% if format.format|lower in audioentries %}
|
{% if format.format|lower in audioentries %}
|
||||||
<li><a target="_blank" href="{{ url_for('web.read_book', book_id=entry.id, book_format=format.format|lower) }}">{{format.format}}</a></li>
|
<li><a target="_blank" href="{{ url_for('web.read_book', book_id=entry.id, book_format=format.format|lower) }}">{{format.format|lower }}</a></li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -136,7 +136,8 @@ def add_security_headers(resp):
|
|||||||
resp.headers['X-Content-Type-Options'] = 'nosniff'
|
resp.headers['X-Content-Type-Options'] = 'nosniff'
|
||||||
resp.headers['X-Frame-Options'] = 'SAMEORIGIN'
|
resp.headers['X-Frame-Options'] = 'SAMEORIGIN'
|
||||||
resp.headers['X-XSS-Protection'] = '1; mode=block'
|
resp.headers['X-XSS-Protection'] = '1; mode=block'
|
||||||
# resp.headers['Strict-Transport-Security'] = 'max-age=31536000; includeSubDomains'
|
resp.headers['Strict-Transport-Security'] = 'max-age=31536000; includeSubDomains'
|
||||||
|
# log.debug(request.full_path)
|
||||||
return resp
|
return resp
|
||||||
|
|
||||||
web = Blueprint('web', __name__)
|
web = Blueprint('web', __name__)
|
||||||
@ -1541,6 +1542,8 @@ def login():
|
|||||||
flash(_(u"Wrong Username or Password"), category="error")
|
flash(_(u"Wrong Username or Password"), category="error")
|
||||||
|
|
||||||
next_url = request.args.get('next', default=url_for("web.index"), type=str)
|
next_url = request.args.get('next', default=url_for("web.index"), type=str)
|
||||||
|
if url_for("web.logout") == next_url:
|
||||||
|
next_url = url_for("web.index")
|
||||||
return render_title_template('login.html',
|
return render_title_template('login.html',
|
||||||
title=_(u"login"),
|
title=_(u"login"),
|
||||||
next_url=next_url,
|
next_url=next_url,
|
||||||
|
Loading…
Reference in New Issue
Block a user