mirror of
https://github.com/janeczku/calibre-web
synced 2024-12-04 23:40:01 +00:00
6717683ac3
Music icon only visible once if more than one audio format available
335 lines
19 KiB
HTML
335 lines
19 KiB
HTML
{% extends "layout.html" %}
|
||
{% block body %}
|
||
{% if book %}
|
||
<div class="col-sm-3 col-lg-3 col-xs-12">
|
||
<div class="cover">
|
||
<!-- Always use full-sized image for the book edit page -->
|
||
<img id="detailcover" title="{{book.title}}" src="{{url_for('web.get_cover', book_id=book.id, resolution='og', c=book|last_modified)}}" />
|
||
</div>
|
||
{% if current_user.role_delete_books() %}
|
||
<div class="text-center">
|
||
<button type="button" class="btn btn-danger" id="delete" data-toggle="modal" data-delete-id="{{ book.id }}" data-target="#deleteModal">{{_("Delete Book")}}</button>
|
||
</div>
|
||
{% if book.data|length > 1 %}
|
||
<div class="text-center more-stuff"><h4>{{_('Delete formats:')}}</h4>
|
||
{% for file in book.data %}
|
||
<div class="form-group">
|
||
<button type="button" class="btn btn-danger" id="delete_format" data-toggle="modal" data-delete-id="{{ book.id }}" data-delete-format="{{ file.format }}" data-target="#deleteModal">{{_('Delete')}} - {{file.format}}</button>
|
||
</div>
|
||
{% endfor %}
|
||
</div>
|
||
{% endif %}
|
||
{% endif %}
|
||
|
||
{% 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('edit-book.convert_bookformat', book_id=book.id) }}" method="post" id="book_convert_frm">
|
||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||
<div class="form-group">
|
||
<div class="text-left">
|
||
<label class="control-label" for="book_format_from">{{_('Convert from:')}}</label>
|
||
<select class="form-control" name="book_format_from" id="book_format_from">
|
||
<option disabled selected value>-- {{_('select an option')}} --</option>
|
||
{% for format in source_formats %}
|
||
<option>{{format|upper}}</option>
|
||
{% endfor %}
|
||
</select>
|
||
<label class="control-label" for="book_format_to">{{_('Convert to:')}}</label>
|
||
<select class="form-control" name="book_format_to" id="book_format_to">
|
||
<option disabled selected value>-- {{_('select an option')}} --</option>
|
||
{% for format in conversion_formats %}
|
||
<option>{{format|upper}}</option>
|
||
{% endfor %}
|
||
</select>
|
||
</div>
|
||
</div>
|
||
<button type="submit" class="btn btn-primary" id="btn-book-convert" name="btn-book-convert"><span class="glyphicon glyphicon-duplicate"></span> {{_('Convert book')}}</button>
|
||
</form>
|
||
</div>
|
||
{% endif %}
|
||
{% if current_user.role_upload() and g.allow_upload %}
|
||
|
||
<div class="text-center more-stuff"><!--h4 aria-label="Upload new book format"></h4-->
|
||
<form id="form-upload-format" action="{{ url_for('edit-book.upload') }}" data-title="{{_('Uploading...')}}" data-footer="{{_('Close')}}" data-failed="{{_('Error')}}" data-message="{{_('Upload done, processing, please wait...')}}" method="post" enctype="multipart/form-data">
|
||
<div class="text-center">
|
||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||
<input type="hidden" name="book_id" value="{{ book.id }}">
|
||
<div role="group" aria-label="Upload new book format">
|
||
<label class="btn btn-primary btn-file" for="btn-upload-format">{{ _('Upload Format') }}</label>
|
||
<div class="upload-format-input-text" id="upload-format"></div>
|
||
<input id="btn-upload-format" name="btn-upload-format" type="file" accept="{% for format in accept %}.{% if format != ''%}{{format}}{% else %}*{% endif %}{{ ',' if not loop.last }}{% endfor %}" multiple>
|
||
</div>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
{% endif %}
|
||
</div>
|
||
<form role="form" action="{{ url_for('edit-book.edit_book', book_id=book.id) }}" method="post" enctype="multipart/form-data" id="book_edit_frm">
|
||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||
<div class="col-sm-9 col-xs-12">
|
||
<div class="form-group">
|
||
<label for="title">{{_('Book Title')}}</label>
|
||
<input type="text" class="form-control" name="title" id="title" value="{{book.title}}">
|
||
</div>
|
||
<div class="text-center">
|
||
<button type="button" class="btn btn-default" id="xchange" ><span class="glyphicon glyphicon-arrow-up"></span><span class="glyphicon glyphicon-arrow-down"></span></button>
|
||
</div>
|
||
<div id="author_div" class="form-group">
|
||
<label for="bookAuthor">{{_('Author')}}</label>
|
||
<input type="text" class="form-control typeahead" autocomplete="off" name="authors" id="authors" value="{{' & '.join(authors)}}">
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label for="comments">{{_('Description')}}</label>
|
||
<textarea class="form-control" name="comments" id="comments" rows="7">{% if book.comments %}{{book.comments[0].text}}{%endif%}</textarea>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label>{{_('Identifiers')}}</label>
|
||
<table class="table" id="identifier-table">
|
||
{% for identifier in book.identifiers %}
|
||
<tr>
|
||
<td><input type="text" class="form-control" name="identifier-type-{{identifier.type}}" value="{{identifier.type}}" required="required" placeholder="{{_('Identifier Type')}}"></td>
|
||
<td><input type="text" class="form-control" name="identifier-val-{{identifier.type}}" value="{{identifier.val}}" required="required" placeholder="{{_('Identifier Value')}}"></td>
|
||
<td><a class="btn btn-default" onclick="removeIdentifierLine(this)">{{_('Remove')}}</a></td>
|
||
</tr>
|
||
{% endfor %}
|
||
</table>
|
||
<a id="add-identifier-line" class="btn btn-default">{{_('Add Identifier')}}</a>
|
||
</div>
|
||
|
||
<div class="form-group">
|
||
<label for="tags">{{_('Tags')}}</label>
|
||
<input type="text" class="form-control typeahead" autocomplete="off" name="tags" id="tags" value="{% for tag in book.tags %}{{tag.name.strip()}}{% if not loop.last %}, {% endif %}{% endfor %}">
|
||
</div>
|
||
<div class="form-group">
|
||
<label for="series">{{_('Series')}}</label>
|
||
<input type="text" class="form-control typeahead" autocomplete="off" name="series" id="series" value="{% if book.series %}{{book.series[0].name}}{% endif %}">
|
||
</div>
|
||
<div class="form-group">
|
||
<label for="series_index">{{_('Series ID')}}</label>
|
||
<input type="number" step="0.01" min="0" placeholder="1" class="form-control" name="series_index" id="series_index" value="{{book.series_index}}">
|
||
</div>
|
||
<div class="form-group">
|
||
<label for="rating">{{_('Rating')}}</label>
|
||
<input type="number" name="rating" id="rating" class="rating input-lg" data-clearable="" value="{% if book.ratings %}{{(book.ratings[0].rating / 2)|int}}{% endif %}">
|
||
</div>
|
||
{% if current_user.role_upload() and g.allow_upload %}
|
||
<div class="form-group">
|
||
<label for="cover_url">{{_('Fetch Cover from URL (JPEG - Image will be downloaded and stored in database)')}}</label>
|
||
<input type="text" class="form-control" name="cover_url" id="cover_url" value="">
|
||
</div>
|
||
<div class="form-group" aria-label="Upload cover from local drive">
|
||
<label class="btn btn-primary btn-file" for="btn-upload-cover">{{ _('Upload Cover from Local Disk') }}</label>
|
||
<div class="upload-cover-input-text" id="upload-cover"></div>
|
||
<input id="btn-upload-cover" name="btn-upload-cover" type="file" accept=".jpg, .jpeg, .png, .webp">
|
||
</div>
|
||
{% endif %}
|
||
<label for="pubdate">{{_('Published Date')}}</label>
|
||
<div class="form-group input-group">
|
||
<input type="text" class="datepicker form-control" name="pubdate" id="pubdate" value="{% if book.pubdate %}{{book.pubdate|formatdateinput}}{% endif %}">
|
||
<input type="text" class="form-control fake-input hidden" id="fake_pubdate" value="{% if book.pubdate %}{{book.pubdate|formatdate}}{% endif %}">
|
||
<span class="input-group-btn">
|
||
<button type="button" id="pubdate_delete" class="datepicker_delete btn btn-default"><span class="glyphicon glyphicon-remove-circle"></span></button>
|
||
</span>
|
||
</div>
|
||
<div class="form-group">
|
||
<label for="publisher">{{_('Publisher')}}</label>
|
||
<input type="text" class="form-control typeahead" autocomplete="off" name="publisher" id="publisher" value="{% if book.publishers|length > 0 %}{{book.publishers[0].name}}{% endif %}">
|
||
</div>
|
||
<div class="form-group">
|
||
<label for="languages">{{_('Language')}}</label>
|
||
<input type="text" class="form-control typeahead" autocomplete="off" name="languages" id="languages" value="{% for language in book.languages %}{{language.language_name.strip()}}{% if not loop.last %}, {% endif %}{% endfor %}">
|
||
</div>
|
||
{% if cc|length > 0 %}
|
||
{% for c in cc %}
|
||
<div class="form-group">
|
||
<label for="{{ 'custom_column_' ~ c.id }}">{{ c.name }}</label>
|
||
{% if c.datatype == 'bool' %}
|
||
<select name="{{ 'custom_column_' ~ c.id }}" id="{{ 'custom_column_' ~ c.id }}" class="form-control">
|
||
<option value="None" {% if book['custom_column_' ~ c.id]|length == 0 %} selected {% endif %}></option>
|
||
<option value="True" {% if book['custom_column_' ~ c.id]|length > 0 %}{% if book['custom_column_' ~ c.id][0].value ==true %}selected{% endif %}{% endif %} >{{_('Yes')}}</option>
|
||
<option value="False" {% if book['custom_column_' ~ c.id]|length > 0 %}{% if book['custom_column_' ~ c.id][0].value ==false %}selected{% endif %}{% endif %}>{{_('No')}}</option>
|
||
</select>
|
||
{% endif %}
|
||
|
||
{% if c.datatype == 'int' or c.datatype == 'float' %}
|
||
<input type="number" step="{% if c.datatype == 'float' %}0.01{% else %}1{% endif %}" class="form-control" name="{{ 'custom_column_' ~ c.id }}" id="{{ 'custom_column_' ~ c.id }}" value="{% if book['custom_column_' ~ c.id]|length > 0 %}{{ book['custom_column_' ~ c.id][0].value }}{% endif %}">
|
||
{% endif %}
|
||
|
||
{% if c.datatype == 'text' %}
|
||
<input type="text" class="form-control" name="{{ 'custom_column_' ~ c.id }}" id="{{ 'custom_column_' ~ c.id }}"
|
||
{% if book['custom_column_' ~ c.id]|length > 0 %}
|
||
value="{% for column in book['custom_column_' ~ c.id] %}{{ column.value.strip() }}{% if not loop.last %}, {% endif %}{% endfor %}"{% endif %}>
|
||
{% endif %}
|
||
|
||
{% if c.datatype == 'series' %}
|
||
<input type="text" class="form-control" name="{{ 'custom_column_' ~ c.id }}" id="{{ 'custom_column_' ~ c.id }}"
|
||
{% if book['custom_column_' ~ c.id]|length > 0 %}
|
||
value="{% for column in book['custom_column_' ~ c.id] %} {{ '%s [%s]' % (book['custom_column_' ~ c.id][0].value, book['custom_column_' ~ c.id][0].extra|formatfloat(2)) }}{% if not loop.last %}, {% endif %}{% endfor %}"
|
||
{% endif %}>
|
||
{% endif %}
|
||
|
||
{% if c.datatype == 'datetime' %}
|
||
<div class="input-group">
|
||
<input type="text" class="datepicker form-control" name="{{ 'custom_column_' ~ c.id }}" id="{{ 'custom_column_' ~ c.id }}"
|
||
{% if book['custom_column_' ~ c.id]|length > 0 %}
|
||
value="{% if book['custom_column_' ~ c.id][0].value %}{{ book['custom_column_' ~ c.id][0].value|formatdateinput}}{% endif %}"
|
||
{% endif %}>
|
||
<input type="text" class="fake_custom_column_{{ c.id }} form-control fake-input hidden" id="fake_pubdate_{{ c.id }}"
|
||
{% if book['custom_column_' ~ c.id]|length > 0 %}
|
||
value="{% if book['custom_column_' ~ c.id][0].value %}{{book['custom_column_' ~ c.id][0].value|formatdate}}{% endif %}"
|
||
{% endif %}>
|
||
<span class="input-group-btn">
|
||
<button type="button" id="{{ 'custom_column_' ~ c.id }}_delete" class="datepicker_delete btn btn-default"><span class="glyphicon glyphicon-remove-circle"></span></button>
|
||
</span>
|
||
</div>
|
||
{% endif %}
|
||
|
||
{% if c.datatype == 'comments' %}
|
||
<textarea class="form-control tiny_editor" name="{{ 'custom_column_' ~ c.id }}" id="{{ 'custom_column_' ~ c.id }}" rows="7">{% if book['custom_column_' ~ c.id]|length > 0 %}{{book['custom_column_' ~ c.id][0].value}}{%endif%}</textarea>
|
||
{% endif %}
|
||
{% if c.datatype == 'enumeration' %}
|
||
<select class="form-control" name="{{ 'custom_column_' ~ c.id }}" id="{{ 'custom_column_' ~ c.id }}">
|
||
<option></option>
|
||
{% for opt in c.get_display_dict().enum_values %}
|
||
<option
|
||
{% if book['custom_column_' ~ c.id]|length > 0 %}
|
||
{% if book['custom_column_' ~ c.id][0].value == opt %}selected="selected"{% endif %}
|
||
{% endif %}
|
||
>{{ opt }}</option>
|
||
{% endfor %}
|
||
</select>
|
||
{% endif %}
|
||
|
||
{% if c.datatype == 'rating' %}
|
||
<input type="number" min="1" max="5" step="0.5" class="form-control" name="{{ 'custom_column_' ~ c.id }}" id="{{ 'custom_column_' ~ c.id }}"
|
||
{% if book['custom_column_' ~ c.id]|length > 0 %}
|
||
value="{{ '%.1f' % (book['custom_column_' ~ c.id][0].value / 2) }}"
|
||
{% endif %}>
|
||
{% endif %}
|
||
</div>
|
||
{% endfor %}
|
||
{% endif %}
|
||
|
||
<div class="checkbox">
|
||
<label>
|
||
<input name="detail_view" type="checkbox" checked> {{_('View Book on Save')}}
|
||
</label>
|
||
</div>
|
||
<a href="#" id="get_meta" class="btn btn-default" data-toggle="modal" data-target="#metaModal">{{_('Fetch Metadata')}}</a>
|
||
<button type="submit" id="submit" class="btn btn-default">{{_('Save')}}</button>
|
||
<a href="{{ url_for('web.show_book', book_id=book.id) }}" id="edit_cancel" class="btn btn-default">{{_('Cancel')}}</a>
|
||
</div>
|
||
</form>
|
||
|
||
{% endif %}
|
||
{% endblock %}
|
||
|
||
{% block modal %}
|
||
{{ delete_book(current_user.role_delete_books()) }}
|
||
{{ delete_confirm_modal() }}
|
||
|
||
<div class="modal fade" id="metaModal" tabindex="-1" role="dialog" aria-labelledby="metaModalLabel">
|
||
<div class="modal-dialog modal-lg" role="document">
|
||
<div class="modal-content">
|
||
<div class="modal-header">
|
||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||
<h4 class="modal-title text-center" id="metaModalLabel">{{_('Fetch Metadata')}}</h4>
|
||
<form class="padded-bottom" id="meta-search">
|
||
<div class="input-group">
|
||
<label class="sr-only" for="keyword">{{_('Keyword')}}</label>
|
||
<input type="text" class="form-control" id="keyword" name="keyword" placeholder="{{_("Search keyword")}}">
|
||
<span class="input-group-btn">
|
||
<button type="submit" class="btn btn-primary" id="do-search">{{_("Search")}}</button>
|
||
</span>
|
||
</div>
|
||
</form>
|
||
<div class="text-center"><strong>{{_('Click the cover to load metadata to the form')}}</strong></div>
|
||
</div>
|
||
<div class="modal-body">
|
||
<div class="text-center padded-bottom" id="metadata_provider">
|
||
</div>
|
||
|
||
<div id="meta-info">
|
||
{{_("Loading...")}}
|
||
</div>
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button id="meta_close" type="button" class="btn btn-default" data-dismiss="modal">{{_('Close')}}</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
{% endblock %}
|
||
|
||
{% block js %}
|
||
<script type="text/template" id="template-book-result">
|
||
<li class="media" data-related="<%= source.id %>">
|
||
<img class="pull-left img-responsive"
|
||
data-toggle="modal"
|
||
data-target="#metaModal"
|
||
src="<%= cover || "{{ url_for('static', filename='img/academicpaper.svg') }}" %>"
|
||
alt="Cover"
|
||
>
|
||
<div class="media-body">
|
||
<h4 class="media-heading">
|
||
<a class="meta_title" href="<%= url %>" target="_blank" rel="noopener"><%= title %></a>
|
||
</h4>
|
||
<p class="meta_author">{{_('Author')}}:<%= authors.join(" & ") %></p>
|
||
<% if (publisher) { %>
|
||
<p class="meta_publisher">{{_('Publisher')}}:<%= publisher %></p>
|
||
<% } %>
|
||
<% if (description) { %>
|
||
<p class="meta_description">{{_('Description')}}: <%= description %></p>
|
||
<% } %>
|
||
<p>{{_('Source')}}:
|
||
<a class="meta_source" href="<%= source.link %>" target="_blank" rel="noopener"><%= source.description %></a>
|
||
</p>
|
||
</div>
|
||
</li>
|
||
</script>
|
||
<script>
|
||
var i18nMsg = {
|
||
'loading': {{_('Loading...')|safe|tojson}},
|
||
'search_error': {{_('Search error!')|safe|tojson}},
|
||
'no_result': {{_('No Result(s) found! Please try another keyword.')|safe|tojson}},
|
||
'author': {{_('Author')|safe|tojson}},
|
||
'publisher': {{_('Publisher')|safe|tojson}},
|
||
'comments': {{_('Description')|safe|tojson}},
|
||
'source': {{_('Source')|safe|tojson}},
|
||
};
|
||
var language = '{{ current_user.locale }}';
|
||
|
||
$("#add-identifier-line").click(function() {
|
||
// create a random identifier type to have a valid name in form. This will not be used when dealing with the form
|
||
var rand_id = Math.floor(Math.random() * 1000000).toString();
|
||
var line = '<tr>';
|
||
line += '<td><input type="text" class="form-control" name="identifier-type-'+ rand_id +'" required="required" placeholder={{_('Identifier Type')|safe|tojson}}></td>';
|
||
line += '<td><input type="text" class="form-control" name="identifier-val-'+ rand_id +'" required="required" placeholder={{_('Identifier Value')|safe|tojson}}></td>';
|
||
line += '<td><a class="btn btn-default" onclick="removeIdentifierLine(this)">{{_('Remove')}}</a></td>';
|
||
line += '</tr>';
|
||
$("#identifier-table").append(line);
|
||
});
|
||
function removeIdentifierLine(el) {
|
||
$(el).parent().parent().remove();
|
||
}
|
||
|
||
</script>
|
||
<script src="{{ url_for('static', filename='js/libs/typeahead.bundle.js') }}"></script>
|
||
<script src="{{ url_for('static', filename='js/libs/bootstrap-rating-input.min.js') }}"></script>
|
||
<script src="{{ url_for('static', filename='js/get_meta.js') }}"></script>
|
||
<script src="{{ url_for('static', filename='js/libs/tinymce/tinymce.min.js') }}"></script>
|
||
<script src="{{ url_for('static', filename='js/libs/bootstrap-datepicker/bootstrap-datepicker.min.js') }}"></script>
|
||
{% if not current_user.locale == 'en' %}
|
||
<script src="{{ url_for('static', filename='js/libs/bootstrap-datepicker/locales/bootstrap-datepicker.' + current_user.locale + '.min.js') }}" charset="UTF-8"></script>
|
||
{% endif %}
|
||
<script src="{{ url_for('static', filename='js/edit_books.js') }}"></script>
|
||
<script src="{{ url_for('static', filename='js/fullscreen.js') }}"></script>
|
||
{% endblock %}
|
||
{% block header %}
|
||
<meta name="referrer" content="never">
|
||
<link href="{{ url_for('static', filename='css/libs/typeahead.css') }}" rel="stylesheet" media="screen">
|
||
<link href="{{ url_for('static', filename='css/libs/bootstrap-datepicker3.min.css') }}" rel="stylesheet" media="screen">
|
||
{% endblock %}
|