Merge branch 'janeczku:Develop' into Develop

This commit is contained in:
Purbayan Chowdhury
2024-05-23 01:45:36 +05:30
committed by GitHub
114 changed files with 13596 additions and 10949 deletions
+4 -4
View File
@@ -8,8 +8,8 @@
<img title="{{author.name}}" src="{{author.image_url}}" alt="{{author.name}}" class="author-photo pull-left">
{% endif %}
{%if author.about is not none %}
<p>{{author.about}}</p>
{%if author.safe_about is not none %}
<p>{{author.safe_about|safe}}</p>
{% endif %}
- {{_("via")}} <a href="{{author.link}}" class="author-link" target="_blank" rel="noopener">Goodreads</a>
@@ -32,7 +32,7 @@
</div>
<div class="row display-flex">
{% for entry in entries %}
<div id="books" class="col-sm-3 col-lg-2 col-xs-6 book">
<div id="books" class="col-sm-3 col-lg-2 col-xs-6 book session">
<div class="cover">
<a href="{{ url_for('web.show_book', book_id=entry.Books.id) }}" {% if simple==false %}data-toggle="modal" data-target="#bookDetailsModal" data-remote="false"{% endif %}>
<span class="img" title="{{entry.Books.title}}">
@@ -99,7 +99,7 @@
<h3>{{_("More by")}} {{ author.name.replace('|',',') }}</h3>
<div class="row">
{% for entry in other_books %}
<div class="col-sm-3 col-lg-2 col-xs-6 book">
<div class="col-sm-3 col-lg-2 col-xs-6 book session">
<div class="cover">
<a href="https://www.goodreads.com/book/show/{{ entry.gid['#text'] }}" target="_blank" rel="noopener">
<img title="{{entry.title}}" src="{{ entry.image_url }}" />
+1 -1
View File
@@ -18,7 +18,7 @@
</div>
<div class="form-group required">
<input type="checkbox" id="config_calibre_split" name="config_calibre_split" data-control="split_settings" data-t ="{{ config.config_calibre_split_dir }}" {% if config.config_calibre_split %}checked{% endif %} >
<label for="config_calibre_split">{{_('Separate Book files from Library')}}</label>
<label for="config_calibre_split">{{_('Separate Book Files from Library')}}</label>
</div>
<div data-related="split_settings">
<div class="form-group required input-group">
Regular → Executable
+24 -11
View File
@@ -9,7 +9,7 @@
<h2>{{title}}</h2>
<form role="form" method="POST" autocomplete="off">
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
<div class="panel-group col-md-10 col-lg-8">
<div class="panel-group col-md-11 col-lg-8">
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
@@ -103,6 +103,10 @@
<input type="checkbox" id="config_unicode_filename" name="config_unicode_filename" {% if config.config_unicode_filename %}checked{% endif %}>
<label for="config_unicode_filename">{{_('Convert non-English characters in title and author while saving to disk')}}</label>
</div>
<div class="form-group">
<input type="checkbox" id="config_embed_metadata" name="config_embed_metadata" {% if config.config_embed_metadata %}checked{% endif %}>
<label for="config_embed_metadata">{{_('Embed Metadata to Ebook File on Download/Conversion/e-mail (needs Calibre/Kepubify binaries)')}}</label>
</div>
<div class="form-group">
<input type="checkbox" id="config_uploading" data-control="upload_settings" name="config_uploading" {% if config.config_uploading %}checked{% endif %}>
<label for="config_uploading">{{_('Enable Uploads')}} {{_('(Please ensure that users also have upload permissions)')}}</label>
@@ -151,17 +155,12 @@
<div class="form-group">
<input type="checkbox" id="config_use_goodreads" name="config_use_goodreads" data-control="goodreads-settings" {% if config.config_use_goodreads %}checked{% endif %}>
<label for="config_use_goodreads">{{_('Use Goodreads')}}</label>
<a href="https://www.goodreads.com/api/keys" target="_blank" style="margin-left: 5px">{{_('Create an API Key')}}</a>
</div>
<div data-related="goodreads-settings">
<div class="form-group">
<label for="config_goodreads_api_key">{{_('Goodreads API Key')}}</label>
<input type="text" class="form-control" id="config_goodreads_api_key" name="config_goodreads_api_key" value="{% if config.config_goodreads_api_key != None %}{{ config.config_goodreads_api_key }}{% endif %}" autocomplete="off">
</div>
<div class="form-group">
<label for="config_goodreads_api_secret_e">{{_('Goodreads API Secret')}}</label>
<input type="password" class="form-control" id="config_goodreads_api_secret_e" name="config_goodreads_api_secret_e" value="" autocomplete="off">
</div>
</div>
{% endif %}
<div class="form-group">
@@ -323,12 +322,12 @@
</div>
<div id="collapsefive" class="panel-collapse collapse">
<div class="panel-body">
<label for="config_converterpath">{{_('Path to Calibre E-Book Converter')}}</label>
<label for="config_binariesdir">{{_('Path to Calibre Binaries')}}</label>
<div class="form-group input-group">
<input type="text" class="form-control" id="config_converterpath" name="config_converterpath" value="{% if config.config_converterpath != None %}{{ config.config_converterpath }}{% endif %}" autocomplete="off">
<span class="input-group-btn">
<button type="button" data-toggle="modal" id="converter_modal_path" data-link="config_converterpath" data-target="#fileModal" class="btn btn-default"><span class="glyphicon glyphicon-folder-open"></span></button>
</span>
<input type="text" class="form-control" id="config_binariesdir" name="config_binariesdir" value="{% if config.config_binariesdir != None %}{{ config.config_binariesdir }}{% endif %}" autocomplete="off">
<span class="input-group-btn">
<button type="button" data-toggle="modal" id="binaries_modal_path" data-link="config_binariesdir" data-folderonly="true" data-target="#fileModal" class="btn btn-default"><span class="glyphicon glyphicon-folder-open"></span></button>
</span>
</div>
<div class="form-group">
<label for="config_calibre">{{_('Calibre E-Book Converter Settings')}}</label>
@@ -368,6 +367,16 @@
<input type="checkbox" id="config_ratelimiter" name="config_ratelimiter" {% if config.config_ratelimiter %}checked{% endif %}>
<label for="config_ratelimiter">{{_('Limit failed login attempts')}}</label>
</div>
<div data-related="ratelimiter_settings">
<div class="form-group" style="margin-left:10px;">
<label for="config_calibre">{{_('Configure Backend for Limiter')}}</label>
<input type="text" class="form-control" id="config_limiter_uri" name="config_limiter_uri" value="{% if config.config_limiter_uri != None %}{{ config.config_limiter_uri }}{% endif %}" autocomplete="off">
</div>
<div class="form-group" style="margin-left:10px;">
<label for="config_calibre">{{_('Options for Limiter')}}</label>
<input type="text" class="form-control" id="config_limiter_options" name="config_limiter_options" value="{% if config.config_limiter_options != None %}{{ config.config_limiter_options }}{% endif %}" autocomplete="off">
</div>
</div>
<div class="form-group">
<label for="config_session">{{_('Session protection')}}</label>
<select name="config_session" id="config_session" class="form-control">
@@ -396,6 +405,10 @@
<input type="checkbox" id="config_password_upper" name="config_password_upper" {% if config.config_password_upper %}checked{% endif %}>
<label for="config_password_upper">{{_('Enforce uppercase characters')}}</label>
</div>
<div class="form-group" style="margin-left:10px;">
<input type="checkbox" id="config_password_character" name="config_password_character" {% if config.config_password_character %}checked{% endif %}>
<label for="config_password_lower">{{_('Enforce characters (needed For Chinese/Japanese/Korean Characters)')}}</label>
</div>
<div class="form-group" style="margin-left:10px;">
<input type="checkbox" id="config_password_special" name="config_password_special" {% if config.config_password_special %}checked{% endif %}>
<label for="config_password_special">{{_('Enforce special characters')}}</label>
Executable → Regular
+8 -8
View File
@@ -205,8 +205,8 @@
{% for c in cc %}
<div class="real_custom_columns">
{% if entry['custom_column_' ~ c.id]|length > 0 %}
{% if entry['custom_column_' ~ c.id]|length > 0 %}
<div class="real_custom_columns">
{{ c.name }}:
{% for column in entry['custom_column_' ~ c.id] %}
{% if c.datatype == 'rating' %}
@@ -235,8 +235,9 @@
{% endif %}
{% endif %}
{% endfor %}
{% endif %}
</div>
</div>
{% endif %}
{% endfor %}
{% endif %}
{% if not current_user.is_anonymous %}
@@ -332,15 +333,15 @@
{% endif %}
{% if current_user.role_edit() %}
<div class="btn-toolbar" role="toolbar">
<div class="col-sm-12">
<div class="btn-group" role="group" aria-label="Edit/Delete book">
<a href="{{ url_for('edit-book.show_edit_book', book_id=entry.id) }}"
class="btn btn-sm btn-primary" id="edit_book" role="button"><span
class="glyphicon glyphicon-edit"></span> {{ _('Edit Metadata') }}</a>
</div>
</div>
<div class="btn btn-default" data-back="{{ url_for('web.index') }}" id="back">{{_('Cancel')}}</div>
</div>
{% endif %}
</div>
</div>
</div>
</div>
@@ -366,4 +367,3 @@
</script>
{% endblock %}
+2 -2
View File
@@ -6,7 +6,7 @@
<h2 class="random-books">{{_('Discover (Random Books)')}}</h2>
<div class="row display-flex">
{% for entry in random %}
<div class="col-sm-3 col-lg-2 col-xs-6 book" id="books_rand">
<div class="col-sm-3 col-lg-2 col-xs-6 book session" id="books_rand">
<div class="cover">
<a href="{{ url_for('web.show_book', book_id=entry.Books.id) }}" {% if simple==false %}data-toggle="modal" data-target="#bookDetailsModal" data-remote="false"{% endif %}>
<span class="img" title="{{ entry.Books.title }}">
@@ -89,7 +89,7 @@
<div class="row display-flex">
{% if entries[0] %}
{% for entry in entries %}
<div class="col-sm-3 col-lg-2 col-xs-6 book" id="books">
<div class="col-sm-3 col-lg-2 col-xs-6 book session" id="books">
<div class="cover">
<a href="{{ url_for('web.show_book', book_id=entry.Books.id) }}" {% if simple==false %}data-toggle="modal" data-target="#bookDetailsModal" data-remote="false"{% endif %}>
<span class="img" title="{{ entry.Books.title }}">
+26 -3
View File
@@ -22,6 +22,7 @@
<updated>{{ current_time }}</updated>
<content type="text">{{_('Books sorted alphabetically')}}</content>
</entry>
{% if current_user.check_visibility(g.constants.SIDEBAR_HOT) %}
<entry>
<title>{{_('Hot Books')}}</title>
<link href="{{url_for('opds.feed_hot')}}" type="application/atom+xml;profile=opds-catalog"/>
@@ -29,6 +30,8 @@
<updated>{{ current_time }}</updated>
<content type="text">{{_('Popular publications from this catalog based on Downloads.')}}</content>
</entry>
{%endif %}
{% if current_user.check_visibility(g.constants.SIDEBAR_BEST_RATED) %}
<entry>
<title>{{_('Top Rated Books')}}</title>
<link href="{{url_for('opds.feed_best_rated')}}" type="application/atom+xml;profile=opds-catalog"/>
@@ -36,6 +39,8 @@
<updated>{{ current_time }}</updated>
<content type="text">{{_('Popular publications from this catalog based on Rating.')}}</content>
</entry>
{%endif %}
{% if current_user.check_visibility(g.constants.SIDEBAR_RECENT) %}
<entry>
<title>{{_('Recently added Books')}}</title>
<link href="{{url_for('opds.feed_new')}}" type="application/atom+xml;profile=opds-catalog"/>
@@ -43,6 +48,8 @@
<updated>{{ current_time }}</updated>
<content type="text">{{_('The latest Books')}}</content>
</entry>
{%endif %}
{% if current_user.check_visibility(g.constants.SIDEBAR_RANDOM) %}
<entry>
<title>{{_('Random Books')}}</title>
<link href="{{url_for('opds.feed_discover')}}" type="application/atom+xml;profile=opds-catalog"/>
@@ -50,7 +57,8 @@
<updated>{{ current_time }}</updated>
<content type="text">{{_('Show Random Books')}}</content>
</entry>
{% if not current_user.is_anonymous %}
{%endif %}
{% if current_user.check_visibility(g.constants.SIDEBAR_READ_AND_UNREAD) and not current_user.is_anonymous %}
<entry>
<title>{{_('Read Books')}}</title>
<link href="{{url_for('opds.feed_read_books')}}" type="application/atom+xml;profile=opds-catalog"/>
@@ -66,6 +74,7 @@
<content type="text">{{_('Unread Books')}}</content>
</entry>
{% endif %}
{% if current_user.check_visibility(g.constants.SIDEBAR_AUTHOR) %}
<entry>
<title>{{_('Authors')}}</title>
<link href="{{url_for('opds.feed_authorindex')}}" type="application/atom+xml;profile=opds-catalog"/>
@@ -73,13 +82,17 @@
<updated>{{ current_time }}</updated>
<content type="text">{{_('Books ordered by Author')}}</content>
</entry>
<entry>
{% endif %}
{% if current_user.check_visibility(g.constants.SIDEBAR_PUBLISHER) %}
<entry>
<title>{{_('Publishers')}}</title>
<link href="{{url_for('opds.feed_publisherindex')}}" type="application/atom+xml;profile=opds-catalog"/>
<id>{{url_for('opds.feed_publisherindex')}}</id>
<updated>{{ current_time }}</updated>
<content type="text">{{_('Books ordered by publisher')}}</content>
</entry>
{% endif %}
{% if current_user.check_visibility(g.constants.SIDEBAR_CATEGORY) %}
<entry>
<title>{{_('Categories')}}</title>
<link href="{{url_for('opds.feed_categoryindex')}}" type="application/atom+xml;profile=opds-catalog"/>
@@ -87,6 +100,8 @@
<updated>{{ current_time }}</updated>
<content type="text">{{_('Books ordered by category')}}</content>
</entry>
{% endif %}
{% if current_user.check_visibility(g.constants.SIDEBAR_SERIES) %}
<entry>
<title>{{_('Series')}}</title>
<link href="{{url_for('opds.feed_seriesindex')}}" type="application/atom+xml;profile=opds-catalog"/>
@@ -94,6 +109,8 @@
<updated>{{ current_time }}</updated>
<content type="text">{{_('Books ordered by series')}}</content>
</entry>
{% endif %}
{% if current_user.check_visibility(g.constants.SIDEBAR_LANGUAGE) %}
<entry>
<title>{{_('Languages')}}</title>
<link href="{{url_for('opds.feed_languagesindex')}}" type="application/atom+xml;profile=opds-catalog"/>
@@ -101,6 +118,8 @@
<updated>{{ current_time }}</updated>
<content type="text">{{_('Books ordered by Languages')}}</content>
</entry>
{% endif %}
{% if current_user.check_visibility(g.constants.SIDEBAR_RATING) %}
<entry>
<title>{{_('Ratings')}}</title>
<link href="{{url_for('opds.feed_ratingindex')}}" type="application/atom+xml;profile=opds-catalog"/>
@@ -108,7 +127,8 @@
<updated>{{ current_time }}</updated>
<content type="text">{{_('Books ordered by Rating')}}</content>
</entry>
{% endif %}
{% if current_user.check_visibility(g.constants.SIDEBAR_FORMAT) %}
<entry>
<title>{{_('File formats')}}</title>
<link href="{{url_for('opds.feed_formatindex')}}" type="application/atom+xml;profile=opds-catalog"/>
@@ -116,6 +136,8 @@
<updated>{{ current_time }}</updated>
<content type="text">{{_('Books ordered by file formats')}}</content>
</entry>
{% endif %}
{% if current_user.is_authenticated or g.allow_anonymous %}
<entry>
<title>{{_('Shelves')}}</title>
<link href="{{url_for('opds.feed_shelfindex')}}" type="application/atom+xml;profile=opds-catalog"/>
@@ -123,4 +145,5 @@
<updated>{{ current_time }}</updated>
<content type="text">{{_('Books organized in shelves')}}</content>
</entry>
{% endif %}
</feed>
+1 -1
View File
@@ -41,7 +41,7 @@
<div class="row display-flex">
{% for entry in entries %}
<div class="col-sm-3 col-lg-2 col-xs-6 book">
<div class="col-sm-3 col-lg-2 col-xs-6 book session">
<div class="cover">
{% if entry.Books.has_cover is defined %}
<a href="{{ url_for('web.show_book', book_id=entry.Books.id) }}" {% if simple==false %}data-toggle="modal" data-target="#bookDetailsModal" data-remote="false"{% endif %}>
+1 -1
View File
@@ -31,7 +31,7 @@
{% endif %}
<div class="row display-flex">
{% for entry in entries %}
<div class="col-sm-3 col-lg-2 col-xs-6 book">
<div class="col-sm-3 col-lg-2 col-xs-6 book session">
<div class="cover">
<a href="{{ url_for('web.show_book', book_id=entry.Books.id) }}" {% if simple==false %}data-toggle="modal" data-target="#bookDetailsModal" data-remote="false"{% endif %}>
<span class="img" title="{{entry.Books.title}}" >
+3 -3
View File
@@ -21,7 +21,7 @@
{% endif %}
<div class="form-group">
<label for="password">{{_('Password')}}</label>
<input type="password" class="form-control" name="password" id="password" data-lang="{{ current_user.locale }}" data-verify="{{ config.config_password_policy }}" {% if config.config_password_policy %} data-min={{ config.config_password_min_length }} data-special={{ config.config_password_special }} data-upper={{ config.config_password_upper }} data-lower={{ config.config_password_lower }} data-number={{ config.config_password_number }}{% endif %} value="" autocomplete="off">
<input type="password" class="form-control" name="password" id="password" data-lang="{{ current_user.locale }}" data-verify="{{ config.config_password_policy }}" {% if config.config_password_policy %} data-min={{ config.config_password_min_length }} data-word={{ config.config_password_character }} data-special={{ config.config_password_special }} data-upper={{ config.config_password_upper }} data-lower={{ config.config_password_lower }} data-number={{ config.config_password_number }}{% endif %} value="" autocomplete="off">
</div>
{% endif %}
<div class="form-group">
@@ -67,7 +67,7 @@
<div class="btn btn-danger" id="config_delete_kobo_token" data-value="{{ content.id }}" data-remote="false" {% if not content.remote_auth_token.first() %} style="display: none;" {% endif %}>{{_('Delete')}}</div>
</div>
<div class="form-group col">
<div class="btn btn-default" id="kobo_full_sync" data-value="{{ content.id }}" {% if not content.remote_auth_token.first() %} style="display: none;" {% endif %}>{{_('Force full kobo sync')}}</div>
<div class="btn btn-default" id="kobo_full_sync" data-value="{% if current_user.role_admin() %}{{ content.id }}{% else %}0{% endif %}" {% if not content.remote_auth_token.first() %} style="display: none;" {% endif %}>{{_('Force full kobo sync')}}</div>
</div>
{% endif %}
<div class="col-sm-6">
@@ -177,7 +177,7 @@
<script src="{{ url_for('static', filename='js/libs/bootstrap-table/bootstrap-editable.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/libs/pwstrength/i18next.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/libs/pwstrength/i18nextHttpBackend.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/libs/pwstrength/pwstrength-bootstrap.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/libs/pwstrength/pwstrength-bootstrap.js') }}"></script>
<script src="{{ url_for('static', filename='js/password.js') }}"></script>
<script src="{{ url_for('static', filename='js/table.js') }}"></script>
{% endblock %}