Commit 82d01c90 authored by Jack Darlington's avatar Jack Darlington

Merge branch 'master' into develop

# Conflicts:
#	cps/web.py
parents ff0e0be2 a7cd993c
......@@ -3,7 +3,6 @@
import os
import sys
import time
base_path = os.path.dirname(os.path.abspath(__file__))
# Insert local directories into path
......@@ -22,9 +21,9 @@ if __name__ == '__main__':
http_server.listen(web.ub.config.config_port)
IOLoop.instance().start()
if web.global_task == 0:
print("Performing restart of Calibre-web")
if web.helper.global_task == 0:
web.app.logger.info("Performing restart of Calibre-web")
os.execl(sys.executable, sys.executable, *sys.argv)
else:
print("Performing shutdown of Calibre-web")
web.app.logger.info("Performing shutdown of Calibre-web")
sys.exit(0)
......@@ -56,6 +56,10 @@ books_languages_link = Table('books_languages_link', Base.metadata,
Column('lang_code', Integer, ForeignKey('languages.id'), primary_key=True)
)
books_publishers_link = Table('books_publishers_link', Base.metadata,
Column('book', Integer, ForeignKey('books.id'), primary_key=True),
Column('publisher', Integer, ForeignKey('publishers.id'), primary_key=True)
)
class Identifiers(Base):
__tablename__ = 'identifiers'
......@@ -182,6 +186,21 @@ class Languages(Base):
def __repr__(self):
return u"<Languages('{0}')>".format(self.lang_code)
class Publishers(Base):
__tablename__ = 'publishers'
id = Column(Integer, primary_key=True)
name = Column(String)
sort = Column(String)
def __init__(self, name,sort):
self.name = name
self.sort = sort
def __repr__(self):
return u"<Publishers('{0},{1}')>".format(self.name, self.sort)
class Data(Base):
__tablename__ = 'data'
......@@ -224,6 +243,7 @@ class Books(Base):
series = relationship('Series', secondary=books_series_link, backref='books')
ratings = relationship('Ratings', secondary=books_ratings_link, backref='books')
languages = relationship('Languages', secondary=books_languages_link, backref='books')
publishers = relationship('Publishers', secondary=books_publishers_link, backref='books')
identifiers = relationship('Identifiers', backref='books')
def __init__(self, title, sort, author_sort, timestamp, pubdate, series_index, last_modified, path, has_cover,
......
This diff is collapsed.
......@@ -47,3 +47,7 @@ span.glyphicon.glyphicon-tags {padding-right: 5px;color: #999;vertical-align: te
.btn-primary:hover, .btn-primary:focus, .btn-primary:active, .btn-primary.active, .open .dropdown-toggle.btn-primary{ background-color: #1C5484; }
.btn-primary.disabled, .btn-primary[disabled], fieldset[disabled] .btn-primary, .btn-primary.disabled:hover, .btn-primary[disabled]:hover, fieldset[disabled] .btn-primary:hover, .btn-primary.disabled:focus, .btn-primary[disabled]:focus, fieldset[disabled] .btn-primary:focus, .btn-primary.disabled:active, .btn-primary[disabled]:active, fieldset[disabled] .btn-primary:active, .btn-primary.disabled.active, .btn-primary[disabled].active, fieldset[disabled] .btn-primary.active { background-color: #89B9E2; }
.btn-toolbar>.btn+.btn, .btn-toolbar>.btn-group+.btn, .btn-toolbar>.btn+.btn-group, .btn-toolbar>.btn-group+.btn-group { margin-left:0px; }
.spinner {margin:0 41%;}
.spinner2 {margin:0 41%;}
var displaytext;
var updateTimerID;
var updateText;
$(function() {
$('.discover .row').isotope({
......@@ -31,7 +34,9 @@ $(function() {
url: window.location.pathname+"/../../shutdown",
data: {"parameter":0},
success: function(data) {
return alert(data.text);}
$('#spinner').show();
displaytext=data.text;
window.setTimeout(restartTimer, 3000);}
});
});
$("#shutdown").click(function() {
......@@ -50,17 +55,66 @@ $(function() {
dataType: 'json',
url: window.location.pathname+"/../../get_update_status",
success: function(data) {
if (data.status == true) {
$("#check_for_update").addClass('hidden');
$("#perform_update").removeClass('hidden');
}else{
$("#check_for_update").html(button_text);
};}
if (data.status == true) {
$("#check_for_update").addClass('hidden');
$("#perform_update").removeClass('hidden');
$("#update_info").removeClass('hidden');
$("#update_info").find('span').html(data.commit);
}
}
});
});
$("#perform_update").click(function() {
$('#spinner2').show();
$.ajax({
type: "POST",
dataType: 'json',
data: { start: "True"},
url: window.location.pathname+"/../../get_updater_status",
success: function(data) {
updateText=data.text
$("#UpdateprogressDialog #Updatecontent").html(updateText[data.status]);
console.log(data.status);
updateTimerID=setInterval(updateTimer, 2000);}
});
});
});
function restartTimer() {
$('#spinner').hide();
$('#RestartDialog').modal('hide');
}
function updateTimer() {
$.ajax({
dataType: 'json',
url: window.location.pathname+"/../../get_updater_status",
success: function(data) {
console.log(data.status);
$("#UpdateprogressDialog #Updatecontent").html(updateText[data.status]);
if (data.status >6){
clearInterval(updateTimerID);
$('#spinner2').hide();
$('#UpdateprogressDialog #updateFinished').removeClass('hidden');
$("#check_for_update").removeClass('hidden');
$("#perform_update").addClass('hidden');
}
},
error: function() {
console.log('Done');
clearInterval(updateTimerID);
$('#spinner2').hide();
$("#UpdateprogressDialog #Updatecontent").html(updateText[7]);
$('#UpdateprogressDialog #updateFinished').removeClass('hidden');
$("#check_for_update").removeClass('hidden');
$("#perform_update").addClass('hidden');
}
});
}
$(window).resize(function(event) {
$('.discover .row').isotope('reLayout');
});
......@@ -2,6 +2,7 @@
{% block body %}
<div class="discover">
<h2>{{_('User list')}}</h2>
<div id="divLoading"></div>
<table class="table table-striped" id="table_user">
<tr>
<th>{{_('Nickname')}}</th>
......@@ -76,11 +77,13 @@
<div class="btn btn-default"><a href="{{url_for('configuration')}}">{{_('Configuration')}}</a></div>
<h2>{{_('Administration')}}</h2>
{% if not development %}
<p>{{_('Current commit timestamp')}}: {{commit}} </p>
<div class="btn btn-default" data-toggle="modal" data-target="#RestartDialog">{{_('Restart Calibre-web')}}</a></div>
<div class="btn btn-default" data-toggle="modal" data-target="#ShutdownDialog">{{_('Stop Calibre-web')}}</a></div>
<div class="btn btn-default" id="check_for_update">{{_('Check for update')}}</a></div>
<a href="{{url_for('update')}}" class="btn btn-default hidden" id="perform_update">{{_('Perform Update')}}</a>
<div>{{_('Current commit timestamp')}}: <span>{{commit}} </span></div>
<div class="hidden" id="update_info">{{_('Newest commit timestamp')}}: <span></span></div>
<p></p>
<div class="btn btn-default" data-toggle="modal" data-target="#RestartDialog">{{_('Restart Calibre-web')}}</div>
<div class="btn btn-default" data-toggle="modal" data-target="#ShutdownDialog">{{_('Stop Calibre-web')}}</div>
<div class="btn btn-default" id="check_for_update">{{_('Check for update')}}</div>
<div class="btn btn-default hidden" id="perform_update" data-toggle="modal" data-target="#UpdateprogressDialog">{{_('Perform Update')}}</div>
{% endif %}
</div>
<!-- Modal -->
......@@ -88,15 +91,17 @@
<div class="modal-dialog modal-sm">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header bg-info">
</div>
<div class="modal-header bg-info"></div>
<div class="modal-body text-center">
<p>{{_('Do you really want to restart Calibre-web?')}}</p>
<button type="button" class="btn btn-default" id="restart" data-dismiss="modal">{{_('Ok')}}</button>
<div id="spinner" class="spinner" style="display:none;">
<img id="img-spinner" src="/static/css/images/loading-icon.gif"/>
</div>
<p></p>
<button type="button" class="btn btn-default" id="restart" >{{_('Ok')}}</button>
<button type="button" class="btn btn-default" data-dismiss="modal">{{_('Back')}}</button>
</div>
</div>
</div>
</div>
<div id="ShutdownDialog" class="modal fade" role="dialog">
......@@ -114,5 +119,23 @@
</div>
</div>
<div id="UpdateprogressDialog" class="modal fade" role="dialog">
<div class="modal-dialog modal-sm">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header bg-info text-center">
<span>{{_('Updating, please do not reload page')}}</span>
</div>
<div class="modal-body text-center">
<div id="spinner2" class="spinner2" style="display:none;">
<img id="img-spinner" src="/static/css/images/loading-icon.gif"/>
</div>
<p></p>
<div id="Updatecontent"></div>
<p></p>
<button type="button" class="btn btn-default hidden" id="updateFinished" data-dismiss="modal">{{_('Ok')}}</button>
</div>
</div>
</div>
</div>
{% endblock %}
......@@ -50,6 +50,7 @@
{% if entry.identifiers|length > 0 %}
<div class="identifiers">
<p>
<span class="glyphicon glyphicon-link"></span>
{% for identifier in entry.identifiers %}
<a href="{{identifier}}" target="_blank" class="btn btn-xs btn-success" role="button">{{identifier.formatType()}}</a>
......@@ -66,10 +67,16 @@
{% for tag in entry.tags %}
<a href="{{ url_for('category', id=tag.id) }}" class="btn btn-xs btn-info" role="button">{{tag.name}}</a>
{%endfor%}
</div>
</p>
{% endif %}
{% if entry.publishers|length > 0 %}
<div class="publishers">
<p>
<span>{{_('Publisher')}}:{% for publisher in entry.publishers %} {{publisher.name}}{% if not loop.last %},{% endif %}{% endfor %}</span>
</p>
</div>
{% endif %}
{% if entry.pubdate[:10] != '0101-01-01' %}
<p>{{_('Publishing date')}}: {{entry.pubdate|formatdate}} </p>
{% endif %}
......
......@@ -65,7 +65,7 @@
<div class="navbar-collapse collapse">
{% if g.user.is_authenticated or g.user.is_anonymous() %}
<ul class="nav navbar-nav ">
<li><a href="{{url_for('advanced_search')}}"><span class="glyphicon glyphicon-search"></span> {{_('Advanced Search')}}</a></li>
<li><a href="{{url_for('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">
......
......@@ -10,63 +10,67 @@
<label for="bookAuthor">{{_('Author')}}</label>
<input type="text" class="form-control typeahead" name="author_name" id="bookAuthor" value="" autocomplete="off">
</div>
<label for="Tags">{{_('Tags')}}</label>
<div class="form-group">
<label for="Publisher">{{_('Publisher')}}</label>
<input type="text" class="form-control" name="publisher" id="publisher" value="">
</div>
<label for="include_tag">{{_('Tags')}}</label>
<div class="form-group" id="test">
<div class="btn-toolbar btn-toolbar-lg" data-toggle="buttons">
{% for tag in tags %}
<label id="tag_{{tag.id}}" class="btn btn-primary tags_click">
<input type="checkbox" autocomplete="off" name="include_tag" value="{{tag.id}}">{{tag.name}}</input>
<input type="checkbox" autocomplete="off" name="include_tag" id="include_tag" value="{{tag.id}}">{{tag.name}}</input>
</label>
{% endfor %}
</div>
</div>
<label for="Tags">{{_('Exclude Tags')}}</label>
<label for="exclude_tag">{{_('Exclude Tags')}}</label>
<div class="form-group">
<div class="btn-toolbar btn-toolbar-lg" data-toggle="buttons">
{% for tag in tags %}
<label id="tag_{{tag.id}}" class="btn btn-danger tags_click">
<input type="checkbox" autocomplete="off" name="exclude_tag" value="{{tag.id}}">{{tag.name}}</input>
<input type="checkbox" autocomplete="off" name="exclude_tag" id="exclude_tag" value="{{tag.id}}">{{tag.name}}</input>
</label>
{% endfor %}
</div>
</div>
<label for="Series">{{_('Series')}}</label>
<label for="include_serie">{{_('Series')}}</label>
<div class="form-group">
<div class="btn-toolbar btn-toolbar-lg" data-toggle="buttons">
{% for serie in series %}
<label id="serie_{{serie.id}}" class="btn btn-primary serie_click">
<input type="checkbox" autocomplete="off" name="include_serie" value="{{serie.id}}">{{serie.name}}</input>
<input type="checkbox" autocomplete="off" name="include_serie" id="include_serie" value="{{serie.id}}">{{serie.name}}</input>
</label>
{% endfor %}
</div>
</div>
<label for="Series">{{_('Exclude Series')}}</label>
<label for="exclude_serie">{{_('Exclude Series')}}</label>
<div class="form-group">
<div class="btn-toolbar btn-toolbar-lg" data-toggle="buttons">
{% for serie in series %}
<label id="serie_{{serie.id}}" class="btn btn-danger serie_click">
<input type="checkbox" autocomplete="off" name="exclude_serie" value="{{serie.id}}">{{serie.name}}</input>
<input type="checkbox" autocomplete="off" name="exclude_serie" id="exclude_serie" value="{{serie.id}}">{{serie.name}}</input>
</label>
{% endfor %}
</div>
</div>
{% if languages %}
<label for="Languages">{{_('Languages')}}</label>
<label for="include_language">{{_('Languages')}}</label>
<div class="form-group">
<div class="btn-toolbar btn-toolbar-lg" data-toggle="buttons">
{% for language in languages %}
<label id="language_{{language.id}}" class="btn btn-primary serie_click">
<input type="checkbox" autocomplete="off" name="include_language" value="{{language.id}}">{{language.name}}</input>
<input type="checkbox" autocomplete="off" name="include_language" id="include_language" value="{{language.id}}">{{language.name}}</input>
</label>
{% endfor %}
</div>
</div>
<label for="Languages">{{_('Exclude Languages')}}</label>
<label for="exclude_language">{{_('Exclude Languages')}}</label>
<div class="form-group">
<div class="btn-toolbar btn-toolbar-lg" data-toggle="buttons">
{% for language in languages %}
<label id="language_{{language.id}}" class="btn btn-danger language_click">
<input type="checkbox" autocomplete="off" name="exclude_language" value="{{language.id}}">{{language.name}}</input>
<input type="checkbox" autocomplete="off" name="exclude_language" id="exclude_language" value="{{language.id}}">{{language.name}}</input>
</label>
{% endfor %}
</div>
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment