Merge branch 'Develop'

# Conflicts:
#	MANIFEST.in
#	README.md
#	cps/helper.py
#	cps/static/js/archive/archive.js
#	cps/translations/nl/LC_MESSAGES/messages.mo
#	cps/translations/nl/LC_MESSAGES/messages.po
#	cps/ub.py
#	cps/updater.py
#	cps/web.py
#	cps/worker.py
#	optional-requirements.txt
This commit is contained in:
Ozzieisaacs
2019-07-13 20:54:21 +02:00
parent 37736e11d5
commit 4708347c16
189 changed files with 33354 additions and 17681 deletions
+10 -7
View File
@@ -12,25 +12,27 @@
<th>{{_('DLS')}}</th>
<th class="hidden-xs">{{_('Admin')}}</th>
<th class="hidden-xs">{{_('Download')}}</th>
<th class="hidden-xs">{{_('View Ebooks')}}</th>
<th class="hidden-xs">{{_('Upload')}}</th>
<th class="hidden-xs">{{_('Edit')}}</th>
</tr>
{% for user in content %}
{% for user in allUser %}
{% if not user.role_anonymous() or config.config_anonbrowse %}
<tr>
<td><a href="{{url_for('edit_user', user_id=user.id)}}">{{user.nickname}}</a></td>
<td><a href="{{url_for('admin.edit_user', user_id=user.id)}}">{{user.nickname}}</a></td>
<td>{{user.email}}</td>
<td>{{user.kindle_mail}}</td>
<td>{{user.downloads.count()}}</td>
<td class="hidden-xs">{% if user.role_admin() %}<span class="glyphicon glyphicon-ok"></span>{% else %}<span class="glyphicon glyphicon-remove"></span>{% endif %}</td>
<td class="hidden-xs">{% if user.role_download() %}<span class="glyphicon glyphicon-ok"></span>{% else %}<span class="glyphicon glyphicon-remove"></span>{% endif %}</td>
<td class="hidden-xs">{% if user.role_viewer() %}<span class="glyphicon glyphicon-ok"></span>{% else %}<span class="glyphicon glyphicon-remove"></span>{% endif %}</td>
<td class="hidden-xs">{% if user.role_upload() %}<span class="glyphicon glyphicon-ok"></span>{% else %}<span class="glyphicon glyphicon-remove"></span>{% endif %}</td>
<td class="hidden-xs">{% if user.role_edit() %}<span class="glyphicon glyphicon-ok"></span>{% else %}<span class="glyphicon glyphicon-remove"></span>{% endif %}</td>
</tr>
{% endif %}
{% endfor %}
</table>
<div class="btn btn-default" id="admin_new_user"><a href="{{url_for('new_user')}}">{{_('Add new user')}}</a></div>
<div class="btn btn-default" id="admin_new_user"><a href="{{url_for('admin.new_user')}}">{{_('Add new user')}}</a></div>
</div>
</div>
@@ -53,7 +55,7 @@
<td class="hidden-xs">{{email.mail_from}}</td>
</tr>
</table>
<div class="btn btn-default" id="admin_edit_email"><a href="{{url_for('edit_mailsettings')}}">{{_('Change SMTP settings')}}</a></div>
<div class="btn btn-default" id="admin_edit_email"><a href="{{url_for('admin.edit_mailsettings')}}">{{_('Change SMTP settings')}}</a></div>
</div>
</div>
@@ -67,7 +69,7 @@
</div>
<div class="row">
<div class="col-xs-6 col-sm-6">{{_('Log level')}}</div>
<div class="col-xs-6 col-sm-6">{{config.get_Log_Level()}}</div>
<div class="col-xs-6 col-sm-6">{{config.get_log_level()}}</div>
</div>
<div class="row">
<div class="col-xs-6 col-sm-6">{{_('Port')}}</div>
@@ -96,14 +98,15 @@
<div class="col-xs-6 col-sm-5">{% if config.config_remote_login %}<span class="glyphicon glyphicon-ok"></span>{% else %}<span class="glyphicon glyphicon-remove"></span>{% endif %}</div>
</div>
</div>
<div class="btn btn-default"><a id="basic_config" href="{{url_for('configuration')}}">{{_('Basic Configuration')}}</a></div>
<div class="btn btn-default"><a id="view_config" href="{{url_for('view_configuration')}}">{{_('UI Configuration')}}</a></div>
<div class="btn btn-default"><a id="basic_config" href="{{url_for('admin.configuration')}}">{{_('Basic Configuration')}}</a></div>
<div class="btn btn-default"><a id="view_config" href="{{url_for('admin.view_configuration')}}">{{_('UI Configuration')}}</a></div>
</div>
</div>
<div class="row">
<div class="col">
<h2>{{_('Administration')}}</h2>
<div class="btn btn-default"><a id="logfile" href="{{url_for('admin.view_logfile')}}">{{_('View Logfiles')}}</a></div>
<div class="btn btn-default" id="restart_database">{{_('Reconnect to Calibre DB')}}</div>
<div class="btn btn-default" id="admin_restart" data-toggle="modal" data-target="#RestartDialog">{{_('Restart Calibre-Web')}}</div>
<div class="btn btn-default" id="admin_stop" data-toggle="modal" data-target="#ShutdownDialog">{{_('Stop Calibre-Web')}}</div>
+22 -9
View File
@@ -22,21 +22,29 @@
{% if author is not none %}
<h3>{{_("In Library")}}</h3>
{% endif %}
<div class="filterheader hidden-xs hidden-sm">
<a id="new" class="btn btn-primary" href="{{url_for('web.books_list', data='author', book_id=id, sort='new')}}"><span class="glyphicon glyphicon-book"></span> <span class="glyphicon glyphicon-calendar"></span><span class="glyphicon glyphicon-sort-by-order"></span></a>
<a id="old" class="btn btn-primary" href="{{url_for('web.books_list', data='author', book_id=id, sort='old')}}"><span class="glyphicon glyphicon-book"></span> <span class="glyphicon glyphicon-calendar"></span><span class="glyphicon glyphicon-sort-by-order-alt"></span></a>
<a id="asc" class="btn btn-primary" href="{{url_for('web.books_list', data='author', book_id=id, sort='abc')}}"><span class="glyphicon glyphicon-font"></span><span class="glyphicon glyphicon-sort-by-alphabet"></span></a>
<a id="desc" class="btn btn-primary" href="{{url_for('web.books_list', data='author', book_id=id, sort='zyx')}}"><span class="glyphicon glyphicon-font"></span><span class="glyphicon glyphicon-sort-by-alphabet-alt"></span></a>
<a id="pub_new" class="btn btn-primary" href="{{url_for('web.books_list', data='author', book_id=id, sort='pubnew')}}"><span class="glyphicon glyphicon-calendar"></span><span class="glyphicon glyphicon-sort-by-order"></span></a>
<a id="pub_old" class="btn btn-primary" href="{{url_for('web.books_list', data='author', book_id=id, sort='pubold')}}"><span class="glyphicon glyphicon-calendar"></span><span class="glyphicon glyphicon-sort-by-order-alt"></span></a>
<!--div class="btn-group character" role="group">
<a id="no_shelf" class="btn btn-primary" href="{{url_for('web.books_list', data='author', book_id=id, sort='pubold')}}"><span class="glyphicon glyphicon-list"></span><b>?</b></a>
<div id="all" class="btn btn-primary">{{_('All')}}</div>
</div-->
</div>
<div class="row">
{% if entries[0] %}
{% for entry in entries %}
<div id="books" class="col-sm-3 col-lg-2 col-xs-6 book">
<div class="cover">
<a href="{{ url_for('show_book', book_id=entry.id) }}">
{% if entry.has_cover %}
<img src="{{ url_for('get_cover', book_id=entry.id) }}" />
{% else %}
<img src="{{ url_for('static', filename='generic_cover.jpg') }}" />
{% endif %}
<a href="{{ url_for('web.show_book', book_id=entry.id) }}">
<img src="{{ url_for('web.get_cover', book_id=entry.id) }}" />
</a>
</div>
<div class="meta">
<a href="{{ url_for('show_book', book_id=entry.id) }}">
<a href="{{ url_for('web.show_book', book_id=entry.id) }}">
<p class="title">{{entry.title|shortentitle}}</p>
</a>
<p class="author">
@@ -45,7 +53,7 @@
{% if not loop.first %}
<span class="author-hidden-divider">&amp;</span>
{% endif %}
<a class="author-name author-hidden" href="{{url_for('author', book_id=author.id) }}">{{author.name.replace('|',',')|shortentitle(30)}}</a>
<a class="author-name author-hidden" href="{{url_for('web.books_list', data='author', sort='new', book_id=author.id) }}">{{author.name.replace('|',',')|shortentitle(30)}}</a>
{% if loop.last %}
<a href="#" class="author-expand" data-authors-max="{{g.config_authors_max}}" data-collapse-caption="({{_('reduce')}})">(...)</a>
{% endif %}
@@ -53,7 +61,12 @@
{% if not loop.first %}
<span>&amp;</span>
{% endif %}
<a class="author-name" href="{{url_for('author', book_id=author.id) }}">{{author.name.replace('|',',')|shortentitle(30)}}</a>
<a class="author-name" href="{{url_for('web.books_list', data='author', sort='new', book_id=author.id) }}">{{author.name.replace('|',',')|shortentitle(30)}}</a>
{% endif %}
{% endfor %}
{% for format in entry.data %}
{% if format.format|lower == 'mp3' %}
<span class="glyphicon glyphicon-music"></span>
{% endif %}
{% endfor %}
</p>
+6 -10
View File
@@ -5,11 +5,7 @@
<div class="col-sm-3 col-lg-3 col-xs-12">
<div class="cover">
{% if book.has_cover %}
<img src="{{ url_for('get_cover', book_id=book.id) }}" alt="{{ book.title }}"/>
{% else %}
<img src="{{ url_for('static', filename='generic_cover.jpg') }}" alt="{{ book.title }}"/>
{% endif %}
<img src="{{ url_for('web.get_cover', book_id=book.id) }}" alt="{{ book.title }}"/>
</div>
{% if g.user.role_delete_books() %}
<div class="text-center">
@@ -19,7 +15,7 @@
<div class="text-center more-stuff"><h4>{{_('Delete formats:')}}</h4>
{% for file in book.data %}
<div class="form-group">
<a href="{{ url_for('delete_book', book_id=book.id, book_format=file.format) }}" class="btn btn-danger" type="button">{{_('Delete')}} - {{file.format}}</a>
<a href="{{ url_for('editbook.delete_book', book_id=book.id, book_format=file.format) }}" class="btn btn-danger" type="button">{{_('Delete')}} - {{file.format}}</a>
</div>
{% endfor %}
</div>
@@ -28,7 +24,7 @@
{% if source_formats|length > 0 and conversion_formats|length > 0 %}
<div class="text-center more-stuff"><h4>{{_('Convert book format:')}}</h4>
<form class="padded-bottom" action="{{ url_for('convert_bookformat', book_id=book.id) }}" method="post" id="book_convert_frm">
<form class="padded-bottom" action="{{ url_for('editbook.convert_bookformat', book_id=book.id) }}" method="post" id="book_convert_frm">
<div class="form-group">
<div class="text-left">
<label class="control-label" for="book_format_from">{{_('Convert from:')}}</label>
@@ -53,7 +49,7 @@
{% endif %}
</div>
<form role="form" action="{{ url_for('edit_book', book_id=book.id) }}" method="post" enctype="multipart/form-data" id="book_edit_frm">
<form role="form" action="{{ url_for('editbook.edit_book', book_id=book.id) }}" method="post" enctype="multipart/form-data" id="book_edit_frm">
<div class="col-sm-9 col-xs-12">
<div class="form-group">
<label for="book_title">{{_('Book Title')}}</label>
@@ -175,7 +171,7 @@
</div>
<a href="#" id="get_meta" class="btn btn-default" data-toggle="modal" data-target="#metaModal">{{_('Get metadata')}}</a>
<button type="submit" id="submit" class="btn btn-default">{{_('Submit')}}</button>
<a href="{{ url_for('show_book', book_id=book.id) }}" class="btn btn-default">{{_('Back')}}</a>
<a href="{{ url_for('web.show_book', book_id=book.id) }}" class="btn btn-default">{{_('Back')}}</a>
</div>
</form>
@@ -196,7 +192,7 @@
</div>
<div class="modal-footer">
<a href="{{ url_for('delete_book', book_id=book.id) }}" class="btn btn-danger">{{_('Delete')}}</a>
<a href="{{ url_for('editbook.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>
+147 -42
View File
@@ -17,10 +17,10 @@
<div class="panel-body">
<div class="form-group required">
<label for="config_calibre_dir">{{_('Location of Calibre database')}}</label>
<input type="text" class="form-control" name="config_calibre_dir" id="config_calibre_dir" value="{% if content.config_calibre_dir != None %}{{ content.config_calibre_dir }}{% endif %}" autocomplete="off">
<input type="text" class="form-control" name="config_calibre_dir" id="config_calibre_dir" value="{% if config.config_calibre_dir != None %}{{ config.config_calibre_dir }}{% endif %}" autocomplete="off">
</div>
<div class="form-group required">
<input type="checkbox" id="config_use_google_drive" name="config_use_google_drive" data-control="gdrive_settings" {% if content.config_use_google_drive %}checked{% endif %} >
<input type="checkbox" id="config_use_google_drive" name="config_use_google_drive" data-control="gdrive_settings" {% if config.config_use_google_drive %}checked{% endif %} >
<label for="config_use_google_drive">{{_('Use Google Drive?')}}</label>
</div>
<div data-related="gdrive_settings">
@@ -31,12 +31,12 @@
</label>
</div>
{% else %}
{% if show_authenticate_google_drive and g.user.is_authenticated and content.config_use_google_drive %}
{% if show_authenticate_google_drive and g.user.is_authenticated and config.config_use_google_drive %}
<div class="form-group required">
<a href="{{ url_for('authenticate_google_drive') }}" class="btn btn-primary">{{_('Authenticate Google Drive')}}</a>
<a href="{{ url_for('gdrive.authenticate_google_drive') }}" class="btn btn-primary">{{_('Authenticate Google Drive')}}</a>
</div>
{% else %}
{% if show_authenticate_google_drive and g.user.is_authenticated and not content.config_use_google_drive %}
{% if show_authenticate_google_drive and g.user.is_authenticated and not config.config_use_google_drive %}
<div >{{_('Please hit submit to continue with setup')}}</div>
{% endif %}
{% if not g.user.is_authenticated %}
@@ -48,18 +48,18 @@
<label for="config_google_drive_folder">{{_('Google Drive Calibre folder')}}</label>
<select name="config_google_drive_folder" id="config_google_drive_folder" class="form-control">
{% for gdrivefolder in gdrivefolders %}
<option value="{{ gdrivefolder.title }}" {% if gdrivefolder.title == content.config_google_drive_folder %}selected{% endif %}>{{ gdrivefolder.title }}</option>
<option value="{{ gdrivefolder.title }}" {% if gdrivefolder.title == config.config_google_drive_folder %}selected{% endif %}>{{ gdrivefolder.title }}</option>
{% endfor %}
</select>
</div>
{% if content.config_google_drive_watch_changes_response %}
{% if config.config_google_drive_watch_changes_response %}
<label for="config_google_drive_watch_changes_response">{{_('Metadata Watch Channel ID')}}</label>
<div class="form-group input-group required">
<input type="text" class="form-control" name="config_google_drive_watch_changes_response" id="config_google_drive_watch_changes_response" value="{{ content.config_google_drive_watch_changes_response['id'] }} expires on {{ content.config_google_drive_watch_changes_response['expiration'] | strftime }}" autocomplete="off" disabled="">
<span class="input-group-btn"><a href="{{ url_for('revoke_watch_gdrive') }}" class="btn btn-primary">{{_('Revoke')}}</a></span>
<input type="text" class="form-control" name="config_google_drive_watch_changes_response" id="config_google_drive_watch_changes_response" value="{{ config.config_google_drive_watch_changes_response['id'] }} expires on {{ content.config_google_drive_watch_changes_response['expiration'] | strftime }}" autocomplete="off" disabled="">
<span class="input-group-btn"><a href="{{ url_for('gdrive.revoke_watch_gdrive') }}" class="btn btn-primary">{{_('Revoke')}}</a></span>
</div>
{% else %}
<a href="{{ url_for('watch_gdrive') }}" class="btn btn-primary">Enable watch of metadata.db</a>
<a href="{{ url_for('gdrive.watch_gdrive') }}" class="btn btn-primary">Enable watch of metadata.db</a>
{% endif %}
{% endif %}
{% endif %}
@@ -83,23 +83,23 @@
<div class="panel-body">
<div class="form-group">
<label for="config_port">{{_('Server Port')}}</label>
<input type="number" min="1" max="65535" class="form-control" name="config_port" id="config_port" value="{% if content.config_port != None %}{{ content.config_port }}{% endif %}" autocomplete="off" required>
<input type="number" min="1" max="65535" class="form-control" name="config_port" id="config_port" value="{% if config.config_port != None %}{{ config.config_port }}{% endif %}" autocomplete="off" required>
</div>
<div class="form-group">
<label for="config_certfile">{{_('SSL certfile location (leave it empty for non-SSL Servers)')}}</label>
<input type="text" class="form-control" name="config_certfile" id="config_certfile" value="{% if content.config_certfile != None %}{{ content.config_certfile }}{% endif %}" autocomplete="off">
<input type="text" class="form-control" name="config_certfile" id="config_certfile" value="{% if config.config_certfile != None %}{{ config.config_certfile }}{% endif %}" autocomplete="off">
</div>
<div class="form-group">
<label for="config_keyfile">{{_('SSL Keyfile location (leave it empty for non-SSL Servers)')}}</label>
<input type="text" class="form-control" name="config_keyfile" id="config_keyfile" value="{% if content.config_keyfile != None %}{{ content.config_keyfile }}{% endif %}" autocomplete="off">
<input type="text" class="form-control" name="config_keyfile" id="config_keyfile" value="{% if config.config_keyfile != None %}{{ config.config_keyfile }}{% endif %}" autocomplete="off">
</div>
<div class="form-group">
<label for="config_updater">{{_('Update channel')}}</label>
<select name="config_updater" id="config_updater" class="form-control">
<option value="0" {% if content.config_updatechannel == 0 %}selected{% endif %}>{{_('Stable')}}</option>
<!--option value="1" {% if content.config_updatechannel == 1 %}selected{% endif %}>{{_('Stable (Automatic)')}}</option-->
<option value="2" {% if content.config_updatechannel == 2 %}selected{% endif %}>{{_('Nightly')}}</option>
<!--option-- value="3" {% if content.config_updatechannel == 3 %}selected{% endif %}>{{_('Nightly (Automatic)')}}</option-->
<label for="config_updatechannel">{{_('Update channel')}}</label>
<select name="config_updatechannel" id="config_updatechannel" class="form-control">
<option value="0" {% if config.config_updatechannel == 0 %}selected{% endif %}>{{_('Stable')}}</option>
<!--option value="1" {% if config.config_updatechannel == 1 %}selected{% endif %}>{{_('Stable (Automatic)')}}</option-->
<option value="2" {% if config.config_updatechannel == 2 %}selected{% endif %}>{{_('Nightly')}}</option>
<!--option-- value="3" {% if config.config_updatechannel == 3 %}selected{% endif %}>{{_('Nightly (Automatic)')}}</option-->
</select>
</div>
</div>
@@ -119,15 +119,23 @@
<div class="form-group">
<label for="config_log_level">{{_('Log Level')}}</label>
<select name="config_log_level" id="config_log_level" class="form-control">
<option value="10" {% if content.config_log_level == 10 %}selected{% endif %}>DEBUG</option>
<option value="20" {% if content.config_log_level == 20 or content.config_log_level == None %}selected{% endif %}>INFO</option>
<option value="30" {% if content.config_log_level == 30 %}selected{% endif %}>WARNING</option>
<option value="40" {% if content.config_log_level == 40 %}selected{% endif %}>ERROR</option>
<option value="10" {% if config.config_log_level == 10 %}selected{% endif %}>DEBUG</option>
<option value="20" {% if config.config_log_level == 20 or config.config_log_level == None %}selected{% endif %}>INFO</option>
<option value="30" {% if config.config_log_level == 30 %}selected{% endif %}>WARNING</option>
<option value="40" {% if config.config_log_level == 40 %}selected{% endif %}>ERROR</option>
</select>
</div>
<div class="form-group">
<label for="config_logfile">{{_('Location and name of logfile (calibre-web.log for no entry)')}}</label>
<input type="text" class="form-control" name="config_logfile" id="config_logfile" value="{% if content.config_logfile != None %}{{ content.config_logfile }}{% endif %}" autocomplete="off">
<input type="text" class="form-control" name="config_logfile" id="config_logfile" value="{% if config.config_logfile != None %}{{ config.config_logfile }}{% endif %}" autocomplete="off">
</div>
<div class="form-group">
<input type="checkbox" id="config_access_log" name="config_access_log" {% if config.config_access_log %}checked{% endif %}>
<label for="config_access_log">{{_('Enable Access Log')}}</label>
</div>
<div class="form-group">
<label for="config_access_logfile">{{_('Location and name of access logfile (access.log for no entry)')}}</label>
<input type="text" class="form-control" name="config_access_logfile" id="config_access_logfile" value="{% if config.config_access_logfile != None %}{{ config.config_access_logfile }}{% endif %}" autocomplete="off">
</div>
</div>
</div>
@@ -144,37 +152,134 @@
<div id="collapsefive" class="panel-collapse collapse">
<div class="panel-body">
<div class="form-group">
<input type="checkbox" id="config_uploading" name="config_uploading" {% if content.config_uploading %}checked{% endif %}>
<input type="checkbox" id="config_uploading" name="config_uploading" {% if config.config_uploading %}checked{% endif %}>
<label for="config_uploading">{{_('Enable uploading')}}</label>
</div>
<div class="form-group">
<input type="checkbox" id="config_anonbrowse" name="config_anonbrowse" {% if content.config_anonbrowse %}checked{% endif %}>
<input type="checkbox" id="config_anonbrowse" name="config_anonbrowse" {% if config.config_anonbrowse %}checked{% endif %}>
<label for="config_anonbrowse">{{_('Enable anonymous browsing')}}</label>
</div>
<div class="form-group">
<input type="checkbox" id="config_public_reg" name="config_public_reg" {% if content.config_public_reg %}checked{% endif %}>
<input type="checkbox" id="config_public_reg" name="config_public_reg" {% if config.config_public_reg %}checked{% endif %}>
<label for="config_public_reg">{{_('Enable public registration')}}</label>
</div>
<div class="form-group">
<input type="checkbox" id="config_remote_login" name="config_remote_login" {% if content.config_remote_login %}checked{% endif %}>
<input type="checkbox" id="config_remote_login" name="config_remote_login" {% if config.config_remote_login %}checked{% endif %}>
<label for="config_remote_login">{{_('Enable remote login ("magic link")')}}</label>
</div>
{% if goodreads %}
{% if feature_support['goodreads'] %}
<div class="form-group">
<input type="checkbox" id="config_use_goodreads" name="config_use_goodreads" data-control="goodreads-settings" {% if content.config_use_goodreads %}checked{% endif %}>
<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">{{_('Obtain 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 content.config_goodreads_api_key != None %}{{ content.config_goodreads_api_key }}{% endif %}" autocomplete="off">
<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">{{_('Goodreads API Secret')}}</label>
<input type="text" class="form-control" id="config_goodreads_api_secret" name="config_goodreads_api_secret" value="{% if content.config_goodreads_api_secret != None %}{{ content.config_goodreads_api_secret }}{% endif %}" autocomplete="off">
<input type="text" class="form-control" id="config_goodreads_api_secret" name="config_goodreads_api_secret" value="{% if config.config_goodreads_api_secret != None %}{{ config.config_goodreads_api_secret }}{% endif %}" autocomplete="off">
</div>
</div>
{% endif %}
{% if feature_support['ldap'] or feature_support['oauth'] %}
<div class="form-group">
<label for="config_login_type">{{_('Login type')}}</label>
<select name="config_login_type" id="config_login_type" class="form-control" data-control="login-settings">
<option value="0" {% if config.config_login_type == 0 %}selected{% endif %}>{{_('Use standard Authentication')}}</option>
{% if feature_support['ldap'] %}
<option value="1" {% if config.config_login_type == 1 %}selected{% endif %}>{{_('Use LDAP Authentication')}}</option>
{% endif %}
{% if feature_support['oauth'] %}
<option value="2" {% if config.config_login_type == 2 %}selected{% endif %}>{{_('Use GitHub OAuth')}}</option>
<option value="3" {% if config.config_login_type == 3 %}selected{% endif %}>{{_('Use Google OAuth')}}</option>
{% endif %}
</select>
</div>
{% if feature_support['ldap'] %}
<div data-related="login-settings-1">
<div class="form-group">
<label for="config_ldap_provider_url">{{_('LDAP Server Host Name or IP Address')}}</label>
<input type="text" class="form-control" id="config_ldap_provider_url" name="config_ldap_provider_url" value="{% if config.config_ldap_provider_url != None %}{{ config.config_ldap_provider_url }}{% endif %}" autocomplete="off">
</div>
<div class="form-group">
<label for="config_ldap_port">{{_('LDAP Server Port')}}</label>
<input type="text" class="form-control" id="config_ldap_port" name="config_ldap_port" value="{% if config.config_ldap_port != None %}{{ config.config_ldap_port }}{% endif %}" autocomplete="off">
</div>
<div class="form-group">
<label for="config_ldap_schema">{{_('LDAP schema (ldap or ldaps)')}}</label>
<input type="text" class="form-control" id="config_ldap_schema" name="config_ldap_schema" value="{% if config.config_ldap_schema != None %}{{ config.config_ldap_schema }}{% endif %}" autocomplete="off">
</div>
<div class="form-group">
<label for="config_ldap_serv_username">{{_('LDAP Admin username')}}</label>
<input type="text" class="form-control" id="config_ldap_serv_username" name="config_ldap_serv_username" value="{% if config.config_ldap_serv_username != None %}{{ config.config_ldap_serv_username }}{% endif %}" autocomplete="off">
</div>
<div class="form-group">
<label for="config_ldap_serv_password">{{_('LDAP Admin password')}}</label>
<input type="password" class="form-control" id="config_ldap_serv_password" name="config_ldap_serv_password" value="{% if config.config_ldap_serv_password != None %}{{ config.config_ldap_serv_password }}{% endif %}" autocomplete="off">
</div>
<div class="form-group">
<input type="checkbox" id="config_ldap_use_ssl" name="config_ldap_use_ssl" {% if config.config_ldap_use_ssl %}checked{% endif %}>
<label for="config_ldap_use_ssl">{{_('LDAP Server use SSL')}}</label>
</div>
<div class="form-group">
<input type="checkbox" id="config_ldap_use_tls" name="config_ldap_use_tls" {% if config.config_ldap_use_tls %}checked{% endif %}>
<label for="config_ldap_use_tls">{{_('LDAP Server use TLS')}}</label>
</div>
<div class="form-group">
<input type="checkbox" id="config_ldap_require_cert" name="config_ldap_require_cert" data-control="ldap-cert-settings" {% if config.config_ldap_require_cert %}checked{% endif %}>
<label for="config_ldap_require_cert">{{_('LDAP Server Certificate')}}</label>
</div>
<div data-related="ldap-cert-settings">
<div class="form-group">
<label for="config_ldap_cert_path">{{_('LDAP SSL Certificate Path')}}</label>
<input type="text" class="form-control" id="config_ldap_cert_path" name="config_ldap_cert_path" value="{% if config.config_ldap_cert_path != None and config.config_ldap_require_cert !=None %}{{ config.config_ldap_cert_path }}{% endif %}" autocomplete="off">
</div>
</div>
<div class="form-group">
<label for="config_ldap_dn">{{_('LDAP Distinguished Name (DN)')}}</label>
<input type="text" class="form-control" id="config_ldap_dn" name="config_ldap_dn" value="{% if config.config_ldap_dn != None %}{{ config.config_ldap_dn }}{% endif %}" autocomplete="off">
</div>
<div class="form-group">
<label for="config_ldap_user_object">{{_('LDAP User object filter')}}</label>
<input type="text" class="form-control" id="config_ldap_user_object" name="config_ldap_user_object" value="{% if config.config_ldap_user_object != None %}{{ config.config_ldap_user_object }}{% endif %}" autocomplete="off">
</div>
<div class="form-group">
<input type="checkbox" id="config_ldap_openldap" name="config_ldap_openldap" {% if config.config_ldap_openldap %}checked{% endif %}>
<label for="config_ldap_openldap">{{_('LDAP Server is OpenLDAP?')}}</label>
</div>
</div>
{% endif %}
{% if feature_support['oauth'] %}
<div data-related="login-settings-2">
<div class="form-group">
<a href="https://github.com/settings/developers" target="_blank">{{_('Obtain GitHub OAuth Credential')}}</a>
</div>
<div class="form-group">
<label for="config_github_oauth_client_id">{{_('GitHub OAuth Client Id')}}</label>
<input type="text" class="form-control" id="config_github_oauth_client_id" name="config_github_oauth_client_id" value="{% if config.config_github_oauth_client_id != None %}{{ config.config_github_oauth_client_id }}{% endif %}" autocomplete="off">
</div>
<div class="form-group">
<label for="config_github_oauth_client_secret">{{_('GitHub OAuth Client Secret')}}</label>
<input type="text" class="form-control" id="config_github_oauth_client_secret" name="config_github_oauth_client_secret" value="{% if config.config_github_oauth_client_secret != None %}{{ config.config_github_oauth_client_secret }}{% endif %}" autocomplete="off">
</div>
</div>
<div data-related="login-settings-3">
<div class="form-group">
<a href="https://console.developers.google.com/apis/credentials" target="_blank">{{_('Obtain Google OAuth Credential')}}</a>
</div>
<div class="form-group">
<label for="config_google_oauth_client_id">{{_('Google OAuth Client Id')}}</label>
<input type="text" class="form-control" id="config_google_oauth_client_id" name="config_google_oauth_client_id" value="{% if config.config_google_oauth_client_id != None %}{{ config.config_google_oauth_client_id }}{% endif %}" autocomplete="off">
</div>
<div class="form-group">
<label for="config_google_oauth_client_secret">{{_('Google OAuth Client Secret')}}</label>
<input type="text" class="form-control" id="config_google_oauth_client_secret" name="config_google_oauth_client_secret" value="{% if config.config_google_oauth_client_secret != None %}{{ config.config_google_oauth_client_secret }}{% endif %}" autocomplete="off">
</div>
</div>
{% endif %}
{% endif %}
</div>
</div>
@@ -191,27 +296,27 @@
<div id="collapseeight" class="panel-collapse collapse">
<div class="panel-body">
<div class="form-group">
<div><input type="radio" name="config_ebookconverter" id="converter0" value="0" {% if content.config_ebookconverter == 0 %}checked{% endif %}>
<div><input type="radio" name="config_ebookconverter" id="converter0" value="0" {% if config.config_ebookconverter == 0 %}checked{% endif %}>
<label for="converter0">{{_('No converter')}}</label></div>
<div><input type="radio" name="config_ebookconverter" id="converter1" value="1" {% if content.config_ebookconverter == 1 %}checked{% endif %}>
<div><input type="radio" name="config_ebookconverter" id="converter1" value="1" {% if config.config_ebookconverter == 1 %}checked{% endif %}>
<label for="converter1">{{_('Use Kindlegen')}}</label></div>
<div><input type="radio" name="config_ebookconverter" id="converter2" value="2" {% if content.config_ebookconverter == 2 %}checked{% endif %}>
<div><input type="radio" name="config_ebookconverter" id="converter2" value="2" {% if config.config_ebookconverter == 2 %}checked{% endif %}>
<label for="converter2">{{_('Use calibre\'s ebook converter')}}</label></div>
</div>
<div data-related="calibre">
<div class="form-group">
<label for="config_calibre">{{_('E-Book converter settings')}}</label>
<input type="text" class="form-control" id="config_calibre" name="config_calibre" value="{% if content.config_calibre != None %}{{ content.config_calibre }}{% endif %}" autocomplete="off">
<input type="text" class="form-control" id="config_calibre" name="config_calibre" value="{% if config.config_calibre != None %}{{ config.config_calibre }}{% endif %}" autocomplete="off">
</div>
<div class="form-group">
<label for="config_calibre">{{_('Path to convertertool')}}</label>
<input type="text" class="form-control" id="config_converterpath" name="config_converterpath" value="{% if content.config_converterpath != None %}{{ content.config_converterpath }}{% endif %}" autocomplete="off">
<input type="text" class="form-control" id="config_converterpath" name="config_converterpath" value="{% if config.config_converterpath != None %}{{ config.config_converterpath }}{% endif %}" autocomplete="off">
</div>
</div>
{% if rarfile_support %}
<div class="form-group">
<label for="config_rarfile_location">{{_('Location of Unrar binary')}}</label>
<input type="text" class="form-control" name="config_rarfile_location" id="config_rarfile_location" value="{% if content.config_rarfile_location != None %}{{ content.config_rarfile_location }}{% endif %}" autocomplete="off">
<input type="text" class="form-control" name="config_rarfile_location" id="config_rarfile_location" value="{% if config.config_rarfile_location != None %}{{ config.config_rarfile_location }}{% endif %}" autocomplete="off">
</div>
{% endif %}
</div>
@@ -222,11 +327,11 @@
<div class="col-sm-12">
<button type="submit" name="submit" class="btn btn-default">{{_('Submit')}}</button>
{% if not origin %}
<a href="{{ url_for('admin') }}" class="btn btn-default">{{_('Back')}}</a>
{% if show_back_button %}
<a href="{{ url_for('admin.admin') }}" class="btn btn-default">{{_('Back')}}</a>
{% endif %}
{% if success %}
<a href="{{ url_for('login') }}" name="login" class="btn btn-default">{{_('Login')}}</a>
{% if show_login_button %}
<a href="{{ url_for('web.login') }}" name="login" class="btn btn-default">{{_('Login')}}</a>
{% endif %}
</div>
</form>
+39 -71
View File
@@ -17,48 +17,48 @@
<div class="panel-body">
<div class="form-group">
<label for="config_calibre_web_title">{{_('Title')}}</label>
<input type="text" class="form-control" name="config_calibre_web_title" id="config_calibre_web_title" value="{% if content.config_calibre_web_title != None %}{{ content.config_calibre_web_title }}{% endif %}" autocomplete="off" required>
<input type="text" class="form-control" name="config_calibre_web_title" id="config_calibre_web_title" value="{% if conf.config_calibre_web_title != None %}{{ conf.config_calibre_web_title }}{% endif %}" autocomplete="off" required>
</div>
<div class="form-group">
<label for="config_books_per_page">{{_('Books per page')}}</label>
<input type="number" min="1" max="200" class="form-control" name="config_books_per_page" id="config_books_per_page" value="{% if content.config_books_per_page != None %}{{ content.config_books_per_page }}{% endif %}" autocomplete="off">
<input type="number" min="1" max="200" class="form-control" name="config_books_per_page" id="config_books_per_page" value="{% if conf.config_books_per_page != None %}{{ conf.config_books_per_page }}{% endif %}" autocomplete="off">
</div>
<div class="form-group">
<label for="config_random_books">{{_('No. of random books to show')}}</label>
<input type="number" min="1" max="30" class="form-control" name="config_random_books" id="config_random_books" value="{% if content.config_random_books != None %}{{ content.config_random_books }}{% endif %}" autocomplete="off">
<input type="number" min="1" max="30" class="form-control" name="config_random_books" id="config_random_books" value="{% if conf.config_random_books != None %}{{ conf.config_random_books }}{% endif %}" autocomplete="off">
</div>
<div class="form-group">
<label for="config_authors_max">{{_('No. of authors to show before hiding (0=disable hiding)')}}</label>
<input type="number" min="0" max="999" class="form-control" name="config_authors_max" id="config_authors_max" value="{% if content.config_authors_max != None %}{{ content.config_authors_max }}{% endif %}" autocomplete="off">
<input type="number" min="0" max="999" class="form-control" name="config_authors_max" id="config_authors_max" value="{% if conf.config_authors_max != None %}{{ conf.config_authors_max }}{% endif %}" autocomplete="off">
</div>
<div class="form-group">
<label for="config_theme">{{_('Theme')}}</label>
<select name="config_theme" id="config_theme" class="form-control">
<option value="0" {% if content.config_theme == 0 %}selected{% endif %}>{{ _("Standard Theme") }}</option>
<option value="1" {% if content.config_theme == 1 %}selected{% endif %}>{{ _("caliBlur! Dark Theme") }}</option>
<option value="0" {% if conf.config_theme == 0 %}selected{% endif %}>{{ _("Standard Theme") }}</option>
<option value="1" {% if conf.config_theme == 1 %}selected{% endif %}>{{ _("caliBlur! Dark Theme") }}</option>
</select>
</div>
<div class="form-group">
<label for="config_columns_to_ignore">{{_('Regular expression for ignoring columns')}}</label>
<input type="text" class="form-control" name="config_columns_to_ignore" id="config_columns_to_ignore" value="{% if content.config_columns_to_ignore != None %}{{ content.config_columns_to_ignore }}{% endif %}" autocomplete="off">
<input type="text" class="form-control" name="config_columns_to_ignore" id="config_columns_to_ignore" value="{% if conf.config_columns_to_ignore != None %}{{ conf.config_columns_to_ignore }}{% endif %}" autocomplete="off">
</div>
<div class="form-group">
<label for="config_read_column">{{_('Link read/unread status to Calibre column')}}</label>
<select name="config_read_column" id="config_read_column" class="form-control">
<option value="0" {% if content.config_read_column == 0 %}selected{% endif %}></option>
<option value="0" {% if conf.config_read_column == 0 %}selected{% endif %}></option>
{% for readColumn in readColumns %}
<option value="{{ readColumn.id }}" {% if readColumn.id == content.config_read_column %}selected{% endif %}>{{ readColumn.name }}</option>
<option value="{{ readColumn.id }}" {% if readColumn.id == conf.config_read_column %}selected{% endif %}>{{ readColumn.name }}</option>
{% endfor %}
</select>
</div>
<div class="form-group">
<label for="config_title_regex">{{_('Regular expression for title sorting')}}</label>
<input type="text" class="form-control" name="config_title_regex" id="config_title_regex" value="{% if content.config_title_regex != None %}{{ content.config_title_regex }}{% endif %}" autocomplete="off">
<input type="text" class="form-control" name="config_title_regex" id="config_title_regex" value="{% if conf.config_title_regex != None %}{{ conf.config_title_regex }}{% endif %}" autocomplete="off">
</div>
<div class="form-group">
<label for="config_mature_content_tags">{{_('Tags for Mature Content')}}</label>
<input type="text" class="form-control" name="config_mature_content_tags" id="config_mature_content_tags"
value="{% if content.config_mature_content_tags != None%}{{ content.config_mature_content_tags }}{% endif %}"
value="{% if conf.config_mature_content_tags != None%}{{ conf.config_mature_content_tags }}{% endif %}"
autocomplete="off"
>
</div>
@@ -77,31 +77,35 @@
<div id="collapsesix" class="panel-collapse collapse">
<div class="panel-body">
<div class="form-group">
<input type="checkbox" name="admin_role" id="admin_role" {% if content.role_admin() %}checked{% endif %}>
<input type="checkbox" name="admin_role" id="admin_role" {% if conf.role_admin() %}checked{% endif %}>
<label for="admin_role">{{_('Admin user')}}</label>
</div>
<div class="form-group">
<input type="checkbox" name="download_role" id="download_role" {% if content.role_download() %}checked{% endif %}>
<input type="checkbox" name="download_role" id="download_role" {% if conf.role_download() %}checked{% endif %}>
<label for="download_role">{{_('Allow Downloads')}}</label>
</div>
<div class="form-group">
<input type="checkbox" name="upload_role" id="upload_role" {% if content.role_upload() %}checked{% endif %}>
<input type="checkbox" name="viewer_role" id="viewer_role" {% if conf.role_viewer() %}checked{% endif %}>
<label for="viewer_role">{{_('Allow book viewer')}}</label>
</div>
<div class="form-group">
<input type="checkbox" name="upload_role" id="upload_role" {% if conf.role_upload() %}checked{% endif %}>
<label for="upload_role">{{_('Allow Uploads')}}</label>
</div>
<div class="form-group">
<input type="checkbox" name="edit_role" id="edit_role" {% if content.role_edit() %}checked{% endif %}>
<input type="checkbox" name="edit_role" id="edit_role" {% if conf.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 %}>
<input type="checkbox" name="delete_role" id="delete_role" {% if conf.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 %}>
<input type="checkbox" name="passwd_role" id="passwd_role" {% if conf.role_passwd() %}checked{% endif %}>
<label for="passwd_role">{{_('Allow Changing Password')}}</label>
</div>
<div class="form-group">
<input type="checkbox" name="edit_shelf_role" id="edit_shelf_role" {% if content.role_edit_shelfs() %}checked{% endif %}>
<input type="checkbox" name="edit_shelf_role" id="edit_shelf_role" {% if conf.role_edit_shelfs() %}checked{% endif %}>
<label for="edit_shelf_role">{{_('Allow Editing Public Shelfs')}}</label>
</div>
</div>
@@ -118,65 +122,29 @@
</div>
<div id="collapseseven" class="panel-collapse collapse">
<div class="panel-body">
<div class="form-group">
<input type="checkbox" name="show_random" id="show_random" {% if content.show_random_books() %}checked{% endif %}>
<label for="show_random">{{_('Show random books')}}</label>
</div>
<div class="form-group">
<input type="checkbox" name="show_recent" id="show_recent" {% if content.show_recent() %}checked{% endif %}>
<label for="show_recent">{{_('Show recent books')}}</label>
</div>
<div class="form-group">
<input type="checkbox" name="show_sorted" id="show_sorted" {% if content.show_sorted() %}checked{% endif %}>
<label for="show_sorted">{{_('Show sorted books')}}</label>
</div>
<div class="form-group">
<input type="checkbox" name="show_hot" id="show_hot" {% if content.show_hot_books() %}checked{% endif %}>
<label for="show_hot">{{_('Show hot books')}}</label>
</div>
<div class="form-group">
<input type="checkbox" name="show_best_rated" id="show_best_rated" {% if content.show_best_rated_books() %}checked{% endif %}>
<label for="show_best_rated">{{_('Show best rated books')}}</label>
</div>
<div class="form-group">
<input type="checkbox" name="show_language" id="show_language" {% if content.show_language() %}checked{% endif %}>
<label for="show_language">{{_('Show language selection')}}</label>
</div>
<div class="form-group">
<input type="checkbox" name="show_series" id="show_series" {% if content.show_series() %}checked{% endif %}>
<label for="show_series">{{_('Show series selection')}}</label>
</div>
<div class="form-group">
<input type="checkbox" name="show_category" id="show_category" {% if content.show_category() %}checked{% endif %}>
<label for="show_category">{{_('Show category selection')}}</label>
</div>
<div class="form-group">
<input type="checkbox" name="show_author" id="show_author" {% if content.show_author() %}checked{% endif %}>
<label for="show_author">{{_('Show author selection')}}</label>
</div>
<div class="form-group">
<input type="checkbox" name="show_publisher" id="show_publisher" {% if content.show_publisher() %}checked{% endif %}>
<label for="show_publisher">{{_('Show publisher selection')}}</label>
</div>
<div class="form-group">
<input type="checkbox" name="show_read_and_unread" id="show_read_and_unread" {% if content.show_read_and_unread() %}checked{% endif %}>
<label for="show_read_and_unread">{{_('Show read and unread')}}</label>
</div>
<div class="form-group">
<input type="checkbox" name="show_detail_random" id="show_detail_random" {% if content.show_detail_random() %}checked{% endif %}>
<label for="show_detail_random">{{_('Show random books in detail view')}}</label>
</div>
<div class="form-group">
<input type="checkbox" name="show_mature_content" id="show_mature_content" {% if content.show_mature_content() %}checked{% endif %}>
<label for="show_mature_content">{{_('Show mature content')}}</label>
</div>
{% for element in sidebar %}
{% if element['config_show'] %}
<div class="form-group">
<input type="checkbox" name="show_{{element['visibility']}}" id="show_{{element['visibility']}}" {% if conf.show_element_new_user(element['visibility']) %}checked{% endif %}>
<label for="show_{{element['visibility']}}">{{element['show_text']}}</label>
</div>
{% endif %}
{% endfor %}
<div class="form-group">
<input type="checkbox" name="Show_detail_random" id="Show_detail_random" {% if conf.show_detail_random() %}checked{% endif %}>
<label for="Show_detail_random">{{_('Show random books in detail view')}}</label>
</div>
<div class="form-group">
<input type="checkbox" name="Show_mature_content" id="Show_mature_content" {% if conf.show_mature_content() %}checked{% endif %}>
<label for="Show_mature_content">{{_('Show mature content')}}</label>
</div>
</div>
</div>
</div>
</div>
<div class="col-sm-12">
<button type="submit" name="submit" class="btn btn-default">{{_('Submit')}}</button>
<a href="{{ url_for('admin') }}" class="btn btn-default">{{_('Back')}}</a>
<a href="{{ url_for('admin.admin') }}" class="btn btn-default">{{_('Back')}}</a>
</div>
</form>
</div>
+43 -26
View File
@@ -4,11 +4,7 @@
<div class="row">
<div class="col-sm-3 col-lg-3 col-xs-5">
<div class="cover">
{% if entry.has_cover %}
<img src="{{ url_for('get_cover', book_id=entry.id) }}" alt="{{ entry.title }}" />
{% else %}
<img src="{{ url_for('static', filename='generic_cover.jpg') }}" alt="{{ entry.title }}" />
{% endif %}
<img src="{{ url_for('web.get_cover', book_id=entry.id) }}" alt="{{ entry.title }}" />
</div>
</div>
<div class="col-sm-9 col-lg-9 book-meta">
@@ -22,7 +18,7 @@
{{_('Download')}} :
</button>
{% for format in entry.data %}
<a href="{{ url_for('get_download_link_ext', book_id=entry.id, book_format=format.format|lower, anyname=entry.id|string+'.'+format.format|lower) }}" id="btnGroupDrop1{{format.format|lower}}" class="btn btn-primary" role="button">
<a href="{{ url_for('web.download_link', book_id=entry.id, book_format=format.format|lower, anyname=entry.id|string+'.'+format.format|lower) }}" id="btnGroupDrop1{{format.format|lower}}" class="btn btn-primary" role="button">
<span class="glyphicon glyphicon-download"></span>{{format.format}} ({{ format.uncompressed_size|filesizeformat }})
</a>
{% endfor %}
@@ -33,7 +29,7 @@
</button>
<ul class="dropdown-menu" aria-labelledby="btnGroupDrop1">
{% for format in entry.data %}
<li><a href="{{ url_for('get_download_link_ext', book_id=entry.id, book_format=format.format|lower, anyname=entry.id|string+'.'+format.format|lower) }}">{{format.format}} ({{ format.uncompressed_size|filesizeformat }})</a></li>
<li><a href="{{ url_for('web.download_link', book_id=entry.id, book_format=format.format|lower, anyname=entry.id|string+'.'+format.format|lower) }}">{{format.format}} ({{ format.uncompressed_size|filesizeformat }})</a></li>
{% endfor %}
</ul>
{% endif %}
@@ -42,7 +38,7 @@
{% endif %}
{% if g.user.kindle_mail and kindle_list %}
{% if kindle_list.__len__() == 1 %}
<a href="{{url_for('send_to_kindle', book_id=entry.id, book_format=kindle_list[0]['format'], convert=kindle_list[0]['convert'])}}" id="sendbtn" data-text="{{_('Send to Kindle')}}" class="btn btn-primary" role="button"><span class="glyphicon glyphicon-send"></span> {{kindle_list[0]['text']}}</a>
<a href="{{url_for('web.send_to_kindle', book_id=entry.id, book_format=kindle_list[0]['format'], convert=kindle_list[0]['convert'])}}" id="sendbtn" data-text="{{_('Send to Kindle')}}" class="btn btn-primary" role="button"><span class="glyphicon glyphicon-send"></span> {{kindle_list[0]['text']}}</a>
{% else %}
<div class="btn-group" role="group">
<button id="sendbtn2" type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
@@ -51,13 +47,13 @@
</button>
<ul class="dropdown-menu" aria-labelledby="send-to-kindle">
{% for format in kindle_list %}
<li><a href="{{url_for('send_to_kindle', book_id=entry.id, book_format=format['format'], convert=format['convert'])}}">{{format['text']}}</a></li>
<li><a href="{{url_for('web.send_to_kindle', book_id=entry.id, book_format=format['format'], convert=format['convert'])}}">{{format['text']}}</a></li>
{%endfor%}
</ul>
</div>
{% endif %}
{% endif %}
{% if reader_list %}
{% if reader_list and g.user.role_viewer() %}
<div class="btn-group" role="group">
<button id="read-in-browser" type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<span class="glyphicon glyphicon-eye-open"></span> {{_('Read in browser')}}
@@ -65,17 +61,38 @@
</button>
<ul class="dropdown-menu" aria-labelledby="read-in-browser">
{% for format in reader_list %}
<li><a target="_blank" href="{{ url_for('read_book', book_id=entry.id, book_format=format) }}">{{format}}</a></li>
<li><a target="_blank" href="{{ url_for('web.read_book', book_id=entry.id, book_format=format) }}">{{format}}</a></li>
{%endfor%}
</ul>
</div>
{% endif %}
{% endif %}
{% if audioentries|length > 0 %}
<div class="btn-group" role="group">
<button id="listen-in-browser" type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<span class="glyphicon glyphicon-music"></span> {{_('Listen in browser')}}
<span class="caret"></span>
</button>
<ul class="dropdown-menu" aria-labelledby="read-in-browser">
{% for format in reader_list %}
<li><a target="_blank" href="{{ url_for('web.read_book', book_id=entry.id, book_format=format) }}">{{format}}</a></li>
{%endfor%}
</ul>
<ul class="dropdown-menu" aria-labelledby="listen-in-browser">
{% for format in entry.data %}
{% 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>
{% endif %}
{% endfor %}
</ul>
</div>
{% endif %}
</div>
</div>
<h2 id="title">{{entry.title|shortentitle(40)}}</h2>
<p class="author">
{% for author in entry.authors %}
<a href="{{url_for('author', book_id=author.id ) }}">{{author.name.replace('|',',')}}</a>
<a href="{{url_for('web.books_list', data='author', sort='new', book_id=author.id ) }}">{{author.name.replace('|',',')}}</a>
{% if not loop.last %}
&amp;
{% endif %}
@@ -97,7 +114,7 @@
{% endif %}
{% if entry.series|length > 0 %}
<p>{{_('Book')}} {{entry.series_index}} {{_('of')}} <a href="{{url_for('series', book_id=entry.series[0].id)}}">{{entry.series[0].name}}</a></p>
<p>{{_('Book')}} {{entry.series_index}} {{_('of')}} <a href="{{url_for('web.books_list', data='series',sort='abc', book_id=entry.series[0].id)}}">{{entry.series[0].name}}</a></p>
{% endif %}
{% if entry.languages.__len__() > 0 %}
@@ -126,7 +143,7 @@
<span class="glyphicon glyphicon-tags"></span>
{% for tag in entry.tags %}
<a href="{{ url_for('category', book_id=tag.id) }}" class="btn btn-xs btn-info" role="button">{{tag.name}}</a>
<a href="{{ url_for('web.books_list', data='category', sort='new', book_id=tag.id) }}" class="btn btn-xs btn-info" role="button">{{tag.name}}</a>
{%endfor%}
</p>
@@ -137,7 +154,7 @@
<div class="publishers">
<p>
<span>{{_('Publisher')}}:
<a href="{{url_for('publisher', book_id=entry.publishers[0].id ) }}">{{entry.publishers[0].name}}</a>
<a href="{{url_for('web.books_list', data='publisher', sort='new', book_id=entry.publishers[0].id ) }}">{{entry.publishers[0].name}}</a>
</span>
</p>
</div>
@@ -178,7 +195,7 @@
<div class="custom_columns">
<p>
<form id="have_read_form" action="{{ url_for('toggle_read', book_id=entry.id)}}" method="POST">
<form id="have_read_form" action="{{ url_for('web.toggle_read', book_id=entry.id)}}" method="POST">
<label class="block-label">
<input id="have_read_cb" data-checked="{{_('Mark As Unread')}}" data-unchecked="{{_('Mark As Read')}}" type="checkbox" {% if have_read %}checked{% endif %} >
<span>{{_('Read')}}</span>
@@ -211,8 +228,8 @@
{% for shelf in g.user.shelf %}
{% if not shelf.id in books_shelfs and shelf.is_public != 1 %}
<li>
<a href="{{ url_for('add_to_shelf', book_id=entry.id, shelf_id=shelf.id) }}"
data-remove-href="{{ url_for('remove_from_shelf', book_id=entry.id, shelf_id=shelf.id) }}"
<a href="{{ url_for('shelf.add_to_shelf', book_id=entry.id, shelf_id=shelf.id) }}"
data-remove-href="{{ url_for('shelf.remove_from_shelf', book_id=entry.id, shelf_id=shelf.id) }}"
data-shelf-action="add"
>
{{shelf.name}}
@@ -223,8 +240,8 @@
{% for shelf in g.public_shelfes %}
{% if not shelf.id in books_shelfs %}
<li>
<a href="{{ url_for('add_to_shelf', book_id=entry.id, shelf_id=shelf.id) }}"
data-remove-href="{{ url_for('remove_from_shelf', book_id=entry.id, shelf_id=shelf.id) }}"
<a href="{{ url_for('shelf.add_to_shelf', book_id=entry.id, shelf_id=shelf.id) }}"
data-remove-href="{{ url_for('shelf.remove_from_shelf', book_id=entry.id, shelf_id=shelf.id) }}"
data-shelf-action="add"
>
{{shelf.name}}
@@ -238,8 +255,8 @@
{% if books_shelfs %}
{% for shelf in g.user.shelf %}
{% if shelf.id in books_shelfs and shelf.is_public != 1 %}
<a href="{{ url_for('remove_from_shelf', book_id=entry.id, shelf_id=shelf.id) }}"
data-add-href="{{ url_for('add_to_shelf', book_id=entry.id, shelf_id=shelf.id) }}"
<a href="{{ url_for('shelf.remove_from_shelf', book_id=entry.id, shelf_id=shelf.id) }}"
data-add-href="{{ url_for('shelf.add_to_shelf', book_id=entry.id, shelf_id=shelf.id) }}"
class="btn btn-sm btn-default" role="button" data-shelf-action="remove"
>
<span class="glyphicon glyphicon-remove"></span> {{shelf.name}}
@@ -248,8 +265,8 @@
{%endfor%}
{% for shelf in g.public_shelfes %}
{% if shelf.id in books_shelfs %}
<a href="{{ url_for('remove_from_shelf', book_id=entry.id, shelf_id=shelf.id) }}"
data-add-href="{{ url_for('add_to_shelf', book_id=entry.id, shelf_id=shelf.id) }}"
<a href="{{ url_for('shelf.remove_from_shelf', book_id=entry.id, shelf_id=shelf.id) }}"
data-add-href="{{ url_for('shelf.add_to_shelf', book_id=entry.id, shelf_id=shelf.id) }}"
class="btn btn-sm btn-default" role="button" data-shelf-action="remove"
>
<span class="glyphicon glyphicon-remove"></span> {{shelf.name}}
@@ -266,7 +283,7 @@
{% if g.user.role_edit() %}
<div class="btn-toolbar" role="toolbar">
<div class="btn-group" role="group" aria-label="Edit/Delete book">
<a href="{{ url_for('edit_book', book_id=entry.id) }}" class="btn btn-sm btn-warning" id="edit_book" role="button"><span class="glyphicon glyphicon-edit"></span> {{_('Edit metadata')}}</a>
<a href="{{ url_for('editbook.edit_book', book_id=entry.id) }}" class="btn btn-sm btn-warning" id="edit_book" role="button"><span class="glyphicon glyphicon-edit"></span> {{_('Edit metadata')}}</a>
</div>
</div>
{% endif %}
+5 -6
View File
@@ -3,18 +3,17 @@
<div class="discover load-more">
<h2>{{title}}</h2>
<div class="row">
{% for entry in entries %}
<div class="col-sm-3 col-lg-2 col-xs-6 book">
<div class="cover">
{% if entry.has_cover is defined %}
<a href="{{ url_for('show_book', book_id=entry.id) }}" data-toggle="modal" data-target="#bookDetailsModal" data-remote="false">
<img src="{{ url_for('get_cover', book_id=entry.id) }}" alt="{{ entry.title }}" />
<a href="{{ url_for('web.show_book', book_id=entry.id) }}" data-toggle="modal" data-target="#bookDetailsModal" data-remote="false">
<img src="{{ url_for('web.get_cover', book_id=entry.id) }}" alt="{{ entry.title }}" />
</a>
{% endif %}
</div>
<div class="meta">
<a href="{{ url_for('show_book', book_id=entry.id) }}" data-toggle="modal" data-target="#bookDetailsModal" data-remote="false">
<a href="{{ url_for('web.show_book', book_id=entry.id) }}" data-toggle="modal" data-target="#bookDetailsModal" data-remote="false">
<p class="title">{{entry.title|shortentitle}}</p>
</a>
<p class="author">
@@ -23,7 +22,7 @@
{% if not loop.first %}
<span class="author-hidden-divider">&amp;</span>
{% endif %}
<a class="author-name author-hidden" href="{{url_for('author', book_id=author.id) }}">{{author.name.replace('|',',')|shortentitle(30)}}</a>
<a class="author-name author-hidden" href="{{url_for('web.books_list', data='author', sort='new', book_id=author.id) }}">{{author.name.replace('|',',')|shortentitle(30)}}</a>
{% if loop.last %}
<a href="#" class="author-expand" data-authors-max="{{g.config_authors_max}}" data-collapse-caption="({{_('reduce')}})">(...)</a>
{% endif %}
@@ -31,7 +30,7 @@
{% if not loop.first %}
<span>&amp;</span>
{% endif %}
<a class="author-name" href="{{url_for('author', book_id=author.id) }}">{{author.name.replace('|',',')|shortentitle(30)}}</a>
<a class="author-name" href="{{url_for('web.books_list', data='author', sort='new', book_id=author.id) }}">{{author.name.replace('|',',')|shortentitle(30)}}</a>
{% endif %}
{% endfor %}
</p>
+4 -5
View File
@@ -37,20 +37,20 @@
</div>
<button type="submit" name="submit" value="submit" class="btn btn-default">{{_('Save settings')}}</button>
<button type="submit" name="test" value="test" class="btn btn-default">{{_('Save settings and send Test E-Mail')}}</button>
<a href="{{ url_for('admin') }}" id="back" class="btn btn-default">{{_('Back')}}</a>
<a href="{{ url_for('admin.admin') }}" id="back" class="btn btn-default">{{_('Back')}}</a>
</form>
{% if g.allow_registration %}
<h2>{{_('Allowed domains for registering')}}</h2>
<table class="table table-no-bordered" id="domain-table" data-url="{{url_for('list_domain')}}" data-id-field="id" data-show-header="false" data-editable-mode="inline">
<table class="table table-no-bordered" id="domain-table" data-url="{{url_for('admin.list_domain')}}" data-id-field="id" data-show-header="false" data-editable-mode="inline">
<thead>
<tr>
<th data-field="domain" id="domain" data-editable-type="text" data-editable-url="{{ url_for('edit_domain')}}" data-editable="true" data-editable-title="{{_('Enter domainname')}}"></th>
<th data-field="domain" id="domain" data-editable-type="text" data-editable-url="{{ url_for('admin.edit_domain')}}" data-editable="true" data-editable-title="{{_('Enter domainname')}}"></th>
<th data-field="id" id="id" data-visible="false"></th>
<th data-align="right" data-formatter="TableActions"></th>
</tr>
</thead>
</table>
<form id="domain_add" action="{{ url_for('add_domain')}}" method="POST">
<form id="domain_add" action="{{ url_for('admin.add_domain')}}" method="POST">
<div class="form-group required">
<label for="domainname">{{_('Add Domain')}}</label>
<input type="text" class="form-control" name="domainname" id="domainname" >
@@ -71,7 +71,6 @@
<div class="modal-body text-center">
<p>{{_('Do you really want to delete this domain rule?')}}</p>
<button type="button" class="btn btn-danger" id="btndeletedomain" >{{_('Delete')}}</button>
<!--a href="{{ url_for('delete_domain')}}" class="btn btn-danger">{{_('Delete')}}</a-->
<button type="button" class="btn btn-default" data-dismiss="modal">{{_('Back')}}</button>
</div>
</div>
+7 -7
View File
@@ -6,10 +6,10 @@
href="{{request.script_root + request.full_path}}"
type="application/atom+xml;profile=opds-catalog;type=feed;kind=navigation"/>
<link rel="start"
href="{{url_for('feed_index')}}"
href="{{url_for('opds.feed_index')}}"
type="application/atom+xml;profile=opds-catalog;type=feed;kind=navigation"/>
<link rel="up"
href="{{url_for('feed_index')}}"
href="{{url_for('opds.feed_index')}}"
type="application/atom+xml;profile=opds-catalog;type=feed;kind=navigation"/>
{% if pagination.has_prev %}
<link rel="first"
@@ -28,9 +28,9 @@
type="application/atom+xml;profile=opds-catalog;type=feed;kind=navigation"/>
{% endif %}
<link rel="search"
href="{{url_for('feed_osd')}}"
href="{{url_for('opds.feed_osd')}}"
type="application/opensearchdescription+xml"/>
<!--link title="{{_('Search')}}" type="application/atom+xml" href="{{url_for('feed_normal_search')}}?query={searchTerms}" rel="search"/-->
<!--link title="{{_('Search')}}" type="application/atom+xml" href="{{url_for('opds.feed_normal_search')}}?query={searchTerms}" rel="search"/-->
<title>{{instance}}</title>
<author>
<name>{{instance}}</name>
@@ -61,11 +61,11 @@
{% endfor %}
{% if entry.comments[0] %}<summary>{{entry.comments[0].text|striptags}}</summary>{% endif %}
{% if entry.has_cover %}
<link type="image/jpeg" href="{{url_for('feed_get_cover', book_id=entry.id)}}" rel="http://opds-spec.org/image"/>
<link type="image/jpeg" href="{{url_for('feed_get_cover', book_id=entry.id)}}" rel="http://opds-spec.org/image/thumbnail"/>
<link type="image/jpeg" href="{{url_for('opds.feed_get_cover', book_id=entry.id)}}" rel="http://opds-spec.org/image"/>
<link type="image/jpeg" href="{{url_for('opds.feed_get_cover', book_id=entry.id)}}" rel="http://opds-spec.org/image/thumbnail"/>
{% endif %}
{% for format in entry.data %}
<link rel="http://opds-spec.org/acquisition" href="{{ url_for('get_opds_download_link', book_id=entry.id, book_format=format.format|lower)}}"
<link rel="http://opds-spec.org/acquisition" href="{{ url_for('web.download_link', book_id=entry.id, book_format=format.format|lower)}}"
length="{{format.uncompressed_size}}" mtime="{{entry.atom_timestamp}}" type="{{format.format|lower|mimetype}}"/>
{% endfor %}
</entry>
+2 -2
View File
@@ -17,10 +17,10 @@
{% endif %}
</head>
<body>
<div class="container text-center">
<div class="text-center">
<h1>{{ error_code }}</h1>
<h3>{{ error_name }}</h3>
<a href="{{url_for('index')}}" title="{{ _('Back to home') }}">{{_('Back to home')}}</a>
<a href="{{url_for('web.index')}}" title="{{ _('Back to home') }}">{{_('Back to home')}}</a>
</div>
</body>
</html>
+28 -20
View File
@@ -4,20 +4,15 @@
<div class="discover random-books">
<h2 class="random-books">{{_('Discover (Random Books)')}}</h2>
<div class="row">
{% for entry in random %}
{% for entry in random %}
<div class="col-sm-3 col-lg-2 col-xs-6 book" id="books_rand">
<div class="cover">
<a href="{{ url_for('show_book', book_id=entry.id) }}" data-toggle="modal" data-target="#bookDetailsModal" data-remote="false">
{% if entry.has_cover %}
<img src="{{ url_for('get_cover', book_id=entry.id) }}" alt="{{ entry.title }}" />
{% else %}
<img src="{{ url_for('static', filename='generic_cover.jpg') }}" alt="{{ entry.title }}" />
{% endif %}
<a href="{{ url_for('web.show_book', book_id=entry.id) }}" data-toggle="modal" data-target="#bookDetailsModal" data-remote="false">
<img src="{{ url_for('web.get_cover', book_id=entry.id) }}" alt="{{ entry.title }}" />
</a>
</div>
<div class="meta">
<a href="{{ url_for('show_book', book_id=entry.id) }}" data-toggle="modal" data-target="#bookDetailsModal" data-remote="false">
<a href="{{ url_for('web.show_book', book_id=entry.id) }}" data-toggle="modal" data-target="#bookDetailsModal" data-remote="false">
<p class="title">{{entry.title|shortentitle}}</p>
</a>
<p class="author">
@@ -26,7 +21,7 @@
{% if not loop.first %}
<span class="author-hidden-divider">&amp;</span>
{% endif %}
<a class="author-name author-hidden" href="{{url_for('author', book_id=author.id) }}">{{author.name.replace('|',',')|shortentitle(30)}}</a>
<a class="author-name author-hidden" href="{{url_for('web.books_list', data='author', sort='new', book_id=author.id) }}">{{author.name.replace('|',',')|shortentitle(30)}}</a>
{% if loop.last %}
<a href="#" class="author-expand" data-authors-max="{{g.config_authors_max}}" data-collapse-caption="({{_('reduce')}})">(...)</a>
{% endif %}
@@ -34,7 +29,7 @@
{% if not loop.first %}
<span>&amp;</span>
{% endif %}
<a class="author-name" href="{{url_for('author', book_id=author.id) }}">{{author.name.replace('|',',')|shortentitle(30)}}</a>
<a class="author-name" href="{{url_for('web.books_list', data='author', sort='new', book_id=author.id) }}">{{author.name.replace('|',',')|shortentitle(30)}}</a>
{% endif %}
{% endfor %}
</p>
@@ -58,21 +53,29 @@
{% endif %}
<div class="discover load-more">
<h2 class="{{title}}">{{_(title)}}</h2>
<div class="filterheader hidden-xs hidden-sm">
<a data-toggle="tooltip" id="new" class="btn btn-primary" href="{{url_for('web.books_list', data=page, book_id=id, sort='new')}}"><span class="glyphicon glyphicon-book"></span> <span class="glyphicon glyphicon-calendar"></span><span class="glyphicon glyphicon-sort-by-order"></span></a>
<a id="old" class="btn btn-primary" href="{{url_for('web.books_list', data=page, book_id=id, sort='old')}}"><span class="glyphicon glyphicon-book"></span> <span class="glyphicon glyphicon-calendar"></span><span class="glyphicon glyphicon-sort-by-order-alt"></span></a>
<a id="asc" class="btn btn-primary" href="{{url_for('web.books_list', data=page, book_id=id, sort='abc')}}"><span class="glyphicon glyphicon-font"></span><span class="glyphicon glyphicon-sort-by-alphabet"></span></a>
<a id="desc" class="btn btn-primary" href="{{url_for('web.books_list', data=page, book_id=id, sort='zyx')}}"><span class="glyphicon glyphicon-font"></span><span class="glyphicon glyphicon-sort-by-alphabet-alt"></span></a>
<a id="pub_new" class="btn btn-primary" href="{{url_for('web.books_list', data=page, book_id=id, sort='pubnew')}}"><span class="glyphicon glyphicon-calendar"></span><span class="glyphicon glyphicon-sort-by-order"></span></a>
<a id="pub_old" class="btn btn-primary" href="{{url_for('web.books_list', data=page, book_id=id, sort='pubold')}}"><span class="glyphicon glyphicon-calendar"></span><span class="glyphicon glyphicon-sort-by-order-alt"></span></a>
<!--div class="btn-group character">
<a id="no_shelf" class="btn btn-primary" href="{{url_for('web.books_list', data=page, book_id=id, sort='pubold')}}"><span class="glyphicon glyphicon-list"></span> <b>{{_('Group by series')}}</b></a>
</div-->
</div>
<div class="row">
{% if entries[0] %}
{% for entry in entries %}
<div class="col-sm-3 col-lg-2 col-xs-6 book" id="books">
<div class="cover">
<a href="{{ url_for('show_book', book_id=entry.id) }}" data-toggle="modal" data-target="#bookDetailsModal" data-remote="false">
{% if entry.has_cover %}
<img src="{{ url_for('get_cover', book_id=entry.id) }}" alt="{{ entry.title }}"/>
{% else %}
<img src="{{ url_for('static', filename='generic_cover.jpg') }}" alt="{{ entry.title }}" />
{% endif %}
<a href="{{ url_for('web.show_book', book_id=entry.id) }}" data-toggle="modal" data-target="#bookDetailsModal" data-remote="false">
<img src="{{ url_for('web.get_cover', book_id=entry.id) }}" alt="{{ entry.title }}"/>
</a>
</div>
<div class="meta">
<a href="{{ url_for('show_book', book_id=entry.id) }}" data-toggle="modal" data-target="#bookDetailsModal" data-remote="false">
<a href="{{ url_for('web.show_book', book_id=entry.id) }}" data-toggle="modal" data-target="#bookDetailsModal" data-remote="false">
<p class="title">{{entry.title|shortentitle}}</p>
</a>
<p class="author">
@@ -81,7 +84,7 @@
{% if not loop.first %}
<span class="author-hidden-divider">&amp;</span>
{% endif %}
<a class="author-name author-hidden" href="{{url_for('author', book_id=author.id) }}">{{author.name.replace('|',',')|shortentitle(30)}}</a>
<a class="author-name author-hidden" href="{{url_for('web.books_list', data='author', book_id=author.id, sort='new') }}">{{author.name.replace('|',',')|shortentitle(30)}}</a>
{% if loop.last %}
<a href="#" class="author-expand" data-authors-max="{{g.config_authors_max}}" data-collapse-caption="({{_('reduce')}})">(...)</a>
{% endif %}
@@ -89,9 +92,14 @@
{% if not loop.first %}
<span>&amp;</span>
{% endif %}
<a class="author-name" href="{{url_for('author', book_id=author.id) }}">{{author.name.replace('|',',')|shortentitle(30)}}</a>
<a class="author-name" href="{{url_for('web.books_list', data='author', book_id=author.id, sort='new') }}">{{author.name.replace('|',',')|shortentitle(30)}}</a>
{% endif %}
{% endfor %}
{% for format in entry.data %}
{% if format.format|lower == 'mp3' %}
<span class="glyphicon glyphicon-music"></span>
{% endif %}
{%endfor%}
</p>
{% if entry.ratings.__len__() > 0 %}
<div class="rating">
+28 -29
View File
@@ -2,13 +2,12 @@
<feed xmlns="http://www.w3.org/2005/Atom">
<id>urn:uuid:2853dacf-ed79-42f5-8e8a-a7bb3d1ae6a2</id>
<updated>{{ current_time }}</updated>
<link rel="self" href="{{url_for('feed_index')}}" type="application/atom+xml;profile=opds-catalog;kind=navigation"/>
<link rel="start" title="{{_('Start')}}" href="{{url_for('feed_index')}}"
<link rel="self" href="{{url_for('opds.feed_index')}}" type="application/atom+xml;profile=opds-catalog;kind=navigation"/>
<link rel="start" title="{{_('Start')}}" href="{{url_for('opds.feed_index')}}"
type="application/atom+xml;profile=opds-catalog;kind=navigation"/>
<link rel="search"
href="{{url_for('feed_osd')}}"
href="{{url_for('opds.feed_osd')}}"
type="application/opensearchdescription+xml"/>
<!--link title="{{_('Search')}}" type="application/atom+xml" href="{{url_for('feed_normal_search')}}?query={searchTerms}" rel="search"/-->
<title>{{instance}}</title>
<author>
<name>{{instance}}</name>
@@ -16,88 +15,88 @@
</author>
<entry>
<title>{{_('Hot Books')}}</title>
<link rel="http://opds-spec.org/sort/popular" href="{{url_for('feed_hot')}}" type="application/atom+xml;profile=opds-catalog"/>
<id>{{url_for('feed_hot')}}</id>
<link rel="http://opds-spec.org/sort/popular" href="{{url_for('opds.feed_hot')}}" type="application/atom+xml;profile=opds-catalog"/>
<id>{{url_for('opds.feed_hot')}}</id>
<updated>{{ current_time }}</updated>
<content type="text">{{_('Popular publications from this catalog based on Downloads.')}}</content>
</entry>
<entry>
<title>{{_('Best rated Books')}}</title>
<link rel="http://opds-spec.org/recommended" href="{{url_for('feed_best_rated')}}" type="application/atom+xml;profile=opds-catalog"/>
<id>{{url_for('feed_best_rated')}}</id>
<link rel="http://opds-spec.org/recommended" href="{{url_for('opds.feed_best_rated')}}" type="application/atom+xml;profile=opds-catalog"/>
<id>{{url_for('opds.feed_best_rated')}}</id>
<updated>{{ current_time }}</updated>
<content type="text">{{_('Popular publications from this catalog based on Rating.')}}</content>
</entry>
<entry>
<title>{{_('New Books')}}</title>
<link rel="http://opds-spec.org/sort/new" href="{{url_for('feed_new')}}" type="application/atom+xml;profile=opds-catalog"/>
<id>{{url_for('feed_new')}}</id>
<link rel="http://opds-spec.org/sort/new" href="{{url_for('opds.feed_new')}}" type="application/atom+xml;profile=opds-catalog"/>
<id>{{url_for('opds.feed_new')}}</id>
<updated>{{ current_time }}</updated>
<content type="text">{{_('The latest Books')}}</content>
</entry>
<entry>
<title>{{_('Random Books')}}</title>
<link rel="http://opds-spec.org/featured" href="{{url_for('feed_discover')}}" type="application/atom+xml;profile=opds-catalog"/>
<id>{{url_for('feed_discover')}}</id>
<link rel="http://opds-spec.org/featured" href="{{url_for('opds.feed_discover')}}" type="application/atom+xml;profile=opds-catalog"/>
<id>{{url_for('opds.feed_discover')}}</id>
<updated>{{ current_time }}</updated>
<content type="text">{{_('Show Random Books')}}</content>
</entry>
{% if not current_user.is_anonymous %}
<entry>
<title>{{_('Read Books')}}</title>
<link rel="subsection" href="{{url_for('feed_read_books')}}" type="application/atom+xml;profile=opds-catalog"/>
<id>{{url_for('feed_read_books')}}</id>
<link rel="subsection" href="{{url_for('opds.feed_read_books')}}" type="application/atom+xml;profile=opds-catalog"/>
<id>{{url_for('opds.feed_read_books')}}</id>
<updated>{{ current_time }}</updated>
<content type="text">{{_('Read Books')}}</content>
</entry>
{% endif %}
<entry>
<title>{{_('Unread Books')}}</title>
<link rel="subsection" href="{{url_for('feed_unread_books')}}" type="application/atom+xml;profile=opds-catalog"/>
<id>{{url_for('feed_unread_books')}}</id>
<link rel="subsection" href="{{url_for('opds.feed_unread_books')}}" type="application/atom+xml;profile=opds-catalog"/>
<id>{{url_for('opds.feed_unread_books')}}</id>
<updated>{{ current_time }}</updated>
<content type="text">{{_('Unread Books')}}</content>
</entry>
{% endif %}
<entry>
<title>{{_('Authors')}}</title>
<link rel="subsection" href="{{url_for('feed_authorindex')}}" type="application/atom+xml;profile=opds-catalog"/>
<id>{{url_for('feed_authorindex')}}</id>
<link rel="subsection" href="{{url_for('opds.feed_authorindex')}}" type="application/atom+xml;profile=opds-catalog"/>
<id>{{url_for('opds.feed_authorindex')}}</id>
<updated>{{ current_time }}</updated>
<content type="text">{{_('Books ordered by Author')}}</content>
</entry>
<entry>
<title>{{_('Publishers')}}</title>
<link rel="subsection" href="{{url_for('feed_publisherindex')}}" type="application/atom+xml;profile=opds-catalog"/>
<id>{{url_for('feed_publisherindex')}}</id>
<link rel="subsection" 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>
<entry>
<title>{{_('Category list')}}</title>
<link rel="subsection" href="{{url_for('feed_categoryindex')}}" type="application/atom+xml;profile=opds-catalog"/>
<id>{{url_for('feed_categoryindex')}}</id>
<link rel="subsection" href="{{url_for('opds.feed_categoryindex')}}" type="application/atom+xml;profile=opds-catalog"/>
<id>{{url_for('opds.feed_categoryindex')}}</id>
<updated>{{ current_time }}</updated>
<content type="text">{{_('Books ordered by category')}}</content>
</entry>
<entry>
<title>{{_('Series list')}}</title>
<link rel="subsection" href="{{url_for('feed_seriesindex')}}" type="application/atom+xml;profile=opds-catalog"/>
<id>{{url_for('feed_seriesindex')}}</id>
<link rel="subsection" href="{{url_for('opds.feed_seriesindex')}}" type="application/atom+xml;profile=opds-catalog"/>
<id>{{url_for('opds.feed_seriesindex')}}</id>
<updated>{{ current_time }}</updated>
<content type="text">{{_('Books ordered by series')}}</content>
</entry>
<entry>
<title>{{_('Public Shelves')}}</title>
<link rel="subsection" href="{{url_for('feed_shelfindex', public="public")}}" type="application/atom+xml;profile=opds-catalog"/>
<id>{{url_for('feed_shelfindex', public="public")}}</id>
<link rel="subsection" href="{{url_for('opds.feed_shelfindex', public="public")}}" type="application/atom+xml;profile=opds-catalog"/>
<id>{{url_for('opds.feed_shelfindex', public="public")}}</id>
<updated>{{ current_time }}</updated>
<content type="text">{{_('Books organized in public shelfs, visible to everyone')}}</content>
</entry>
{% if not current_user.is_anonymous %}
<entry>
<title>{{_('Your Shelves')}}</title>
<link rel="subsection" href="{{url_for('feed_shelfindex')}}" type="application/atom+xml;profile=opds-catalog"/>
<id>{{url_for('feed_shelfindex')}}</id>
<link rel="subsection" href="{{url_for('opds.feed_shelfindex')}}" type="application/atom+xml;profile=opds-catalog"/>
<id>{{url_for('opds.feed_shelfindex')}}</id>
<updated>{{ current_time }}</updated>
<content type="text">{{_("User's own shelfs, only visible to the current user himself")}}</content>
</entry>
+26 -26
View File
@@ -1,53 +1,53 @@
{
"pubdate": "{{entry.pubdate}}",
"title": "{{entry.title}}",
"pubdate": "{{entry.pubdate}}",
"title": "{{entry.title}}",
"format_metadata": {
{% for format in entry.data %}
{% for format in entry.data %}
"{{format.format}}": {
"mtime": "{{entry.last_modified}}",
"size": {{format.uncompressed_size}},
"mtime": "{{entry.last_modified}}",
"size": {{format.uncompressed_size}},
"path": ""
}{% if not loop.last %},{% endif %}
{% endfor %}
},
},
"formats": [
{% for format in entry.data %}
{% for format in entry.data %}
"{{format.format}}"{% if not loop.last %},{% endif %}
{% endfor %}
],
"series": null,
"cover": "{{url_for('feed_get_cover', book_id=entry.id)}}",
{% endfor %}
],
"series": null,
"cover": "{{url_for('opds.feed_get_cover', book_id=entry.id)}}",
"languages": [
{% for lang in entry.languages %}
{% for lang in entry.languages %}
"{{lang.lang_code}}"{% if not loop.last %},{% endif %}
{% endfor %}
],
],
"comments": "{% if entry.comments|length > 0 %}{{entry.comments[0].text.replace('"', '\\"')|safe}}{% endif %}",
"tags": [
{% for tag in entry.tags %}
"{{tag.name}}"{% if not loop.last %},{% endif %}
{% endfor %}
],
"application_id": {{entry.id}},
"series_index": {% if entry.series|length > 0 %}"{{entry.series_index}}"{% else %}null{% endif %},
"last_modified": "{{entry.last_modified}}",
"author_sort": "{{entry.author_sort}}",
"uuid": "{{entry.uuid}}",
"timestamp": "{{entry.timestamp}}",
"thumbnail": "{{url_for('feed_get_cover', book_id=entry.id)}}",
{% endfor %}
],
"application_id": {{entry.id}},
"series_index": {% if entry.series|length > 0 %}"{{entry.series_index}}"{% else %}null{% endif %},
"last_modified": "{{entry.last_modified}}",
"author_sort": "{{entry.author_sort}}",
"uuid": "{{entry.uuid}}",
"timestamp": "{{entry.timestamp}}",
"thumbnail": "{{url_for('opds.feed_get_cover', book_id=entry.id)}}",
"main_format": {
"{{entry.data[0].format|lower}}": "{{ url_for('get_opds_download_link', book_id=entry.id, book_format=entry.data[0].format|lower)}}"
"{{entry.data[0].format|lower}}": "{{ url_for('web.download_link', book_id=entry.id, book_format=entry.data[0].format|lower)}}"
},
"rating":{% if entry.ratings.__len__() > 0 %} "{{entry.ratings[0].rating}}.0"{% else %}0.0{% endif %},
"authors": [
{% for author in entry.authors %}
"{{author.name.replace('|',',')}}"{% if not loop.last %},{% endif %}
{% endfor %}
],
{% endfor %}
],
"other_formats": {
{% if entry.data.__len__() > 1 %}
{% for format in entry.data[1:] %}
"{{format.format|lower}}": "{{ url_for('get_opds_download_link', book_id=entry.id, book_format=format.format|lower)}}"{% if not loop.last %},{% endif %}
"{{format.format|lower}}": "{{ url_for('web.download_link', book_id=entry.id, book_format=format.format|lower)}}"{% if not loop.last %},{% endif %}
{% endfor %}
{% endif %} },
"title_sort": "{{entry.sort}}"
+1 -1
View File
@@ -10,7 +10,7 @@
{% endif %}
<div class="row">
<div class="col-xs-2 col-sm-2 col-md-1" align="left"><span class="badge">{{lang_counter[loop.index0].bookcount}}</span></div>
<div class="col-xs-10 col-sm-10 col-md-11"><a id="list_{{loop.index0}}" href="{{url_for('language', name=lang.lang_code)}}">{{lang.name}}</a></div>
<div class="col-xs-10 col-sm-10 col-md-11"><a id="list_{{loop.index0}}" href="{{url_for('web.language', name=lang.lang_code)}}">{{lang.name}}</a></div>
</div>
{% endfor %}
</div>
+27 -66
View File
@@ -36,10 +36,10 @@
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="{{url_for('index')}}">{{instance}}</a>
<a class="navbar-brand" href="{{url_for('web.index')}}">{{instance}}</a>
</div>
{% if g.user.is_authenticated or g.user.is_anonymous %}
<form class="navbar-form navbar-left" role="search" action="{{url_for('search')}}" method="GET">
{% if g.user.is_authenticated or g.allow_anonymous %}
<form class="navbar-form navbar-left" role="search" action="{{url_for('web.search')}}" method="GET">
<div class="form-group input-group input-group-sm">
<label for="query" class="sr-only">{{_('Search')}}</label>
<input type="text" class="form-control" id="query" name="query" placeholder="{{_('Search')}}">
@@ -50,17 +50,17 @@
</form>
{% endif %}
<div class="navbar-collapse collapse">
{% if g.user.is_authenticated or g.user.is_anonymous %}
{% if g.user.is_authenticated or g.allow_anonymous %}
<ul class="nav navbar-nav ">
<li><a href="{{url_for('advanced_search')}}"><span class="glyphicon glyphicon-search"></span><span class="hidden-sm"> {{_('Advanced Search')}}</span></a></li>
<li><a href="{{url_for('web.advanced_search')}}"><span class="glyphicon glyphicon-search"></span><span class="hidden-sm"> {{_('Advanced Search')}}</span></a></li>
</ul>
{% endif %}
<ul class="nav navbar-nav navbar-right" id="main-nav">
{% if g.user.is_authenticated or g.user.is_anonymous %}
{% if g.user.is_authenticated or g.allow_anonymous %}
{% if g.user.role_upload() or g.user.role_admin()%}
{% if g.allow_upload %}
<li>
<form id="form-upload" class="navbar-form" action="{{ url_for('upload') }}" method="post" enctype="multipart/form-data">
<form id="form-upload" class="navbar-form" action="{{ url_for('editbook.upload') }}" method="post" enctype="multipart/form-data">
<div class="form-group">
<span class="btn btn-default btn-file">{{_('Upload')}}<input id="btn-upload" name="btn-upload"
type="file" accept="{% for format in accept %}.{{format}}{{ ',' if not loop.last }}{% endfor %}" multiple></span>
@@ -70,19 +70,19 @@
{% endif %}
{% endif %}
{% if not g.user.is_anonymous %}
<li><a id="top_tasks" href="{{url_for('get_tasks_status')}}"><span class="glyphicon glyphicon-tasks"></span><span class="hidden-sm">{{_('Tasks')}}</span></a></li>
<li><a id="top_tasks" href="{{url_for('web.get_tasks_status')}}"><span class="glyphicon glyphicon-tasks"></span><span class="hidden-sm">{{_('Tasks')}}</span></a></li>
{% endif %}
{% if g.user.role_admin() %}
<li><a id="top_admin" data-text="{{_('Settings')}}" href="{{url_for('admin')}}"><span class="glyphicon glyphicon-dashboard"></span><span class="hidden-sm">{{_('Admin')}}</span></a></li>
<li><a id="top_admin" data-text="{{_('Settings')}}" href="{{url_for('admin.admin')}}"><span class="glyphicon glyphicon-dashboard"></span><span class="hidden-sm">{{_('Admin')}}</span></a></li>
{% endif %}
<li><a id="top_user" data-text="{{_('Account')}}" href="{{url_for('profile')}}"><span class="glyphicon glyphicon-user"></span><span class="hidden-sm">{{g.user.nickname}}</span></a></li>
<li><a id="top_user" data-text="{{_('Account')}}" href="{{url_for('web.profile')}}"><span class="glyphicon glyphicon-user"></span><span class="hidden-sm">{{g.user.nickname}}</span></a></li>
{% if not g.user.is_anonymous %}
<li><a id="logout" href="{{url_for('logout')}}"><span class="glyphicon glyphicon-log-out"></span><span class="hidden-sm">{{_('Logout')}}</span></a></li>
<li><a id="logout" href="{{url_for('web.logout')}}"><span class="glyphicon glyphicon-log-out"></span><span class="hidden-sm">{{_('Logout')}}</span></a></li>
{% endif %}
{% endif %}
{% if g.allow_registration and not g.user.is_authenticated %}
<li><a id="login" href="{{url_for('login')}}"><span class="glyphicon glyphicon-log-in"></span> {{_('Login')}}</a></li>
<li><a id="register" href="{{url_for('register')}}"><span class="glyphicon glyphicon-user"></span> {{_('Register')}}</a></li>
<li><a id="login" href="{{url_for('web.login')}}"><span class="glyphicon glyphicon-log-in"></span> {{_('Login')}}</a></li>
<li><a id="register" href="{{url_for('web.register')}}"><span class="glyphicon glyphicon-user"></span> {{_('Register')}}</a></li>
{% endif %}
</ul>
</div><!--/.nav-collapse -->
@@ -115,70 +115,31 @@
{%endif%}
<div class="container-fluid">
<div class="row-fluid">
{% if g.user.is_authenticated or g.user.is_anonymous %}
{% if g.user.is_authenticated or g.allow_anonymous %}
<div class="col-sm-2">
<nav class="navigation">
<ul class="list-unstyled" id="scnd-nav" intent in-standard-append="nav.navigation" in-mobile-after="#main-nav" in-mobile-class="nav navbar-nav">
<li class="nav-head hidden-xs">{{_('Browse')}}</li>
{% if g.user.show_recent() %}
<li id="nav_new" {% if page == 'root' %}class="active"{% endif %}><a href="{{url_for('index')}}"><span class="glyphicon glyphicon-book"></span> {{_('Recently Added')}}</a></li>
{% if g.user.check_visibility(1024) %} <!-- ToDo: eliminate -->
{%endif%}
{% if g.user.show_sorted() %}
<li id="nav_sort" class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
<span class="glyphicon glyphicon-sort-by-attributes"></span>{{_('Sorted Books')}}
<span class="caret"></span>
</a>
<ul class="dropdown-menu">
<li id="nav_sort_old" {% if page == 'newest' %}class="active"{% endif %}><a href="{{url_for('newest_books')}}">{{_('Sort By')}} {{_('Newest')}}</a></li>
<li id="nav_sort_new" {% if page == 'oldest' %}class="active"{% endif %}><a href="{{url_for('oldest_books')}}">{{_('Sort By')}} {{_('Oldest')}}</a></li>
<li id="nav_sort_asc" {% if page == 'a-z' %}class="active"{% endif %}><a href="{{url_for('titles_ascending')}}">{{_('Sort By')}} {{_('Title')}} ({{_('Ascending')}})</a></li>
<li id="nav_sort_desc" {% if page == 'z-a' %}class="active"{% endif %}><a href="{{url_for('titles_descending')}}">{{_('Sort By')}} {{_('Title')}} ({{_('Descending')}})</a></li>
</ul>
</li>
{%endif%}
{% if g.user.show_hot_books() %}
<li id="nav_hot" {% if page == 'hot' %}class="active"{% endif %}><a href="{{url_for('hot_books')}}"><span class="glyphicon glyphicon-fire"></span>{{_('Hot Books')}}</a></li>
{%endif%}
{% if g.user.show_best_rated_books() %}
<li id="nav_rated" {% if page == 'rated' %}class="active"{% endif %}><a href="{{url_for('best_rated_books')}}"><span class="glyphicon glyphicon-star"></span>{{_('Best rated Books')}}</a></li>
{%endif%}
{% if g.user.show_read_and_unread() %}
{% if not g.user.is_anonymous %}
<li id="nav_read" {% if page == 'read' %}class="active"{% endif %}><a href="{{url_for('read_books')}}"><span class="glyphicon glyphicon-eye-open"></span>{{_('Read Books')}}</a></li>
{%endif%}
<li id="nav_unread" {% if page == 'read' %}class="active"{% endif %}><a href="{{url_for('unread_books')}}"><span class="glyphicon glyphicon-eye-close"></span>{{_('Unread Books')}}</a></li>
{%endif%}
{% if g.user.show_random_books() %}
<li id="nav_rand" {% if page == 'discover' %}class="active"{% endif %}><a href="{{url_for('discover')}}"><span class="glyphicon glyphicon-random"></span>{{_('Discover')}}</a></li>
{%endif%}
{% if g.user.show_category() %}
<li id="nav_cat" {% if page == 'discover' %}class="category"{% endif %}><a href="{{url_for('category_list')}}"><span class="glyphicon glyphicon-inbox"></span>{{_('Categories')}}</a></li>
{%endif%}
{% if g.user.show_series() %}
<li id="nav_serie" {% if page == 'series' %}class="active"{% endif %}><a href="{{url_for('series_list')}}"><span class="glyphicon glyphicon-bookmark"></span>{{_('Series')}}</a></li>
{%endif%}
{% if g.user.show_author() %}
<li id="nav_author" {% if page == 'author' %}class="active"{% endif %}><a href="{{url_for('author_list')}}"><span class="glyphicon glyphicon-user"></span>{{_('Authors')}}</a></li>
{%endif%}
{% if g.user.show_publisher() %}
<li id="nav_publisher" {% if page == 'publisher' %}class="active"{% endif %}><a href="{{url_for('publisher_list')}}"><span class="glyphicon glyphicon-text-size"></span>{{_('Publishers')}}</a></li>
{%endif%}
{% if g.user.filter_language() == 'all' and g.user.show_language() %}
<li id="nav_lang" {% if page == 'language' %}class="active"{% endif %}><a href="{{url_for('language_overview')}}"><span class="glyphicon glyphicon-flag"></span>{{_('Languages')}} </a></li>
{%endif%}
{% if g.user.is_authenticated or g.user.is_anonymous %}
{% for element in sidebar %}
{% if g.user.check_visibility(element['visibility']) and element['public'] %}
<li id="nav_{{element['id']}}" {% if page == element['page'] %}class="active"{% endif %}><a href="{{url_for(element['link'], data=element['page'], sort='new')}}"><span class="glyphicon {{element['glyph']}}"></span>{{_(element['text'])}}</a></li>
{% endif %}
{% endfor %}
{% if g.user.is_authenticated or allow_anonymous %}
<li class="nav-head hidden-xs public-shelves">{{_('Public Shelves')}}</li>
{% for shelf in g.public_shelfes %}
<li><a href="{{url_for('show_shelf', shelf_id=shelf.id)}}"><span class="glyphicon glyphicon-list public_shelf"></span>{{shelf.name|shortentitle(40)}}</a></li>
<li><a href="{{url_for('shelf.show_shelf', shelf_id=shelf.id)}}"><span class="glyphicon glyphicon-list public_shelf"></span>{{shelf.name|shortentitle(40)}}</a></li>
{% endfor %}
<li class="nav-head hidden-xs your-shelves">{{_('Your Shelves')}}</li>
{% for shelf in g.user.shelf %}
<li><a href="{{url_for('show_shelf', shelf_id=shelf.id)}}"><span class="glyphicon glyphicon-list private_shelf"></span>{{shelf.name|shortentitle(40)}}</a></li>
<li><a href="{{url_for('shelf.show_shelf', shelf_id=shelf.id)}}"><span class="glyphicon glyphicon-list private_shelf"></span>{{shelf.name|shortentitle(40)}}</a></li>
{% endfor %}
{% if not g.user.is_anonymous %}
<li id="nav_createshelf" class="create-shelf"><a href="{{url_for('create_shelf')}}">{{_('Create a Shelf')}}</a></li>
<li id="nav_about" {% if page == 'stat' %}class="active"{% endif %}><a href="{{url_for('stats')}}"><span class="glyphicon glyphicon-info-sign"></span>{{_('About')}}</a></li>
<li id="nav_createshelf" class="create-shelf"><a href="{{url_for('shelf.create_shelf')}}">{{_('Create a Shelf')}}</a></li>
<li id="nav_about" {% if page == 'stat' %}class="active"{% endif %}><a href="{{url_for('about.stats')}}"><span class="glyphicon glyphicon-info-sign"></span>{{_('About')}}</a></li>
{% endif %}
{% endif %}
@@ -252,7 +213,7 @@
<script type="text/javascript">
$(function() {
$("#form-upload").uploadprogress({
redirect_url: "{{ url_for('index')}}",
redirect_url: "{{ url_for('web.index')}}",
uploadedMsg: "{{_('Upload done, processing, please wait...')}}",
modalTitle: "{{_('Uploading...')}}",
modalFooter: "{{_('Close')}}",
+46 -9
View File
@@ -1,18 +1,55 @@
{% extends "layout.html" %}
{% block body %}
<h1 class="{{page}}">{{_(title)}}</h1>
<div class="container">
<div class="col-xs-12 col-sm-6">
{% for entry in entries %}
{% if loop.index0 == (loop.length/2)|int and loop.length > 20 %}
</div>
<div class="col-xs-12 col-sm-6">
<div class="filterheader hidden-xs hidden-sm">
{% if entries.__len__ %}
{% if entries[0][0].sort %}
<button id="sort_name" class="btn btn-success"><b>B,A <-> A B</b></button>
{% endif %}
{% endif %}
<div class="row">
<button id="desc" class="btn btn-success"><span class="glyphicon glyphicon-sort-by-alphabet"></span></button>
<button id="asc" class="btn btn-success"><span class="glyphicon glyphicon-sort-by-alphabet-alt"></span></button>
{% if charlist|length %}
<button id="all" class="btn btn-success">{{_('All')}}</button>
{% endif %}
<div class="btn-group character" role="group">
{% for char in charlist%}
<button class="btn btn-success char">{{char.char}}</button>
{% endfor %}
</div>
</div>
<div class="container">
<div id="list" class="col-xs-12 col-sm-6">
{% for entry in entries %}
{% if loop.index0 == (loop.length/2+loop.length%2)|int and loop.length > 20 %}
</div>
<div id="second" class="col-xs-12 col-sm-6">
{% endif %}
<div class="row" {% if entry[0].sort %}data-name="{{entry[0].name}}"{% endif %} data-id="{% if entry[0].sort %}{{entry[0].sort}}{% else %}{% if entry.name %}{{entry.name}}{% else %}{{entry[0].name}}{% endif %}{% endif %}">
<div class="col-xs-2 col-sm-2 col-md-1" align="left"><span class="badge">{{entry.count}}</span></div>
<div class="col-xs-10 col-sm-10 col-md-11"><a id="list_{{loop.index0}}" href="{{url_for(folder, book_id=entry[0].id )}}">{{entry[0].name}}</a></div>
<div class="col-xs-10 col-sm-10 col-md-11"><a id="list_{{loop.index0}}" href="{% if entry.format %}{{url_for('web.books_list', data=data, sort='new', book_id=entry.format )}}{% else %}{{url_for('web.books_list', data=data, sort='new', book_id=entry[0].id )}}{% endif %}">
{% if entry.name %}
<div class="rating">
{% for number in range(entry.name) %}
<span class="glyphicon glyphicon-star good"></span>
{% if loop.last and loop.index < 5 %}
{% for numer in range(5 - loop.index) %}
<span class="glyphicon glyphicon-star"></span>
{% endfor %}
{% endif %}
{% endfor %}
</div>
{% else %}
{% if entry.format %}
{{entry.format}}
{% else %}
{{entry[0].name}}{% endif %}{% endif %}</a></div>
</div>
{% endfor %}
</div>
</div>
</div>
{% endblock %}
{% block js %}
<script src="{{ url_for('static', filename='js/filter_list.js') }}"></script>
{% endblock %}
+238
View File
@@ -0,0 +1,238 @@
<!DOCTYPE html>
<html class="no-js">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>{{ entry.title }}</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width">
<meta name="apple-mobile-web-app-capable" content="yes">
<script src="{{ url_for('static', filename='js/libs/jquery.min.js') }}"></script>
<script src="{{ url_for('static', filename='js/libs/soundmanager2.js') }}"></script>
<script src="{{ url_for('static', filename='js/libs/bar-ui.js') }}"></script>
<link rel="apple-touch-icon" sizes="140x140" href="{{ url_for('static', filename='favicon.ico') }}">
<link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}">
<link href="{{ url_for('static', filename='css/libs/bootstrap.min.css') }}" rel="stylesheet" media="screen">
<link rel="stylesheet" href="{{ url_for('static', filename='css/libs/bar-ui.css') }}" />
<!--link rel="stylesheet" href="{{ url_for('static', filename='css/listen.css') }}" /-->
<!-- <link rel="stylesheet" href="{{ url_for('static', filename='css/libs/normalize.css') }}">
<link rel="stylesheet" href="{{ url_for('static', filename='css/main.css') }}">
<link rel="stylesheet" href="{{ url_for('static', filename='css/popup.css') }}"> -->
<script>
"use strict";
</script>
</head>
<body>
<!--div id="main">
<div class="content">
<h2>{{ entry.title }}</h2>
<div class="cover">
<img src="{{ url_for('web.get_cover', book_id=entry.id) }}" alt="{{ entry.title }}" />
</div>
{% if entry.ratings.__len__() > 0 %}
<div class="rating">
<p>
{% for number in range((entry.ratings[0].rating/2)|int(2)) %}
<span class="glyphicon glyphicon-star good"></span>
{% if loop.last and loop.index
< 5 %} {% for numer in range(5 - loop.index) %} <span class="glyphicon glyphicon-star">
</span>
{% endfor %} {% endif %} {% endfor %}
</p>
</div>
{% endif %}
<h3>{{_('Description:')}}</h3>
{{entry.comments[0].text|safe}}
</div-->
<!--div class="sm2-bar-ui compact full-width">
<div class="bd sm2-main-controls">
<div class="sm2-inline-texture"></div>
<div class="sm2-inline-gradient"></div>
<div class="sm2-inline-element sm2-button-element">
<div class="sm2-button-bd">
<a href="#play" class="sm2-inline-button sm2-icon-play-pause">{{_('Play / pause')}}</a>
</div>
</div>
<div class="sm2-inline-element sm2-inline-status">
<div class="sm2-playlist">
<div class="sm2-playlist-target">
<!-- playlist <ul> + <li> markup will be injected here -->
<!-- if you want default / non-JS content, you can put that here. -->
<!--noscript><p>JavaScript is required.</p></noscript>
</div>
</div>
<div class="sm2-progress">
<div class="sm2-row">
<div class="sm2-inline-time">0:00</div>
<div class="sm2-progress-bd">
<div class="sm2-progress-track">
<div class="sm2-progress-bar"></div>
<div class="sm2-progress-ball"><div class="icon-overlay"></div></div>
</div>
</div>
<div class="sm2-inline-duration">0:00</div>
</div>
</div>
</div>
<div class="sm2-inline-element sm2-button-element sm2-volume">
<div class="sm2-button-bd">
<span class="sm2-inline-button sm2-volume-control volume-shade"></span>
<a href="#volume" class="sm2-inline-button sm2-volume-control">{{_('volume')}}</a>
</div>
</div>
</div>
<div class="bd sm2-playlist-drawer sm2-element">
<div class="sm2-inline-texture">
<div class="sm2-box-shadow"></div>
</div>
<!-- playlist content is mirrored here -->
<!--div class="sm2-playlist-wrapper">
<ul class="sm2-playlist-bd">
<li><a href="{{ url_for('web.serve_book', book_id=mp3file,book_format=audioformat)}}"><b>{% for author in entry.authors %}{{author.name.replace('|',',')}}
{% if not loop.last %} & {% endif %} {% endfor %}</b> - {{entry.title}}</a></li>
</ul>
</div>
</div>
</div-->
<div class="sm2-bar-ui full-width fixed">
<div class="bd sm2-main-controls">
<div class="sm2-inline-texture"></div>
<div class="sm2-inline-gradient"></div>
<div class="sm2-inline-element sm2-button-element">
<div class="sm2-button-bd">
<a href="#play" class="sm2-inline-button sm2-icon-play-pause">Play / pause</a>
</div>
</div>
<div class="sm2-inline-element sm2-inline-status">
<div class="sm2-playlist">
<div class="sm2-playlist-target">
<noscript><p>JavaScript is required.</p></noscript>
</div>
</div>
<div class="sm2-progress">
<div class="sm2-row">
<div class="sm2-inline-time">0:00</div>
<div class="sm2-progress-bd">
<div class="sm2-progress-track">
<div class="sm2-progress-bar"></div>
<div class="sm2-progress-ball"><div class="icon-overlay"></div></div>
</div>
</div>
<div class="sm2-inline-duration">0:00</div>
</div>
</div>
</div>
<div class="sm2-inline-element sm2-button-element sm2-volume">
<div class="sm2-button-bd">
<span class="sm2-inline-button sm2-volume-control volume-shade"></span>
<a href="#volume" class="sm2-inline-button sm2-volume-control">volume</a>
</div>
</div>
<div class="sm2-inline-element sm2-button-element">
<div class="sm2-button-bd">
<a href="#prev" title="Previous" class="sm2-inline-button sm2-icon-previous">&lt; previous</a>
</div>
</div>
<div class="sm2-inline-element sm2-button-element">
<div class="sm2-button-bd">
<a href="#next" title="Next" class="sm2-inline-button sm2-icon-next">&gt; next</a>
</div>
</div>
<div class="sm2-inline-element sm2-button-element">
<div class="sm2-button-bd">
<a href="#repeat" title="Repeat playlist" class="sm2-inline-button sm2-icon-repeat">&infin; repeat</a>
</div>
</div>
<div class="sm2-inline-element sm2-button-element sm2-menu">
<div class="sm2-button-bd">
<a href="#menu" class="sm2-inline-button sm2-icon-menu">menu</a>
</div>
</div>
</div>
<div class="bd sm2-playlist-drawer sm2-element">
<div class="sm2-inline-texture">
<div class="sm2-box-shadow"></div>
</div>
<!-- playlist content is mirrored here -->
<div class="sm2-playlist-wrapper">
<ul class="sm2-playlist-bd">
<li><a href="{{ url_for('web.serve_book', book_id=mp3file,book_format=audioformat)}}"><b>{% for author in entry.authors %}{{author.name.replace('|',',')}}
{% if not loop.last %} & {% endif %} {% endfor %}</b> - {{entry.title}}</a></li>
</ul>
</div>
</div>
</div>
<script>
soundManager.setup({
useHTML5Audio: true,
preferFlash: false,
url: '/path/to/swf-files/',
onready: function() {
var mySound = soundManager.createSound({
// id: 'aSound',
// url: "{{ url_for('web.serve_book', book_id=mp3file,book_format=audioformat)}}"
});
mySound.play();
},
ontimeout: function() {
// Hrmm, SM2 could not start. Missing SWF? Flash blocked? Show an error, etc.?
}
});
window.calibre = {
filePath: "{{ url_for('static', filename='js/libs/') }}",
cssPath: "{{ url_for('static', filename='css/') }}",
bookUrl: "{{ url_for('static', filename=mp3file) }}/",
bookmarkUrl: "{{ url_for('web.bookmark', book_id=mp3file, book_format=audioformat.upper()) }}",
bookmark: "{{ bookmark.bookmark_key if bookmark != None }}",
useBookmarks: "{{ g.user.is_authenticated | tojson }}"
};
</script>
</body>
</html>
+17 -2
View File
@@ -18,8 +18,23 @@
</label>
</div>
<button type="submit" name="submit" class="btn btn-default">{{_('Submit')}}</button>
{% if remote_login %}
<a href="{{url_for('remote_login')}}" class="pull-right">{{_('Log in with magic link')}}</a>
{% if config.config_remote_login %}
<a href="{{url_for('web.remote_login')}}" class="pull-right">{{_('Log in with magic link')}}</a>
{% endif %}
{% if config.config_login_type == 2 %}
<a href="{{url_for('oauth.github_login')}}" class="pull-right">
<svg height="32" class="octicon octicon-mark-github" viewBox="0 0 16 16" version="1.1" width="32" aria-hidden="true">
<path fill-rule="evenodd" d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z"></path>
</svg>
</a>
{% endif %}
{% if config.config_login_type == 3 %}
<a href="{{url_for('oauth.google_login')}}" class="pull-right">
<svg xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
width="40" height="40"
viewBox="0 3 48 49"
style="fill:#000000;"><g id="surface1"><path style=" fill:#FFC107;" d="M 43.609375 20.082031 L 42 20.082031 L 42 20 L 24 20 L 24 28 L 35.304688 28 C 33.652344 32.65625 29.222656 36 24 36 C 17.371094 36 12 30.628906 12 24 C 12 17.371094 17.371094 12 24 12 C 27.058594 12 29.84375 13.152344 31.960938 15.039063 L 37.617188 9.382813 C 34.046875 6.054688 29.269531 4 24 4 C 12.953125 4 4 12.953125 4 24 C 4 35.046875 12.953125 44 24 44 C 35.046875 44 44 35.046875 44 24 C 44 22.660156 43.863281 21.351563 43.609375 20.082031 Z "></path><path style=" fill:#FF3D00;" d="M 6.304688 14.691406 L 12.878906 19.511719 C 14.65625 15.109375 18.960938 12 24 12 C 27.058594 12 29.84375 13.152344 31.960938 15.039063 L 37.617188 9.382813 C 34.046875 6.054688 29.269531 4 24 4 C 16.316406 4 9.65625 8.335938 6.304688 14.691406 Z "></path><path style=" fill:#4CAF50;" d="M 24 44 C 29.164063 44 33.859375 42.023438 37.410156 38.808594 L 31.21875 33.570313 C 29.210938 35.089844 26.714844 36 24 36 C 18.796875 36 14.382813 32.683594 12.71875 28.054688 L 6.195313 33.078125 C 9.503906 39.554688 16.226563 44 24 44 Z "></path><path style=" fill:#1976D2;" d="M 43.609375 20.082031 L 42 20.082031 L 42 20 L 24 20 L 24 28 L 35.304688 28 C 34.511719 30.238281 33.070313 32.164063 31.214844 33.570313 C 31.21875 33.570313 31.21875 33.570313 31.21875 33.570313 L 37.410156 38.808594 C 36.972656 39.203125 44 34 44 24 C 44 22.660156 43.863281 21.351563 43.609375 20.082031 Z "></path></g></svg>
</a>
{% endif %}
</form>
</div>
+15
View File
@@ -0,0 +1,15 @@
{% extends "layout.html" %}
{% block body %}
<div id="log_group" class="inputs">
<div><input type="radio" name="log_radio" id="log1" value="0" checked>
<label for="log0">{{_('Show Calibre-Web log')}}</label> {{logfiles[0]}}</div>
{% if accesslog_enable %}
<div><input type="radio" name="log_radio" id="log0" value="1">
<label for="log1">{{_('Show access log')}}</label> {{logfiles[1]}}</div>
{% endif %}
</div>
<div id="renderer" class="log"></div>
{% endblock %}
{% block js %}
<script src="{{ url_for('static', filename='js/logviewer.js') }}"></script>
{% endblock %}
+2 -2
View File
@@ -6,9 +6,9 @@
<Developer>Janeczku</Developer>
<Contact>https://github.com/janeczku/calibre-web</Contact>
<Url type="text/html"
template="{{url_for('feed_cc_search')}}{searchTerms}"/>
template="{{url_for('opds.feed_cc_search')}}{searchTerms}"/>
<Url type="application/atom+xml"
template="{{url_for('feed_normal_search')}}?query={searchTerms}"/>
template="{{url_for('opds.feed_normal_search')}}?query={searchTerms}"/>
<SyndicationRight>open</SyndicationRight>
<Language>{{lang}}</Language>
<OutputEncoding>UTF-8</OutputEncoding>
+12 -1
View File
@@ -86,7 +86,18 @@
bookmarkUrl: "{{ url_for('bookmark', book_id=bookid, book_format='EPUB') }}",
bookUrl: "{{ url_for('get_download_link_ext', book_id=bookid, book_format="epub", anyname='file.epub') }}",
bookmark: "{{ bookmark.bookmark_key if bookmark != None }}",
useBookmarks: {{ g.user.is_authenticated | tojson }}
useBookmarks: {{ g.user.is_authenticated | tojson }} };
</script>
<script src="{{ url_for('static', filename='js/libs/jszip.min.js') }}">
</script> <script src="{{ url_for('static', filename='js/libs/epub.min.js') }}"></script>
<script type="text/javascript">
window.calibre = {
filePath: "{{ url_for('static', filename='js/libs/') }}",
cssPath: "{{ url_for('static', filename='css/') }}",
bookmarkUrl: "{{ url_for('web.bookmark', book_id=bookid, book_format='EPUB') }}",
bookUrl: "{{ url_for('web.download_link', book_id=bookid, book_format='epub', anyname='file.epub') }}",
bookmark: "{{ bookmark.bookmark_key if bookmark != None }}",
useBookmarks: "{{ g.user.is_authenticated | tojson }}"
};
</script>
<script src="{{ url_for('static', filename='js/libs/jquery.min.js') }}"></script>
+2 -2
View File
@@ -28,8 +28,8 @@
};
document.onreadystatechange = function () {
if (document.readyState == "complete") {
init("{{ url_for('serve_book', book_id=comicfile, book_format=extension) }}");
updateArrows();
init("{{ url_for('web.serve_book', book_id=comicfile, book_format=extension) }}");
updateArrows();
}
}
</script>
+3 -5
View File
@@ -26,7 +26,7 @@ See https://github.com/adobe-type-tools/cmap-resources
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="google" content="notranslate">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>{{_('PDF.js viewer')}}</title>
<title>{{_('PDF reader')}}</title>
<link rel="stylesheet" href="{{ url_for('static', filename='css/libs/viewer.css') }}">
@@ -37,12 +37,11 @@ See https://github.com/adobe-type-tools/cmap-resources
<script src="{{ url_for('static', filename='js/libs/pdf.js') }}"></script>
<script type="text/javascript">
window.addEventListener('load', function() {
PDFViewerApplicationOptions.set('sidebarViewOnLoad', 0);
PDFViewerApplicationOptions.set('imageResourcesPath', "{{ url_for('static', filename='css/images/') }}");
PDFViewerApplicationOptions.set('workerSrc', "{{ url_for('static', filename='js/libs/pdf.worker.js') }}");
PDFViewerApplication.open("{{ url_for('serve_book', book_id=pdffile, book_format='pdf') }}");
PDFViewerApplication.open("{{ url_for('web.serve_book', book_id=pdffile, book_format='pdf') }}");
});
</script>
<link rel="resource" type="application/l10n" href="{{ url_for('static', filename='locale/locale.properties') }}">
@@ -123,11 +122,9 @@ See https://github.com/adobe-type-tools/cmap-resources
<button id="secondaryPrint" class="secondaryToolbarButton print visibleMediumView" title="Print" tabindex="53" data-l10n-id="print">
<span data-l10n-id="print_label">Print</span>
</button>
<button id="secondaryDownload" class="secondaryToolbarButton download visibleMediumView" title="Download" tabindex="54" data-l10n-id="download" {% if not g.user.role_download() %} style="display:none;" {% endif %}>
<span data-l10n-id="download_label">Download</span>
</button>
<a href="#" id="secondaryViewBookmark" class="secondaryToolbarButton bookmark visibleSmallView" title="Current view (copy or open in new window)" tabindex="55" data-l10n-id="bookmark">
<span data-l10n-id="bookmark_label">Current View</span>
</a>
@@ -230,6 +227,7 @@ See https://github.com/adobe-type-tools/cmap-resources
<button id="download" class="toolbarButton download hiddenMediumView" title="Download" tabindex="34" data-l10n-id="download" {% if not g.user.role_download() %} style="display:none;" {% endif %}>
<span data-l10n-id="download_label">Download</span>
</button>
<a href="#" id="viewBookmark" class="toolbarButton bookmark hiddenSmallView" title="Current view (copy or open in new window)" tabindex="35" data-l10n-id="bookmark">
<span data-l10n-id="bookmark_label">Current View</span>
</a>
+3 -3
View File
@@ -109,12 +109,12 @@
$("#area").width($("#area").width());
$("#content").width($("#content").width());
//bind text
$("#content").load("{{ url_for('serve_book', book_id=txtfile,book_format='txt') }}",function(textStr) {
$("#content").load("{{ url_for('web.serve_book', book_id=txtfile,book_format='txt') }}",function(textStr) {
$(this).height($(this).parent().height()*0.95);
$(this).text(textStr);
});
//keybind
$(document).keydown(function(event){
$(document).keydown(function(event){
if(event.keyCode == 37){
prevPage();
}
@@ -162,4 +162,4 @@
</script>
</body>
</html>
</html>
+15
View File
@@ -12,6 +12,21 @@
<input type="email" class="form-control" id="email" name="email" placeholder="{{_('Your email address')}}" required>
</div>
<button type="submit" id="submit" class="btn btn-primary">{{_('Register')}}</button>
{% if config.config_use_github_oauth %}
<a href="{{url_for('oauth.github_login')}}" class="pull-right">
<svg height="32" class="octicon octicon-mark-github" viewBox="0 0 16 16" version="1.1" width="32" aria-hidden="true">
<path fill-rule="evenodd" d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z"></path>
</svg>
</a>
{% endif %}
{% if config.config_use_google_oauth %}
<a href="{{url_for('oauth.google_login')}}" class="pull-right">
<svg xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
width="40" height="40"
viewBox="0 3 48 49"
style="fill:#000000;"><g id="surface1"><path style=" fill:#FFC107;" d="M 43.609375 20.082031 L 42 20.082031 L 42 20 L 24 20 L 24 28 L 35.304688 28 C 33.652344 32.65625 29.222656 36 24 36 C 17.371094 36 12 30.628906 12 24 C 12 17.371094 17.371094 12 24 12 C 27.058594 12 29.84375 13.152344 31.960938 15.039063 L 37.617188 9.382813 C 34.046875 6.054688 29.269531 4 24 4 C 12.953125 4 4 12.953125 4 24 C 4 35.046875 12.953125 44 24 44 C 35.046875 44 44 35.046875 44 24 C 44 22.660156 43.863281 21.351563 43.609375 20.082031 Z "></path><path style=" fill:#FF3D00;" d="M 6.304688 14.691406 L 12.878906 19.511719 C 14.65625 15.109375 18.960938 12 24 12 C 27.058594 12 29.84375 13.152344 31.960938 15.039063 L 37.617188 9.382813 C 34.046875 6.054688 29.269531 4 24 4 C 16.316406 4 9.65625 8.335938 6.304688 14.691406 Z "></path><path style=" fill:#4CAF50;" d="M 24 44 C 29.164063 44 33.859375 42.023438 37.410156 38.808594 L 31.21875 33.570313 C 29.210938 35.089844 26.714844 36 24 36 C 18.796875 36 14.382813 32.683594 12.71875 28.054688 L 6.195313 33.078125 C 9.503906 39.554688 16.226563 44 24 44 Z "></path><path style=" fill:#1976D2;" d="M 43.609375 20.082031 L 42 20.082031 L 42 20 L 24 20 L 24 28 L 35.304688 28 C 34.511719 30.238281 33.070313 32.164063 31.214844 33.570313 C 31.21875 33.570313 31.21875 33.570313 31.21875 33.570313 L 37.410156 38.808594 C 36.972656 39.203125 44 34 44 24 C 44 22.660156 43.863281 21.351563 43.609375 20.082031 Z "></path></g></svg>
</a>
{% endif %}
</form>
</div>
{% if error %}
+2 -2
View File
@@ -19,12 +19,12 @@
(function () {
// Poll the server to check if the user has authenticated
var t = setInterval(function () {
$.post('{{url_for("token_verified")}}', { token: '{{token}}' })
$.post('{{url_for("web.token_verified")}}', { token: '{{token}}' })
.done(function(response) {
if (response.status === 'success') {
// Wait a tick so cookies are updated
setTimeout(function () {
window.location.href = '{{url_for("index")}}';
window.location.href = '{{url_for("web.index")}}';
}, 0);
}
})
+25 -8
View File
@@ -17,17 +17,29 @@
<ul id="add-to-shelves" class="dropdown-menu" aria-labelledby="add-to-shelf">
{% for shelf in g.user.shelf %}
{% if shelf.is_public != 1 %}
<li><a href="{{ url_for('search_to_shelf', shelf_id=shelf.id) }}"> {{shelf.name}}</a></li>
<li><a href="{{ url_for('shelf.search_to_shelf', shelf_id=shelf.id) }}"> {{shelf.name}}</a></li>
{% endif %}
{% endfor %}
{% for shelf in g.public_shelfes %}
<li><a href="{{ url_for('search_to_shelf', shelf_id=shelf.id) }}">{{shelf.name}}</a></li>
<li><a href="{{ url_for('shelf.search_to_shelf', shelf_id=shelf.id) }}">{{shelf.name}}</a></li>
{% endfor %}
</ul>
</div>
</div>
{% endif %}
{% endif %}
<div class="filterheader hidden-xs hidden-sm"><!-- ToDo: Implement filter for search results -->
<a id="new" class="btn btn-primary" href="{{url_for('web.books_list', data=page, sort='new')}}"><span class="glyphicon glyphicon-sort-by-order"></span></a>
<a id="old" class="btn btn-primary" href="{{url_for('web.books_list', data=page, sort='old')}}"><span class="glyphicon glyphicon-sort-by-order-alt"></span></a>
<a id="asc" class="btn btn-primary" href="{{url_for('web.books_list', data=page, sort='abc')}}"><span class="glyphicon glyphicon-font"></span><span class="glyphicon glyphicon-sort-by-alphabet"></span></a>
<a id="desc" class="btn btn-primary" href="{{url_for('web.books_list', data=page, sort='zyx')}}"><span class="glyphicon glyphicon-font"></span><span class="glyphicon glyphicon-sort-by-alphabet-alt"></span></a>
<a id="pub_new" class="btn btn-primary" href="{{url_for('web.books_list', data=page, sort='pubnew')}}"><span class="glyphicon glyphicon-calendar"></span><span class="glyphicon glyphicon-sort-by-order"></span></a>
<a id="pub_old" class="btn btn-primary" href="{{url_for('web.books_list', data=page, sort='pubold')}}"><span class="glyphicon glyphicon-calendar"></span><span class="glyphicon glyphicon-sort-by-order-alt"></span></a>
</div>
<div class="btn-group character" role="group">
<a id="no_shelf" class="btn btn-primary" href="{{url_for('web.books_list', data=page, sort='pubold')}}"><span class="glyphicon glyphicon-list"></span><b>?</b></a>
<div id="all" class="btn btn-primary">{{_('All')}}</div>
</div>
{% endif %}
<div class="row">
@@ -35,13 +47,13 @@
<div class="col-sm-3 col-lg-2 col-xs-6 book">
<div class="cover">
{% if entry.has_cover is defined %}
<a href="{{ url_for('show_book', book_id=entry.id) }}" data-toggle="modal" data-target="#bookDetailsModal" data-remote="false">
<img src="{{ url_for('get_cover', book_id=entry.id) }}" alt="{{ entry.title }}" />
<a href="{{ url_for('web.show_book', book_id=entry.id) }}" data-toggle="modal" data-target="#bookDetailsModal" data-remote="false">
<img src="{{ url_for('web.get_cover', book_id=entry.id) }}" alt="{{ entry.title }}" />
</a>
{% endif %}
</div>
<div class="meta">
<a href="{{ url_for('show_book', book_id=entry.id) }}" data-toggle="modal" data-target="#bookDetailsModal" data-remote="false">
<a href="{{ url_for('web.show_book', book_id=entry.id) }}" data-toggle="modal" data-target="#bookDetailsModal" data-remote="false">
<p class="title">{{entry.title|shortentitle}}</p>
</a>
<p class="author">
@@ -49,8 +61,8 @@
{% if loop.index > g.config_authors_max and g.config_authors_max != 0 %}
{% if not loop.first %}
<span class="author-hidden-divider">&amp;</span>
{% endif %}
<a class="author-name author-hidden" href="{{url_for('author', book_id=author.id) }}">{{author.name.replace('|',',')|shortentitle(30)}}</a>
{% endif %}
<a class="author-name author-hidden" href="{{url_for('web.books_list', data='author', sort='new', book_id=author.id) }}">{{author.name.replace('|',',')|shortentitle(30)}}</a>
{% if loop.last %}
<a href="#" class="author-expand" data-authors-max="{{g.config_authors_max}}" data-collapse-caption="({{_('reduce')}})">(...)</a>
{% endif %}
@@ -58,7 +70,12 @@
{% if not loop.first %}
<span>&amp;</span>
{% endif %}
<a class="author-name" href="{{url_for('author', book_id=author.id) }}">{{author.name.replace('|',',')|shortentitle(30)}}</a>
<a class="author-name" href="{{url_for('web.books_list', data='author', sort='new', book_id=author.id) }}">{{author.name.replace('|',',')|shortentitle(30)}}</a>
{% endif %}
{% endfor %}
{% for format in entry.data %}
{% if format.format|lower == 'mp3' %}
<span class="glyphicon glyphicon-music"></span>
{% endif %}
{% endfor %}
</p>
+1 -1
View File
@@ -1,7 +1,7 @@
{% extends "layout.html" %}
{% block body %}
<div class="col-sm-8">
<form role="form" id="search" action="{{ url_for('advanced_search') }}" method="GET">
<form role="form" id="search" action="{{ url_for('web.advanced_search') }}" method="GET">
<div class="form-group">
<label for="book_title">{{_('Book Title')}}</label>
<input type="text" class="form-control" name="book_title" id="book_title" value="">
+11 -12
View File
@@ -2,11 +2,14 @@
{% block body %}
<div class="discover">
<h2>{{title}}</h2>
{% if g.user.role_download() %}
<a id="shelf_down" href="{{ url_for('shelf.show_shelf', shelf_type=2, shelf_id=shelf.id) }}" class="btn btn-primary">{{ _('Download') }} </a>
{% endif %}
{% if g.user.is_authenticated %}
{% if (g.user.role_edit_shelfs() and shelf.is_public ) or not shelf.is_public %}
<div id="delete_shelf" data-toggle="modal" data-target="#DeleteShelfDialog" class="btn btn-danger">{{ _('Delete this Shelf') }} </div>
<a id="edit_shelf" href="{{ url_for('edit_shelf', shelf_id=shelf.id) }}" class="btn btn-primary">{{ _('Edit Shelf') }} </a>
<a id="order_shelf" href="{{ url_for('order_shelf', shelf_id=shelf.id) }}" class="btn btn-primary">{{ _('Change order') }} </a>
<a id="edit_shelf" href="{{ url_for('shelf.edit_shelf', shelf_id=shelf.id) }}" class="btn btn-primary">{{ _('Edit Shelf') }} </a>
<a id="order_shelf" href="{{ url_for('shelf.order_shelf', shelf_id=shelf.id) }}" class="btn btn-primary">{{ _('Change order') }} </a>
{% endif %}
{% endif %}
<div class="row">
@@ -14,16 +17,12 @@
{% for entry in entries %}
<div class="col-sm-3 col-lg-2 col-xs-6 book">
<div class="cover">
<a href="{{ url_for('show_book', book_id=entry.id) }}" data-toggle="modal" data-target="#bookDetailsModal" data-remote="false">
{% if entry.has_cover %}
<img src="{{ url_for('get_cover', book_id=entry.id) }}" alt="{{ entry.title }}" />
{% else %}
<img src="{{ url_for('static', filename='generic_cover.jpg') }}" alt="{{ entry.title }}" />
{% endif %}
<a href="{{ url_for('web.show_book', book_id=entry.id) }}" data-toggle="modal" data-target="#bookDetailsModal" data-remote="false">
<img src="{{ url_for('web.get_cover', book_id=entry.id) }}" alt="{{ entry.title }}" />
</a>
</div>
<div class="meta">
<a href="{{ url_for('show_book', book_id=entry.id) }}" data-toggle="modal" data-target="#bookDetailsModal" data-remote="false">
<a href="{{ url_for('web.show_book', book_id=entry.id) }}" data-toggle="modal" data-target="#bookDetailsModal" data-remote="false">
<p class="title">{{entry.title|shortentitle}}</p>
</a>
<p class="author">
@@ -32,7 +31,7 @@
{% if not loop.first %}
<span class="author-hidden-divider">&amp;</span>
{% endif %}
<a class="author-name author-hidden" href="{{url_for('author', book_id=author.id) }}">{{author.name.replace('|',',')|shortentitle(30)}}</a>
<a class="author-name author-hidden" href="{{url_for('web.books_list', data='author', sort='new', book_id=author.id) }}">{{author.name.replace('|',',')|shortentitle(30)}}</a>
{% if loop.last %}
<a href="#" class="author-expand" data-authors-max="{{g.config_authors_max}}" data-collapse-caption="({{_('reduce')}})">(...)</a>
{% endif %}
@@ -40,7 +39,7 @@
{% if not loop.first %}
<span>&amp;</span>
{% endif %}
<a class="author-name" href="{{url_for('author', book_id=author.id) }}">{{author.name.replace('|',',')|shortentitle(30)}}</a>
<a class="author-name" href="{{url_for('web.books_list', data='author', sort='new', book_id=author.id) }}">{{author.name.replace('|',',')|shortentitle(30)}}</a>
{% endif %}
{% endfor %}
</p>
@@ -70,7 +69,7 @@
<div class="modal-body text-center">
<span>{{_('Shelf will be lost for everybody and forever!')}}</span>
<p></p>
<a id="confirm" href="{{ url_for('delete_shelf', shelf_id=shelf.id) }}" class="btn btn-danger">{{_('Ok')}}</a>
<a id="confirm" href="{{ url_for('shelf.delete_shelf', shelf_id=shelf.id) }}" class="btn btn-danger">{{_('Ok')}}</a>
<button type="button" class="btn btn-default" data-dismiss="modal">{{_('Back')}}</button>
</div>
</div>
+1 -1
View File
@@ -16,7 +16,7 @@
{% endif %}
<button type="submit" class="btn btn-default" id="submit">{{_('Submit')}}</button>
{% if shelf.id != None %}
<a href="{{ url_for('show_shelf', shelf_id=shelf.id) }}" class="btn btn-default">{{_('Back')}}</a>
<a href="{{ url_for('shelf.show_shelf', shelf_id=shelf.id) }}" class="btn btn-default">{{_('Back')}}</a>
{% endif %}
</form>
</div>
+2 -2
View File
@@ -8,8 +8,8 @@
<div id="{{entry.id}}" class="list-group-item">{{entry.title}}</div>
{% endfor %}
</div>
<button onclick="sendData('{{ url_for('order_shelf', shelf_id=shelf.id) }}')" class="btn btn-default" id="ChangeOrder">{{_('Change order')}}</button>
<a href="{{ url_for('show_shelf', shelf_id=shelf.id) }}" class="btn btn-default">{{_('Back')}}</a>
<button onclick="sendData('{{ url_for('shelf.order_shelf', shelf_id=shelf.id) }}')" class="btn btn-default" id="ChangeOrder">{{_('Change order')}}</button>
<a href="{{ url_for('shelf.show_shelf', shelf_id=shelf.id) }}" class="btn btn-default">{{_('Back')}}</a>
</div>
{% endblock %}
+82
View File
@@ -0,0 +1,82 @@
<!DOCTYPE html>
<html lang="{{ g.user.locale }}">
<head>
<title>{{instance}} | {{title}}</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="apple-mobile-web-app-capable" content="yes">
<!-- Bootstrap -->
<link rel="apple-touch-icon" sizes="140x140" href="{{ url_for('static', filename='favicon.ico') }}">
<link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}">
<link href="{{ url_for('static', filename='css/libs/bootstrap.min.css') }}" rel="stylesheet" media="screen">
<link href="{{ url_for('static', filename='css/style.css') }}" rel="stylesheet" media="screen">
{% if g.user.get_theme == 1 %}
<link href="{{ url_for('static', filename='css/caliBlur-style.css') }}" rel="stylesheet" media="screen">
{% endif %}
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>
<![endif]-->
{% block header %}{% endblock %}
</head>
<body class="{{ page }}">
{% block body %}
<div class="discover">
<h2>{{title}}</h2>
<div class="row">
{% for entry in entries %}
<div class="col-sm-3 col-lg-2 col-xs-6 book">
<div class="meta">
<p class="title">{{entry.title|shortentitle}}</p>
<p class="author">
{% for author in entry.authors %}
<a href="{{url_for('web.books_list', data='author', sort='new', book_id=author.id) }}">{{author.name.replace('|',',')}}</a>
{% if not loop.last %}
&amp;
{% endif %}
{% endfor %}
</p>
</div>
<div class="btn-group" role="group" aria-label="Download, send to Kindle, reading">
{% if g.user.role_download() %}
{% if entry.data|length %}
<div class="btn-group" role="group">
{% if entry.data|length < 2 %}
{% for format in entry.data %}
<a href="{{ url_for('web.download_link', book_id=entry.id, book_format=format.format|lower, anyname=entry.id|string+'.'+format.format|lower) }}" id="btnGroupDrop1{{format.format|lower}}" class="btn btn-primary" role="button">
<span class="glyphicon glyphicon-download"></span>{{format.format}} ({{ format.uncompressed_size|filesizeformat }})
</a>
{% endfor %}
{% else %}
<button id="btnGroupDrop1" type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<span class="glyphicon glyphicon-download"></span> {{_('Download')}}
<span class="caret"></span>
</button>
<ul class="dropdown-menu" aria-labelledby="btnGroupDrop1">
{% for format in entry.data %}
<li><a href="{{ url_for('web.download_link', book_id=entry.id, book_format=format.format|lower, anyname=entry.id|string+'.'+format.format|lower) }}">{{format.format}} ({{ format.uncompressed_size|filesizeformat }})</a></li>
{% endfor %}
</ul>
{% endif %}
</div>
{% endif %}
{% endif %}
</div>
</div>
{% endfor %}
</div>
</div>
{% endblock %}
</body>
</html>
+2 -2
View File
@@ -5,7 +5,7 @@
{% block body %}
<div class="discover">
<h2>{{_('Tasks list')}}</h2>
<table class="table table-no-bordered" id="table" data-url="{{ url_for('get_email_status_json') }}" data-sort-name="starttime" data-sort-order="asc">
<table class="table table-no-bordered" id="table" data-url="{{ url_for('web.get_email_status_json') }}" data-sort-name="starttime" data-sort-order="asc">
<thead>
<tr>
{% if g.user.role_admin() %}
@@ -38,7 +38,7 @@
setInterval(function() {
$.ajax({
method:"get",
url: "{{ url_for('get_email_status_json')}}",
url: "{{ url_for('web.get_email_status_json')}}",
async: true,
timeout: 900,
success:function(data){
+37 -54
View File
@@ -15,7 +15,7 @@
</div>
{% if ( g.user and g.user.role_passwd() or g.user.role_admin() ) and not content.role_anonymous() %}
{% if g.user and g.user.role_admin() and g.allow_registration and not new_user and not profile %}
<div class="btn btn-default" id="resend_password"><a href="{{url_for('reset_password', user_id = content.id) }}">{{_('Reset user Password')}}</a></div>
<div class="btn btn-default" id="resend_password"><a href="{{url_for('admin.reset_password', user_id = content.id) }}">{{_('Reset user Password')}}</a></div>
{% else %}
<div class="form-group">
<label for="password">{{_('Password')}}</label>
@@ -35,6 +35,7 @@
{% endfor %}
</select>
</div>
<div class="form-group">
<label for="default_language">{{_('Show books with language')}}</label>
<select name="default_language" id="default_language" class="form-control">
@@ -44,56 +45,34 @@
{% endfor %}
</select>
</div>
{% if registered_oauth.keys()| length > 0 %}
{% for oauth, name in registered_oauth.iteritems() %}
<div class="form-group">
<label>{{ name }} {{_('OAuth Settings')}}</label>
{% if oauth not in oauth_status %}
<div><a href="{{ url_for(oauth +'.login') }}" id="config_{{ oauth }}_oauth" class="btn btn-primary">{{_('Link')}}</a></div>
{% else %}
<div><a href="{{ url_for('oauth.'+ oauth +'_login_unlink') }}" id="config_{{ oauth }}_oauth" class="btn btn-primary">{{_('Unlink')}}</a></div>
{% endif %}
{% endfor %}
</div>
{% endif %}
<div class="col-sm-6">
{% for element in sidebar %}
{% if element['config_show'] %}
<div class="form-group">
<input type="checkbox" name="show_{{element['visibility']}}" id="show_{{element['visibility']}}" {% if content.check_visibility(element['visibility']) %}checked{% endif %}>
<label for="show_{{element['visibility']}}">{{element['show_text']}}</label>
</div>
{% endif %}
{% endfor %}
<div class="form-group">
<input type="checkbox" name="show_random" id="show_random" {% if content.show_random_books() %}checked{% endif %}>
<label for="show_random">{{_('Show random books')}}</label>
</div>
<div class="form-group">
<input type="checkbox" name="show_recent" id="show_recent" {% if content.show_recent() %}checked{% endif %}>
<label for="show_recent">{{_('Show recent books')}}</label>
</div>
<div class="form-group">
<input type="checkbox" name="show_sorted" id="show_sorted" {% if content.show_sorted() %}checked{% endif %}>
<label for="show_sorted">{{_('Show sorted books')}}</label>
</div>
<div class="form-group">
<input type="checkbox" name="show_hot" id="show_hot" {% if content.show_hot_books() %}checked{% endif %}>
<label for="show_hot">{{_('Show hot books')}}</label>
</div>
<div class="form-group">
<input type="checkbox" name="show_best_rated" id="show_best_rated" {% if content.show_best_rated_books() %}checked{% endif %}>
<label for="show_best_rated">{{_('Show best rated books')}}</label>
</div>
<div class="form-group">
<input type="checkbox" name="show_language" id="show_language" {% if content.show_language() %}checked{% endif %}>
<label for="show_language">{{_('Show language selection')}}</label>
</div>
<div class="form-group">
<input type="checkbox" name="show_series" id="show_series" {% if content.show_series() %}checked{% endif %}>
<label for="show_series">{{_('Show series selection')}}</label>
</div>
<div class="form-group">
<input type="checkbox" name="show_category" id="show_category" {% if content.show_category() %}checked{% endif %}>
<label for="show_category">{{_('Show category selection')}}</label>
</div>
<div class="form-group">
<input type="checkbox" name="show_author" id="show_author" {% if content.show_author() %}checked{% endif %}>
<label for="show_author">{{_('Show author selection')}}</label>
</div>
<div class="form-group">
<input type="checkbox" name="show_publisher" id="show_publisher" {% if content.show_publisher() %}checked{% endif %}>
<label for="show_publisher">{{_('Show publisher selection')}}</label>
</div>
{% if not content.role_anonymous() %}
<div class="form-group">
<input type="checkbox" name="show_read_and_unread" id="show_read_and_unread" {% if content.show_read_and_unread() %}checked{% endif %}>
<label for="show_read_and_unread">{{_('Show read and unread')}}</label>
</div>
{% endif %}
<div class="form-group">
<input type="checkbox" name="show_detail_random" id="show_detail_random" {% if content.show_detail_random() %}checked{% endif %}>
<label for="show_detail_random">{{_('Show random books in detail view')}}</label>
<input type="checkbox" name="Show_detail_random" id="Show_detail_random" {% if content.show_detail_random() %}checked{% endif %}>
<label for="Show_detail_random">{{_('Show random books in detail view')}}</label>
</div>
</div>
<div class="col-sm-6">
@@ -105,13 +84,17 @@
</div>
{% endif %}
<div class="form-group">
<input type="checkbox" name="show_mature_content" id="show_mature_content" {% if content.mature_content %}checked{% endif %}>
<label for="show_mature_content">{{_('Show mature content')}}</label>
<input type="checkbox" name="Show_mature_content" id="Show_mature_content" {% if content.mature_content %}checked{% endif %}>
<label for="Show_mature_content">{{_('Show mature content')}}</label>
</div>
<div class="form-group">
<input type="checkbox" name="download_role" id="download_role" {% if content.role_download() %}checked{% endif %}>
<label for="download_role">{{_('Allow Downloads')}}</label>
</div>
<div class="form-group">
<input type="checkbox" name="viewer_role" id="viewer_role" {% if content.role_viewer() %}checked{% endif %}>
<label for="viewer_role">{{_('Allow book viewer')}}</label>
</div>
<div class="form-group">
<input type="checkbox" name="upload_role" id="upload_role" {% if content.role_upload() %}checked{% endif %}>
<label for="upload_role">{{_('Allow Uploads')}}</label>
@@ -146,7 +129,7 @@
<div class="col-sm-12">
<button type="submit" id="submit" class="btn btn-default">{{_('Submit')}}</button>
{% if not profile %}
<a href="{{ url_for('admin') }}" id="back" class="btn btn-default">{{_('Back')}}</a>
<a href="{{ url_for('admin.admin') }}" id="back" class="btn btn-default">{{_('Back')}}</a>
{% endif %}
</div>
</form>
@@ -156,8 +139,8 @@
<h2>{{_('Recent Downloads')}}</h2>
{% for entry in downloads %}
<div class="col-sm-2">
<a class="pull-left" href="{{ url_for('show_book', book_id=entry.id) }}">
<img class="media-object" width="100" src="{{ url_for('get_cover', book_id=entry.id) }}" alt="...">
<a class="pull-left" href="{{ url_for('web.show_book', book_id=entry.id) }}">
<img class="media-object" width="100" src="{{ url_for('web.get_cover', book_id=entry.id) }}" alt="...">
</a>
</div>
{% endfor %}