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
82
cps/db.py
82
cps/db.py
|
@ -11,10 +11,8 @@ from ub import config
|
|||
import ub
|
||||
|
||||
session = None
|
||||
cc_exceptions = None
|
||||
cc_exceptions = ['datetime', 'int', 'comments', 'float', 'composite', 'series']
|
||||
cc_classes = None
|
||||
cc_ids = None
|
||||
books_custom_column_links = None
|
||||
engine = None
|
||||
|
||||
|
||||
|
@ -283,12 +281,9 @@ class Custom_Columns(Base):
|
|||
|
||||
|
||||
def setup_db():
|
||||
global session
|
||||
global cc_exceptions
|
||||
global cc_classes
|
||||
global cc_ids
|
||||
global books_custom_column_links
|
||||
global engine
|
||||
global session
|
||||
global cc_classes
|
||||
|
||||
if config.config_calibre_dir is None or config.config_calibre_dir == u'':
|
||||
return False
|
||||
|
@ -297,7 +292,6 @@ def setup_db():
|
|||
engine = create_engine('sqlite:///{0}'.format(dbpath.encode('utf-8')), echo=False, isolation_level="SERIALIZABLE")
|
||||
try:
|
||||
conn = engine.connect()
|
||||
|
||||
except:
|
||||
content = ub.session.query(ub.Settings).first()
|
||||
content.config_calibre_dir = None
|
||||
|
@ -311,43 +305,43 @@ def setup_db():
|
|||
config.loadSettings()
|
||||
conn.connection.create_function('title_sort', 1, title_sort)
|
||||
|
||||
cc = conn.execute("SELECT id, datatype FROM custom_columns")
|
||||
if not cc_classes:
|
||||
cc = conn.execute("SELECT id, datatype FROM custom_columns")
|
||||
|
||||
cc_ids = []
|
||||
cc_exceptions = ['datetime', 'int', 'comments', 'float', 'composite', 'series']
|
||||
books_custom_column_links = {}
|
||||
cc_classes = {}
|
||||
for row in cc:
|
||||
if row.datatype not in cc_exceptions:
|
||||
books_custom_column_links[row.id] = Table('books_custom_column_' + str(row.id) + '_link', Base.metadata,
|
||||
Column('book', Integer, ForeignKey('books.id'),
|
||||
primary_key=True),
|
||||
Column('value', Integer,
|
||||
ForeignKey('custom_column_' + str(row.id) + '.id'),
|
||||
primary_key=True)
|
||||
)
|
||||
cc_ids.append([row.id, row.datatype])
|
||||
if row.datatype == 'bool':
|
||||
ccdict = {'__tablename__': 'custom_column_' + str(row.id),
|
||||
'id': Column(Integer, primary_key=True),
|
||||
'book': Column(Integer, ForeignKey('books.id')),
|
||||
'value': Column(Boolean)}
|
||||
cc_ids = []
|
||||
books_custom_column_links = {}
|
||||
cc_classes = {}
|
||||
for row in cc:
|
||||
if row.datatype not in cc_exceptions:
|
||||
books_custom_column_links[row.id] = Table('books_custom_column_' + str(row.id) + '_link', Base.metadata,
|
||||
Column('book', Integer, ForeignKey('books.id'),
|
||||
primary_key=True),
|
||||
Column('value', Integer,
|
||||
ForeignKey('custom_column_' + str(row.id) + '.id'),
|
||||
primary_key=True)
|
||||
)
|
||||
cc_ids.append([row.id, row.datatype])
|
||||
if row.datatype == 'bool':
|
||||
ccdict = {'__tablename__': 'custom_column_' + str(row.id),
|
||||
'id': Column(Integer, primary_key=True),
|
||||
'book': Column(Integer, ForeignKey('books.id')),
|
||||
'value': Column(Boolean)}
|
||||
else:
|
||||
ccdict = {'__tablename__': 'custom_column_' + str(row.id),
|
||||
'id': Column(Integer, primary_key=True),
|
||||
'value': Column(String)}
|
||||
cc_classes[row.id] = type('Custom_Column_' + str(row.id), (Base,), ccdict)
|
||||
|
||||
for id in cc_ids:
|
||||
if id[1] == 'bool':
|
||||
setattr(Books, 'custom_column_' + str(id[0]), relationship(cc_classes[id[0]],
|
||||
primaryjoin=(
|
||||
Books.id == cc_classes[id[0]].book),
|
||||
backref='books'))
|
||||
else:
|
||||
ccdict = {'__tablename__': 'custom_column_' + str(row.id),
|
||||
'id': Column(Integer, primary_key=True),
|
||||
'value': Column(String)}
|
||||
cc_classes[row.id] = type('Custom_Column_' + str(row.id), (Base,), ccdict)
|
||||
|
||||
for id in cc_ids:
|
||||
if id[1] == 'bool':
|
||||
setattr(Books, 'custom_column_' + str(id[0]), relationship(cc_classes[id[0]],
|
||||
primaryjoin=(
|
||||
Books.id == cc_classes[id[0]].book),
|
||||
backref='books'))
|
||||
else:
|
||||
setattr(Books, 'custom_column_' + str(id[0]), relationship(cc_classes[id[0]],
|
||||
secondary=books_custom_column_links[id[0]],
|
||||
backref='books'))
|
||||
setattr(Books, 'custom_column_' + str(id[0]), relationship(cc_classes[id[0]],
|
||||
secondary=books_custom_column_links[id[0]],
|
||||
backref='books'))
|
||||
|
||||
# Base.metadata.create_all(engine)
|
||||
Session = sessionmaker()
|
||||
|
|
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() {
|
||||
$('#spinner2').show();
|
||||
$.ajax({
|
||||
|
|
|
@ -80,6 +80,7 @@
|
|||
<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" 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="#ShutdownDialog">{{_('Stop Calibre-web')}}</div>
|
||||
<div class="btn btn-default" id="check_for_update">{{_('Check for update')}}</div>
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
</div>
|
||||
<div class="form-group">
|
||||
<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 class="form-group">
|
||||
<label for="cover_url">{{_('Cover URL (jpg)')}}</label>
|
||||
|
@ -114,6 +114,7 @@
|
|||
{% block js %}
|
||||
<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/libs/bootstrap-rating-input.min.js') }}"></script>
|
||||
{% endblock %}
|
||||
{% block header %}
|
||||
<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>
|
||||
</author>
|
||||
|
||||
{% if entries[0] %}
|
||||
{% for entry in entries %}
|
||||
<entry>
|
||||
<title>{{entry.title}}</title>
|
||||
|
@ -60,6 +61,7 @@
|
|||
{% endfor %}
|
||||
</entry>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% for entry in listelements %}
|
||||
<entry>
|
||||
<title>{{entry.name}}</title>
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
<div class="discover load-more">
|
||||
<h2>{{title}}</h2>
|
||||
<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">
|
||||
|
@ -76,6 +77,7 @@
|
|||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% 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'
|
||||
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
|
||||
def get_locale():
|
||||
# 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)
|
||||
entries = list()
|
||||
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__()
|
||||
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)
|
||||
|
@ -839,7 +854,13 @@ def hot_books(page):
|
|||
hot_books = all_books.offset(off).limit(config.config_books_per_page)
|
||||
entries = list()
|
||||
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__()
|
||||
pagination = Pagination(page, config.config_books_per_page, numBooks)
|
||||
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')
|
||||
return json.dumps(showtext)
|
||||
else:
|
||||
if task == 2:
|
||||
db.session.close()
|
||||
db.engine.dispose()
|
||||
db.setup_db()
|
||||
return json.dumps({})
|
||||
abort(404)
|
||||
|
||||
@app.route("/update")
|
||||
|
|
Loading…
Reference in New Issue
Block a user