mirror of
https://github.com/janeczku/calibre-web
synced 2024-11-24 18:47:23 +00:00
Added editing star rating graphically
Added ability to reload database connection (refresh problem) Bugfix display hot books (no hot books, hot books are deleted books, no longer result in error 500)
This commit is contained in:
parent
789a1af68f
commit
edadf84710
14
cps/db.py
14
cps/db.py
@ -11,10 +11,8 @@ from ub import config
|
|||||||
import ub
|
import ub
|
||||||
|
|
||||||
session = None
|
session = None
|
||||||
cc_exceptions = None
|
cc_exceptions = ['datetime', 'int', 'comments', 'float', 'composite', 'series']
|
||||||
cc_classes = None
|
cc_classes = None
|
||||||
cc_ids = None
|
|
||||||
books_custom_column_links = None
|
|
||||||
engine = None
|
engine = None
|
||||||
|
|
||||||
|
|
||||||
@ -283,12 +281,9 @@ class Custom_Columns(Base):
|
|||||||
|
|
||||||
|
|
||||||
def setup_db():
|
def setup_db():
|
||||||
global session
|
|
||||||
global cc_exceptions
|
|
||||||
global cc_classes
|
|
||||||
global cc_ids
|
|
||||||
global books_custom_column_links
|
|
||||||
global engine
|
global engine
|
||||||
|
global session
|
||||||
|
global cc_classes
|
||||||
|
|
||||||
if config.config_calibre_dir is None or config.config_calibre_dir == u'':
|
if config.config_calibre_dir is None or config.config_calibre_dir == u'':
|
||||||
return False
|
return False
|
||||||
@ -297,7 +292,6 @@ def setup_db():
|
|||||||
engine = create_engine('sqlite:///{0}'.format(dbpath.encode('utf-8')), echo=False, isolation_level="SERIALIZABLE")
|
engine = create_engine('sqlite:///{0}'.format(dbpath.encode('utf-8')), echo=False, isolation_level="SERIALIZABLE")
|
||||||
try:
|
try:
|
||||||
conn = engine.connect()
|
conn = engine.connect()
|
||||||
|
|
||||||
except:
|
except:
|
||||||
content = ub.session.query(ub.Settings).first()
|
content = ub.session.query(ub.Settings).first()
|
||||||
content.config_calibre_dir = None
|
content.config_calibre_dir = None
|
||||||
@ -311,10 +305,10 @@ def setup_db():
|
|||||||
config.loadSettings()
|
config.loadSettings()
|
||||||
conn.connection.create_function('title_sort', 1, title_sort)
|
conn.connection.create_function('title_sort', 1, title_sort)
|
||||||
|
|
||||||
|
if not cc_classes:
|
||||||
cc = conn.execute("SELECT id, datatype FROM custom_columns")
|
cc = conn.execute("SELECT id, datatype FROM custom_columns")
|
||||||
|
|
||||||
cc_ids = []
|
cc_ids = []
|
||||||
cc_exceptions = ['datetime', 'int', 'comments', 'float', 'composite', 'series']
|
|
||||||
books_custom_column_links = {}
|
books_custom_column_links = {}
|
||||||
cc_classes = {}
|
cc_classes = {}
|
||||||
for row in cc:
|
for row in cc:
|
||||||
|
1
cps/static/js/libs/bootstrap-rating-input.min.js
vendored
Normal file
1
cps/static/js/libs/bootstrap-rating-input.min.js
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
!function(a){"use strict";function b(a){return"[data-value"+(a?"="+a:"")+"]"}function c(a,b,c){var d=c.activeIcon,e=c.inactiveIcon;a.removeClass(b?e:d).addClass(b?d:e)}function d(b,c){var d=a.extend({},i,b.data(),c);return d.inline=""===d.inline||d.inline,d.readonly=""===d.readonly||d.readonly,d.clearable===!1?d.clearableLabel="":d.clearableLabel=d.clearable,d.clearable=""===d.clearable||d.clearable,d}function e(b,c){if(c.inline)var d=a('<span class="rating-input"></span>');else var d=a('<div class="rating-input"></div>');d.addClass(b.attr("class")),d.removeClass("rating");for(var e=c.min;e<=c.max;e++)d.append('<i class="'+c.iconLib+'" data-value="'+e+'"></i>');return c.clearable&&!c.readonly&&d.append(" ").append('<a class="'+f+'"><i class="'+c.iconLib+" "+c.clearableIcon+'"/>'+c.clearableLabel+"</a>"),d}var f="rating-clear",g="."+f,h="hidden",i={min:1,max:5,"empty-value":0,iconLib:"glyphicon",activeIcon:"glyphicon-star",inactiveIcon:"glyphicon-star-empty",clearable:!1,clearableIcon:"glyphicon-remove",clearableRemain:!1,inline:!1,readonly:!1},j=function(a,b){var c=this.$input=a;this.options=d(c,b);var f=this.$el=e(c,this.options);c.addClass(h).before(f),c.attr("type","hidden"),this.highlight(c.val())};j.VERSION="0.4.0",j.DEFAULTS=i,j.prototype={clear:function(){this.setValue(this.options["empty-value"])},setValue:function(a){this.highlight(a),this.updateInput(a)},highlight:function(a,d){var e=this.options,f=this.$el;if(a>=this.options.min&&a<=this.options.max){var i=f.find(b(a));c(i.prevAll("i").andSelf(),!0,e),c(i.nextAll("i"),!1,e)}else c(f.find(b()),!1,e);d||(this.options.clearableRemain?f.find(g).removeClass(h):a&&a!=this.options["empty-value"]?f.find(g).removeClass(h):f.find(g).addClass(h))},updateInput:function(a){var b=this.$input;b.val()!=a&&b.val(a).change()}};var k=a.fn.rating=function(c){return this.filter("input[type=number]").each(function(){var d=a(this),e="object"==typeof c&&c||{},f=new j(d,e);f.options.readonly||f.$el.on("mouseenter",b(),function(){f.highlight(a(this).data("value"),!0)}).on("mouseleave",b(),function(){f.highlight(d.val(),!0)}).on("click",b(),function(){f.setValue(a(this).data("value"))}).on("click",g,function(){f.clear()})})};k.Constructor=j,a(function(){a("input.rating[type=number]").each(function(){a(this).rating()})})}(jQuery);
|
@ -65,6 +65,13 @@ $(function() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
$("#restart_database").click(function() {
|
||||||
|
$.ajax({
|
||||||
|
dataType: 'json',
|
||||||
|
url: window.location.pathname+"/../../shutdown",
|
||||||
|
data: {"parameter":2}
|
||||||
|
});
|
||||||
|
});
|
||||||
$("#perform_update").click(function() {
|
$("#perform_update").click(function() {
|
||||||
$('#spinner2').show();
|
$('#spinner2').show();
|
||||||
$.ajax({
|
$.ajax({
|
||||||
|
@ -80,6 +80,7 @@
|
|||||||
<div>{{_('Current commit timestamp')}}: <span>{{commit}} </span></div>
|
<div>{{_('Current commit timestamp')}}: <span>{{commit}} </span></div>
|
||||||
<div class="hidden" id="update_info">{{_('Newest commit timestamp')}}: <span></span></div>
|
<div class="hidden" id="update_info">{{_('Newest commit timestamp')}}: <span></span></div>
|
||||||
<p></p>
|
<p></p>
|
||||||
|
<div class="btn btn-default" id="restart_database">{{_('Reconnect to Calibre DB')}}</div>
|
||||||
<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="#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" 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" id="check_for_update">{{_('Check for update')}}</div>
|
||||||
|
@ -39,7 +39,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="rating">{{_('Rating')}}</label>
|
<label for="rating">{{_('Rating')}}</label>
|
||||||
<input type="number" min="0" max="5" step="1" class="form-control" name="rating" id="rating" value="{% if book.ratings %}{{book.ratings[0].rating / 2}}{% endif %}">
|
<input type="number" name="rating" id="rating" class="rating input-lg" data-clearable="" value="{% if book.ratings %}{{(book.ratings[0].rating / 2)|int}}{% endif %}">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="cover_url">{{_('Cover URL (jpg)')}}</label>
|
<label for="cover_url">{{_('Cover URL (jpg)')}}</label>
|
||||||
@ -114,6 +114,7 @@
|
|||||||
{% block js %}
|
{% block js %}
|
||||||
<script src="{{ url_for('static', filename='js/libs/typeahead.bundle.js') }}"></script>
|
<script src="{{ url_for('static', filename='js/libs/typeahead.bundle.js') }}"></script>
|
||||||
<script src="{{ url_for('static', filename='js/edit_books.js') }}"></script>
|
<script src="{{ url_for('static', filename='js/edit_books.js') }}"></script>
|
||||||
|
<script src="{{ url_for('static', filename='js/libs/bootstrap-rating-input.min.js') }}"></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block header %}
|
{% block header %}
|
||||||
<link href="{{ url_for('static', filename='css/libs/typeahead.css') }}" rel="stylesheet" media="screen">
|
<link href="{{ url_for('static', filename='css/libs/typeahead.css') }}" rel="stylesheet" media="screen">
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
<uri>https://github.com/janeczku/calibre-web</uri>
|
<uri>https://github.com/janeczku/calibre-web</uri>
|
||||||
</author>
|
</author>
|
||||||
|
|
||||||
|
{% if entries[0] %}
|
||||||
{% for entry in entries %}
|
{% for entry in entries %}
|
||||||
<entry>
|
<entry>
|
||||||
<title>{{entry.title}}</title>
|
<title>{{entry.title}}</title>
|
||||||
@ -60,6 +61,7 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
</entry>
|
</entry>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
{% for entry in listelements %}
|
{% for entry in listelements %}
|
||||||
<entry>
|
<entry>
|
||||||
<title>{{entry.name}}</title>
|
<title>{{entry.name}}</title>
|
||||||
|
@ -40,6 +40,7 @@
|
|||||||
<div class="discover load-more">
|
<div class="discover load-more">
|
||||||
<h2>{{title}}</h2>
|
<h2>{{title}}</h2>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
{% if entries[0] %}
|
||||||
{% for entry in entries %}
|
{% for entry in entries %}
|
||||||
<div id="books" class="col-sm-3 col-lg-2 col-xs-6 book">
|
<div id="books" class="col-sm-3 col-lg-2 col-xs-6 book">
|
||||||
<div class="cover">
|
<div class="cover">
|
||||||
@ -76,6 +77,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
30
cps/web.py
30
cps/web.py
@ -136,6 +136,15 @@ lm.anonymous_user = ub.Anonymous
|
|||||||
app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'
|
app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'
|
||||||
db.setup_db()
|
db.setup_db()
|
||||||
|
|
||||||
|
if config.config_log_level == logging.DEBUG :
|
||||||
|
logging.getLogger("sqlalchemy.engine").addHandler(file_handler)
|
||||||
|
logging.getLogger("sqlalchemy.engine").setLevel(logging.INFO)
|
||||||
|
logging.getLogger("sqlalchemy.pool").addHandler(file_handler)
|
||||||
|
logging.getLogger("sqlalchemy.pool").setLevel(config.config_log_level)
|
||||||
|
logging.getLogger("sqlalchemy.orm").addHandler(file_handler)
|
||||||
|
logging.getLogger("sqlalchemy.orm").setLevel(config.config_log_level)
|
||||||
|
|
||||||
|
|
||||||
@babel.localeselector
|
@babel.localeselector
|
||||||
def get_locale():
|
def get_locale():
|
||||||
# if a user is logged in, use the locale from the user settings
|
# if a user is logged in, use the locale from the user settings
|
||||||
@ -550,7 +559,13 @@ def feed_hot():
|
|||||||
hot_books = all_books.offset(off).limit(config.config_books_per_page)
|
hot_books = all_books.offset(off).limit(config.config_books_per_page)
|
||||||
entries = list()
|
entries = list()
|
||||||
for book in hot_books:
|
for book in hot_books:
|
||||||
entries.append(db.session.query(db.Books).filter(filter).filter(db.Books.id == book.Downloads.book_id).first())
|
downloadBook = db.session.query(db.Books).filter(db.Books.id == book.Downloads.book_id).first()
|
||||||
|
if downloadBook:
|
||||||
|
entries.append(
|
||||||
|
db.session.query(db.Books).filter(filter).filter(db.Books.id == book.Downloads.book_id).first())
|
||||||
|
else:
|
||||||
|
ub.session.query(ub.Downloads).filter(book.Downloads.book_id == ub.Downloads.book_id).delete()
|
||||||
|
ub.session.commit()
|
||||||
numBooks = entries.__len__()
|
numBooks = entries.__len__()
|
||||||
pagination = Pagination((int(off) / (int(config.config_books_per_page)) + 1), config.config_books_per_page, numBooks)
|
pagination = Pagination((int(off) / (int(config.config_books_per_page)) + 1), config.config_books_per_page, numBooks)
|
||||||
xml = render_title_template('feed.xml', entries=entries, pagination=pagination)
|
xml = render_title_template('feed.xml', entries=entries, pagination=pagination)
|
||||||
@ -839,7 +854,13 @@ def hot_books(page):
|
|||||||
hot_books = all_books.offset(off).limit(config.config_books_per_page)
|
hot_books = all_books.offset(off).limit(config.config_books_per_page)
|
||||||
entries = list()
|
entries = list()
|
||||||
for book in hot_books:
|
for book in hot_books:
|
||||||
entries.append(db.session.query(db.Books).filter(filter).filter(db.Books.id == book.Downloads.book_id).first())
|
downloadBook = db.session.query(db.Books).filter(db.Books.id == book.Downloads.book_id).first()
|
||||||
|
if downloadBook:
|
||||||
|
entries.append(
|
||||||
|
db.session.query(db.Books).filter(filter).filter(db.Books.id == book.Downloads.book_id).first())
|
||||||
|
else:
|
||||||
|
ub.session.query(ub.Downloads).filter(book.Downloads.book_id == ub.Downloads.book_id).delete()
|
||||||
|
ub.session.commit()
|
||||||
numBooks = entries.__len__()
|
numBooks = entries.__len__()
|
||||||
pagination = Pagination(page, config.config_books_per_page, numBooks)
|
pagination = Pagination(page, config.config_books_per_page, numBooks)
|
||||||
return render_title_template('index.html', random=random, entries=entries, pagination=pagination,
|
return render_title_template('index.html', random=random, entries=entries, pagination=pagination,
|
||||||
@ -1085,6 +1106,11 @@ def shutdown():
|
|||||||
showtext['text'] = _(u'Performing shutdown of server, please close window')
|
showtext['text'] = _(u'Performing shutdown of server, please close window')
|
||||||
return json.dumps(showtext)
|
return json.dumps(showtext)
|
||||||
else:
|
else:
|
||||||
|
if task == 2:
|
||||||
|
db.session.close()
|
||||||
|
db.engine.dispose()
|
||||||
|
db.setup_db()
|
||||||
|
return json.dumps({})
|
||||||
abort(404)
|
abort(404)
|
||||||
|
|
||||||
@app.route("/update")
|
@app.route("/update")
|
||||||
|
Loading…
Reference in New Issue
Block a user