Book list for merging
This commit is contained in:
parent
827b0c6e50
commit
0dd0605a1f
85
cps/db.py
85
cps/db.py
|
@ -30,7 +30,8 @@ from sqlalchemy import create_engine
|
||||||
from sqlalchemy import Table, Column, ForeignKey, CheckConstraint
|
from sqlalchemy import Table, Column, ForeignKey, CheckConstraint
|
||||||
from sqlalchemy import String, Integer, Boolean, TIMESTAMP, Float
|
from sqlalchemy import String, Integer, Boolean, TIMESTAMP, Float
|
||||||
from sqlalchemy.orm import relationship, sessionmaker, scoped_session
|
from sqlalchemy.orm import relationship, sessionmaker, scoped_session
|
||||||
from sqlalchemy.ext.declarative import declarative_base
|
from sqlalchemy.orm.collections import InstrumentedList
|
||||||
|
from sqlalchemy.ext.declarative import declarative_base, DeclarativeMeta
|
||||||
from sqlalchemy.exc import OperationalError
|
from sqlalchemy.exc import OperationalError
|
||||||
from flask_login import current_user
|
from flask_login import current_user
|
||||||
from sqlalchemy.sql.expression import and_, true, false, text, func, or_
|
from sqlalchemy.sql.expression import and_, true, false, text, func, or_
|
||||||
|
@ -97,6 +98,9 @@ class Identifiers(Base):
|
||||||
self.type = id_type
|
self.type = id_type
|
||||||
self.book = book
|
self.book = book
|
||||||
|
|
||||||
|
#def get(self):
|
||||||
|
# return {self.type: self.val}
|
||||||
|
|
||||||
def formatType(self):
|
def formatType(self):
|
||||||
if self.type == "amazon":
|
if self.type == "amazon":
|
||||||
return u"Amazon"
|
return u"Amazon"
|
||||||
|
@ -149,6 +153,9 @@ class Comments(Base):
|
||||||
self.text = text
|
self.text = text
|
||||||
self.book = book
|
self.book = book
|
||||||
|
|
||||||
|
def get(self):
|
||||||
|
return self.text
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return u"<Comments({0})>".format(self.text)
|
return u"<Comments({0})>".format(self.text)
|
||||||
|
|
||||||
|
@ -162,6 +169,9 @@ class Tags(Base):
|
||||||
def __init__(self, name):
|
def __init__(self, name):
|
||||||
self.name = name
|
self.name = name
|
||||||
|
|
||||||
|
def get(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return u"<Tags('{0})>".format(self.name)
|
return u"<Tags('{0})>".format(self.name)
|
||||||
|
|
||||||
|
@ -179,6 +189,9 @@ class Authors(Base):
|
||||||
self.sort = sort
|
self.sort = sort
|
||||||
self.link = link
|
self.link = link
|
||||||
|
|
||||||
|
def get(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return u"<Authors('{0},{1}{2}')>".format(self.name, self.sort, self.link)
|
return u"<Authors('{0},{1}{2}')>".format(self.name, self.sort, self.link)
|
||||||
|
|
||||||
|
@ -194,6 +207,9 @@ class Series(Base):
|
||||||
self.name = name
|
self.name = name
|
||||||
self.sort = sort
|
self.sort = sort
|
||||||
|
|
||||||
|
def get(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return u"<Series('{0},{1}')>".format(self.name, self.sort)
|
return u"<Series('{0},{1}')>".format(self.name, self.sort)
|
||||||
|
|
||||||
|
@ -207,6 +223,9 @@ class Ratings(Base):
|
||||||
def __init__(self, rating):
|
def __init__(self, rating):
|
||||||
self.rating = rating
|
self.rating = rating
|
||||||
|
|
||||||
|
def get(self):
|
||||||
|
return self.rating
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return u"<Ratings('{0}')>".format(self.rating)
|
return u"<Ratings('{0}')>".format(self.rating)
|
||||||
|
|
||||||
|
@ -220,6 +239,9 @@ class Languages(Base):
|
||||||
def __init__(self, lang_code):
|
def __init__(self, lang_code):
|
||||||
self.lang_code = lang_code
|
self.lang_code = lang_code
|
||||||
|
|
||||||
|
def get(self):
|
||||||
|
return self.lang_code
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return u"<Languages('{0}')>".format(self.lang_code)
|
return u"<Languages('{0}')>".format(self.lang_code)
|
||||||
|
|
||||||
|
@ -235,6 +257,9 @@ class Publishers(Base):
|
||||||
self.name = name
|
self.name = name
|
||||||
self.sort = sort
|
self.sort = sort
|
||||||
|
|
||||||
|
def get(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return u"<Publishers('{0},{1}')>".format(self.name, self.sort)
|
return u"<Publishers('{0},{1}')>".format(self.name, self.sort)
|
||||||
|
|
||||||
|
@ -255,6 +280,10 @@ class Data(Base):
|
||||||
self.uncompressed_size = uncompressed_size
|
self.uncompressed_size = uncompressed_size
|
||||||
self.name = name
|
self.name = name
|
||||||
|
|
||||||
|
# ToDo: Check
|
||||||
|
def get(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return u"<Data('{0},{1}{2}{3}')>".format(self.book, self.format, self.uncompressed_size, self.name)
|
return u"<Data('{0},{1}{2}{3}')>".format(self.book, self.format, self.uncompressed_size, self.name)
|
||||||
|
|
||||||
|
@ -301,6 +330,9 @@ class Books(Base):
|
||||||
self.path = path
|
self.path = path
|
||||||
self.has_cover = has_cover
|
self.has_cover = has_cover
|
||||||
|
|
||||||
|
#def as_dict(self):
|
||||||
|
# return {c.name: getattr(self, c.name) for c in self.__table__.columns}
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return u"<Books('{0},{1}{2}{3}{4}{5}{6}{7}{8}')>".format(self.title, self.sort, self.author_sort,
|
return u"<Books('{0},{1}{2}{3}{4}{5}{6}{7}{8}')>".format(self.title, self.sort, self.author_sort,
|
||||||
self.timestamp, self.pubdate, self.series_index,
|
self.timestamp, self.pubdate, self.series_index,
|
||||||
|
@ -329,6 +361,39 @@ class Custom_Columns(Base):
|
||||||
display_dict['enum_values'] = [x.decode('unicode_escape') for x in display_dict['enum_values']]
|
display_dict['enum_values'] = [x.decode('unicode_escape') for x in display_dict['enum_values']]
|
||||||
return display_dict
|
return display_dict
|
||||||
|
|
||||||
|
class AlchemyEncoder(json.JSONEncoder):
|
||||||
|
|
||||||
|
def default(self, obj):
|
||||||
|
if isinstance(obj.__class__, DeclarativeMeta):
|
||||||
|
# an SQLAlchemy class
|
||||||
|
fields = {}
|
||||||
|
for field in [x for x in dir(obj) if not x.startswith('_') and x != 'metadata']:
|
||||||
|
if field == 'books':
|
||||||
|
continue
|
||||||
|
data = obj.__getattribute__(field)
|
||||||
|
try:
|
||||||
|
if isinstance(data, str):
|
||||||
|
data = data.replace("'","\'")
|
||||||
|
elif isinstance(data, InstrumentedList):
|
||||||
|
el =list()
|
||||||
|
for ele in data:
|
||||||
|
if ele.get:
|
||||||
|
el.append(ele.get())
|
||||||
|
else:
|
||||||
|
el.append(json.dumps(ele, cls=AlchemyEncoder))
|
||||||
|
data =",".join(el)
|
||||||
|
if data == '[]':
|
||||||
|
data = ""
|
||||||
|
else:
|
||||||
|
json.dumps(data)
|
||||||
|
fields[field] = data
|
||||||
|
except:
|
||||||
|
fields[field] = ""
|
||||||
|
# a json-encodable dict
|
||||||
|
return fields
|
||||||
|
|
||||||
|
return json.JSONEncoder.default(self, obj)
|
||||||
|
|
||||||
|
|
||||||
class CalibreDB(threading.Thread):
|
class CalibreDB(threading.Thread):
|
||||||
|
|
||||||
|
@ -507,10 +572,11 @@ class CalibreDB(threading.Thread):
|
||||||
pos_content_cc_filter, ~neg_content_cc_filter, archived_filter)
|
pos_content_cc_filter, ~neg_content_cc_filter, archived_filter)
|
||||||
|
|
||||||
# Fill indexpage with all requested data from database
|
# Fill indexpage with all requested data from database
|
||||||
def fill_indexpage(self, page, database, db_filter, order, *join):
|
def fill_indexpage(self, page, pagesize, database, db_filter, order, *join):
|
||||||
return self.fill_indexpage_with_archived_books(page, database, db_filter, order, False, *join)
|
return self.fill_indexpage_with_archived_books(page, pagesize, database, db_filter, order, False, *join)
|
||||||
|
|
||||||
def fill_indexpage_with_archived_books(self, page, database, db_filter, order, allow_show_archived, *join):
|
def fill_indexpage_with_archived_books(self, page, pagesize, database, db_filter, order, allow_show_archived, *join):
|
||||||
|
pagesize = pagesize or self.config.config_books_per_page
|
||||||
if current_user.show_detail_random():
|
if current_user.show_detail_random():
|
||||||
randm = self.session.query(Books) \
|
randm = self.session.query(Books) \
|
||||||
.filter(self.common_filters(allow_show_archived)) \
|
.filter(self.common_filters(allow_show_archived)) \
|
||||||
|
@ -518,14 +584,14 @@ class CalibreDB(threading.Thread):
|
||||||
.limit(self.config.config_random_books)
|
.limit(self.config.config_random_books)
|
||||||
else:
|
else:
|
||||||
randm = false()
|
randm = false()
|
||||||
off = int(int(self.config.config_books_per_page) * (page - 1))
|
off = int(int(pagesize) * (page - 1))
|
||||||
query = self.session.query(database) \
|
query = self.session.query(database) \
|
||||||
.join(*join, isouter=True) \
|
.join(*join, isouter=True) \
|
||||||
.filter(db_filter) \
|
.filter(db_filter) \
|
||||||
.filter(self.common_filters(allow_show_archived))
|
.filter(self.common_filters(allow_show_archived))
|
||||||
pagination = Pagination(page, self.config.config_books_per_page,
|
pagination = Pagination(page, pagesize,
|
||||||
len(query.all()))
|
len(query.all()))
|
||||||
entries = query.order_by(*order).offset(off).limit(self.config.config_books_per_page).all()
|
entries = query.order_by(*order).offset(off).limit(pagesize).all()
|
||||||
for book in entries:
|
for book in entries:
|
||||||
book = self.order_authors(book)
|
book = self.order_authors(book)
|
||||||
return entries, randm, pagination
|
return entries, randm, pagination
|
||||||
|
@ -565,7 +631,8 @@ class CalibreDB(threading.Thread):
|
||||||
.filter(and_(Books.authors.any(and_(*q)), func.lower(Books.title).ilike("%" + title + "%"))).first()
|
.filter(and_(Books.authors.any(and_(*q)), func.lower(Books.title).ilike("%" + title + "%"))).first()
|
||||||
|
|
||||||
# read search results from calibre-database and return it (function is used for feed and simple search
|
# read search results from calibre-database and return it (function is used for feed and simple search
|
||||||
def get_search_results(self, term):
|
def get_search_results(self, term, order=None, limit=-1):
|
||||||
|
order = order or [Books.sort]
|
||||||
term.strip().lower()
|
term.strip().lower()
|
||||||
self.session.connection().connection.connection.create_function("lower", 1, lcase)
|
self.session.connection().connection.connection.create_function("lower", 1, lcase)
|
||||||
q = list()
|
q = list()
|
||||||
|
@ -578,7 +645,7 @@ class CalibreDB(threading.Thread):
|
||||||
Books.authors.any(and_(*q)),
|
Books.authors.any(and_(*q)),
|
||||||
Books.publishers.any(func.lower(Publishers.name).ilike("%" + term + "%")),
|
Books.publishers.any(func.lower(Publishers.name).ilike("%" + term + "%")),
|
||||||
func.lower(Books.title).ilike("%" + term + "%")
|
func.lower(Books.title).ilike("%" + term + "%")
|
||||||
)).order_by(Books.sort).all()
|
)).order_by(*order).limit(limit).all()
|
||||||
|
|
||||||
# Creates for all stored languages a translated speaking name in the array for the UI
|
# Creates for all stored languages a translated speaking name in the array for the UI
|
||||||
def speaking_language(self, languages=None):
|
def speaking_language(self, languages=None):
|
||||||
|
|
18
cps/opds.py
18
cps/opds.py
|
@ -100,7 +100,7 @@ def feed_normal_search():
|
||||||
@requires_basic_auth_if_no_ano
|
@requires_basic_auth_if_no_ano
|
||||||
def feed_new():
|
def feed_new():
|
||||||
off = request.args.get("offset") or 0
|
off = request.args.get("offset") or 0
|
||||||
entries, __, pagination = calibre_db.fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1),
|
entries, __, pagination = calibre_db.fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1), 0,
|
||||||
db.Books, True, [db.Books.timestamp.desc()])
|
db.Books, True, [db.Books.timestamp.desc()])
|
||||||
return render_xml_template('feed.xml', entries=entries, pagination=pagination)
|
return render_xml_template('feed.xml', entries=entries, pagination=pagination)
|
||||||
|
|
||||||
|
@ -118,7 +118,7 @@ def feed_discover():
|
||||||
@requires_basic_auth_if_no_ano
|
@requires_basic_auth_if_no_ano
|
||||||
def feed_best_rated():
|
def feed_best_rated():
|
||||||
off = request.args.get("offset") or 0
|
off = request.args.get("offset") or 0
|
||||||
entries, __, pagination = calibre_db.fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1),
|
entries, __, pagination = calibre_db.fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1), 0,
|
||||||
db.Books, db.Books.ratings.any(db.Ratings.rating > 9),
|
db.Books, db.Books.ratings.any(db.Ratings.rating > 9),
|
||||||
[db.Books.timestamp.desc()])
|
[db.Books.timestamp.desc()])
|
||||||
return render_xml_template('feed.xml', entries=entries, pagination=pagination)
|
return render_xml_template('feed.xml', entries=entries, pagination=pagination)
|
||||||
|
@ -164,7 +164,7 @@ def feed_authorindex():
|
||||||
@requires_basic_auth_if_no_ano
|
@requires_basic_auth_if_no_ano
|
||||||
def feed_author(book_id):
|
def feed_author(book_id):
|
||||||
off = request.args.get("offset") or 0
|
off = request.args.get("offset") or 0
|
||||||
entries, __, pagination = calibre_db.fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1),
|
entries, __, pagination = calibre_db.fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1), 0,
|
||||||
db.Books,
|
db.Books,
|
||||||
db.Books.authors.any(db.Authors.id == book_id),
|
db.Books.authors.any(db.Authors.id == book_id),
|
||||||
[db.Books.timestamp.desc()])
|
[db.Books.timestamp.desc()])
|
||||||
|
@ -190,7 +190,7 @@ def feed_publisherindex():
|
||||||
@requires_basic_auth_if_no_ano
|
@requires_basic_auth_if_no_ano
|
||||||
def feed_publisher(book_id):
|
def feed_publisher(book_id):
|
||||||
off = request.args.get("offset") or 0
|
off = request.args.get("offset") or 0
|
||||||
entries, __, pagination = calibre_db.fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1),
|
entries, __, pagination = calibre_db.fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1), 0,
|
||||||
db.Books,
|
db.Books,
|
||||||
db.Books.publishers.any(db.Publishers.id == book_id),
|
db.Books.publishers.any(db.Publishers.id == book_id),
|
||||||
[db.Books.timestamp.desc()])
|
[db.Books.timestamp.desc()])
|
||||||
|
@ -218,7 +218,7 @@ def feed_categoryindex():
|
||||||
@requires_basic_auth_if_no_ano
|
@requires_basic_auth_if_no_ano
|
||||||
def feed_category(book_id):
|
def feed_category(book_id):
|
||||||
off = request.args.get("offset") or 0
|
off = request.args.get("offset") or 0
|
||||||
entries, __, pagination = calibre_db.fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1),
|
entries, __, pagination = calibre_db.fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1), 0,
|
||||||
db.Books,
|
db.Books,
|
||||||
db.Books.tags.any(db.Tags.id == book_id),
|
db.Books.tags.any(db.Tags.id == book_id),
|
||||||
[db.Books.timestamp.desc()])
|
[db.Books.timestamp.desc()])
|
||||||
|
@ -245,7 +245,7 @@ def feed_seriesindex():
|
||||||
@requires_basic_auth_if_no_ano
|
@requires_basic_auth_if_no_ano
|
||||||
def feed_series(book_id):
|
def feed_series(book_id):
|
||||||
off = request.args.get("offset") or 0
|
off = request.args.get("offset") or 0
|
||||||
entries, __, pagination = calibre_db.fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1),
|
entries, __, pagination = calibre_db.fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1), 0,
|
||||||
db.Books,
|
db.Books,
|
||||||
db.Books.series.any(db.Series.id == book_id),
|
db.Books.series.any(db.Series.id == book_id),
|
||||||
[db.Books.series_index])
|
[db.Books.series_index])
|
||||||
|
@ -276,7 +276,7 @@ def feed_ratingindex():
|
||||||
@requires_basic_auth_if_no_ano
|
@requires_basic_auth_if_no_ano
|
||||||
def feed_ratings(book_id):
|
def feed_ratings(book_id):
|
||||||
off = request.args.get("offset") or 0
|
off = request.args.get("offset") or 0
|
||||||
entries, __, pagination = calibre_db.fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1),
|
entries, __, pagination = calibre_db.fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1), 0,
|
||||||
db.Books,
|
db.Books,
|
||||||
db.Books.ratings.any(db.Ratings.id == book_id),
|
db.Books.ratings.any(db.Ratings.id == book_id),
|
||||||
[db.Books.timestamp.desc()])
|
[db.Books.timestamp.desc()])
|
||||||
|
@ -304,7 +304,7 @@ def feed_formatindex():
|
||||||
@requires_basic_auth_if_no_ano
|
@requires_basic_auth_if_no_ano
|
||||||
def feed_format(book_id):
|
def feed_format(book_id):
|
||||||
off = request.args.get("offset") or 0
|
off = request.args.get("offset") or 0
|
||||||
entries, __, pagination = calibre_db.fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1),
|
entries, __, pagination = calibre_db.fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1), 0,
|
||||||
db.Books,
|
db.Books,
|
||||||
db.Books.data.any(db.Data.format == book_id.upper()),
|
db.Books.data.any(db.Data.format == book_id.upper()),
|
||||||
[db.Books.timestamp.desc()])
|
[db.Books.timestamp.desc()])
|
||||||
|
@ -338,7 +338,7 @@ def feed_languagesindex():
|
||||||
@requires_basic_auth_if_no_ano
|
@requires_basic_auth_if_no_ano
|
||||||
def feed_languages(book_id):
|
def feed_languages(book_id):
|
||||||
off = request.args.get("offset") or 0
|
off = request.args.get("offset") or 0
|
||||||
entries, __, pagination = calibre_db.fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1),
|
entries, __, pagination = calibre_db.fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1), 0,
|
||||||
db.Books,
|
db.Books,
|
||||||
db.Books.languages.any(db.Languages.id == book_id),
|
db.Books.languages.any(db.Languages.id == book_id),
|
||||||
[db.Books.timestamp.desc()])
|
[db.Books.timestamp.desc()])
|
||||||
|
|
11
cps/static/css/libs/bootstrap-table.min.css
vendored
11
cps/static/css/libs/bootstrap-table.min.css
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
10
cps/static/js/libs/bootstrap-table/locale/bootstrap-table-fi-FI.min.js
vendored
Normal file
10
cps/static/js/libs/bootstrap-table/locale/bootstrap-table-fi-FI.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
10
cps/static/js/libs/bootstrap-table/locale/bootstrap-table-fr-CH.min.js
vendored
Normal file
10
cps/static/js/libs/bootstrap-table/locale/bootstrap-table-fr-CH.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
10
cps/static/js/libs/bootstrap-table/locale/bootstrap-table-fr-LU.min.js
vendored
Normal file
10
cps/static/js/libs/bootstrap-table/locale/bootstrap-table-fr-LU.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
10
cps/static/js/libs/bootstrap-table/locale/bootstrap-table-nl-BE.min.js
vendored
Normal file
10
cps/static/js/libs/bootstrap-table/locale/bootstrap-table-nl-BE.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
10
cps/static/js/libs/bootstrap-table/locale/bootstrap-table-sr-Cyrl-RS.min.js
vendored
Normal file
10
cps/static/js/libs/bootstrap-table/locale/bootstrap-table-sr-Cyrl-RS.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
10
cps/static/js/libs/bootstrap-table/locale/bootstrap-table-sr-Latn-RS.min.js
vendored
Normal file
10
cps/static/js/libs/bootstrap-table/locale/bootstrap-table-sr-Latn-RS.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -15,10 +15,16 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* exported TableActions, RestrictionActions*/
|
/* exported TableActions, RestrictionActions, EbookActions*/
|
||||||
|
|
||||||
$(function() {
|
$(function() {
|
||||||
|
|
||||||
|
$("#books-table").bootstrapTable({
|
||||||
|
formatNoMatches: function () {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
$("#domain_allow_submit").click(function(event) {
|
$("#domain_allow_submit").click(function(event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
$("#domain_add_allow").ajaxForm();
|
$("#domain_add_allow").ajaxForm();
|
||||||
|
@ -213,3 +219,13 @@ function RestrictionActions (value, row) {
|
||||||
"</div>"
|
"</div>"
|
||||||
].join("");
|
].join("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Function for deleting books */
|
||||||
|
function EbookActions (value, row) {
|
||||||
|
return [
|
||||||
|
"<div class=\"danger remove\" listbook-id=\"" + row.id + "\" title=\"Remove\">",
|
||||||
|
"<i class=\"glyphicon glyphicon-trash\"></i>",
|
||||||
|
"</div>"
|
||||||
|
].join("");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,59 +1,55 @@
|
||||||
{% extends "layout.html" %}
|
{% extends "layout.html" %}
|
||||||
|
{% block header %}
|
||||||
|
<link href="{{ url_for('static', filename='css/libs/bootstrap-table.min.css') }}" rel="stylesheet">
|
||||||
|
<link href="{{ url_for('static', filename='css/libs/bootstrap-editable.css') }}" rel="stylesheet">
|
||||||
|
{% endblock %}
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<h1 class="{{page}}">{{_(title)}}</h1>
|
<h2 class="{{page}}">{{_(title)}}</h2>
|
||||||
|
<!--
|
||||||
|
|
||||||
<div class="filterheader hidden-xs hidden-sm">
|
|
||||||
{% if entries.__len__() %}
|
|
||||||
{% if data == 'author' %}
|
|
||||||
<button id="sort_name" class="btn btn-primary"><b>B,A <-> A B</b></button>
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
|
||||||
<button id="desc" class="btn btn-primary"><span class="glyphicon glyphicon-sort-by-alphabet"></span></button>
|
|
||||||
<button id="asc" class="btn btn-primary"><span class="glyphicon glyphicon-sort-by-alphabet-alt"></span></button>
|
|
||||||
{% if charlist|length %}
|
|
||||||
<button id="all" class="btn btn-primary">{{_('All')}}</button>
|
|
||||||
{% endif %}
|
|
||||||
<div class="btn-group character" role="group">
|
|
||||||
{% for char in charlist%}
|
|
||||||
<button class="btn btn-primary char">{{char.char}}</button>
|
|
||||||
{% endfor %}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{% if title == "Series" %}
|
-->
|
||||||
<button class="update-view btn btn-primary" href="#" data-target="series_view" data-view="grid">Grid</button>
|
<table class="table table-no-bordered table-striped"
|
||||||
{% endif %}
|
data-toggle="table"
|
||||||
</div>
|
data-side-pagination="server"
|
||||||
<div class="container">
|
data-pagination="true"
|
||||||
<div id="list" class="col-xs-12 col-sm-6">
|
data-pagination-detail-h-align=" hidden"
|
||||||
{% for entry in entries %}
|
data-pagination-h-align="left"
|
||||||
{% if loop.index0 == (loop.length/2+loop.length%2)|int and loop.length > 20 %}
|
id="books-table"
|
||||||
</div>
|
data-url="{{url_for('web.list_books')}}"
|
||||||
<div id="second" class="col-xs-12 col-sm-6">
|
data-id-field="id"
|
||||||
{% endif %}
|
data-editable-mode="inline"
|
||||||
<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 %}">
|
data-show-columns="true"
|
||||||
<div class="col-xs-2 col-sm-2 col-md-1" align="left"><span class="badge">{{entry.count}}</span></div>
|
data-search="true"
|
||||||
<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 %}">
|
data-search-align="left"
|
||||||
{% if entry.name %}
|
data-show-search-button="false"
|
||||||
<div class="rating">
|
data-checkbox-header="false"
|
||||||
{% for number in range(entry.name) %}
|
data-maintain-meta-data="true">
|
||||||
<span class="glyphicon glyphicon-star good"></span>
|
<thead>
|
||||||
{% if loop.last and loop.index < 5 %}
|
<tr>
|
||||||
{% for numer in range(5 - loop.index) %}
|
<!--th data-field="title" id="title" data-editable-type="text" data-editable-url="{{ url_for('web.edit_list_book')}}" data-editable="true" data-editable-title="{{_('Enter title')}}"></th-->
|
||||||
<span class="glyphicon glyphicon-star"></span>
|
<th data-checkbox="true" data-sortable="true"></th>
|
||||||
{% endfor %}
|
<th data-field="id" id="id" data-visible="false" data-switchable="false"></th>
|
||||||
{% endif %}
|
<th data-field="title" id="title" data-sortable="true">Title</th>
|
||||||
{% endfor %}
|
<th data-field="sort" id="sort" data-sortable="true">Sort</th>
|
||||||
</div>
|
<th data-field="author_sort" id="author_sort" data-sortable="true">Authors Sort</th>
|
||||||
{% else %}
|
<th data-field="authors" id="authors" data-sortable="true">Authors</th>
|
||||||
{% if entry.format %}
|
<th data-field="tags" id="tags" data-sortable="true">Tags</th>
|
||||||
{{entry.format}}
|
<th data-field="series" id="series" data-sortable="true">Series</th>
|
||||||
{% else %}
|
<th data-field="series_index" id="series_index" data-sortable="true">Series Index</th>
|
||||||
{{entry[0].name}}{% endif %}{% endif %}</a></div>
|
<th data-field="languages" id="languages" data-sortable="true">Language</th>
|
||||||
</div>
|
<th data-field="pubdate" id="pubdate" data-sortable="true">Publishing Date</th>
|
||||||
{% endfor %}
|
<th data-field="publishers" id="publishers" data-sortable="true">Publishers</th>
|
||||||
</div>
|
{% if g.user.role_edit() %}
|
||||||
</div>
|
<th data-align="right" data-formatter="EbookActions" data-switchable="false"></th>
|
||||||
|
{% endif %}
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
</table>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block js %}
|
{% block js %}
|
||||||
<script src="{{ url_for('static', filename='js/filter_list.js') }}"></script>
|
<script src="{{ url_for('static', filename='js/libs/bootstrap-table/bootstrap-table.min.js') }}"></script>
|
||||||
|
<script src="{{ url_for('static', filename='js/libs/bootstrap-table/bootstrap-table-editable.min.js') }}"></script>
|
||||||
|
<script src="{{ url_for('static', filename='js/libs/bootstrap-table/bootstrap-editable.min.js') }}"></script>
|
||||||
|
<script src="{{ url_for('static', filename='js/table.js') }}"></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
54
cps/web.py
54
cps/web.py
|
@ -620,7 +620,7 @@ def get_matching_tags():
|
||||||
@web.route('/page/<int:page>')
|
@web.route('/page/<int:page>')
|
||||||
@login_required_if_no_ano
|
@login_required_if_no_ano
|
||||||
def index(page):
|
def index(page):
|
||||||
entries, random, pagination = calibre_db.fill_indexpage(page, db.Books, True, [db.Books.timestamp.desc()])
|
entries, random, pagination = calibre_db.fill_indexpage(page, 0, db.Books, True, [db.Books.timestamp.desc()])
|
||||||
return render_title_template('index.html', random=random, entries=entries, pagination=pagination,
|
return render_title_template('index.html', random=random, entries=entries, pagination=pagination,
|
||||||
title=_(u"Recently Added Books"), page="root")
|
title=_(u"Recently Added Books"), page="root")
|
||||||
|
|
||||||
|
@ -647,7 +647,7 @@ def books_list(data, sort, book_id, page):
|
||||||
|
|
||||||
if data == "rated":
|
if data == "rated":
|
||||||
if current_user.check_visibility(constants.SIDEBAR_BEST_RATED):
|
if current_user.check_visibility(constants.SIDEBAR_BEST_RATED):
|
||||||
entries, random, pagination = calibre_db.fill_indexpage(page,
|
entries, random, pagination = calibre_db.fill_indexpage(page, 0,
|
||||||
db.Books,
|
db.Books,
|
||||||
db.Books.ratings.any(db.Ratings.rating > 9),
|
db.Books.ratings.any(db.Ratings.rating > 9),
|
||||||
order)
|
order)
|
||||||
|
@ -657,7 +657,7 @@ def books_list(data, sort, book_id, page):
|
||||||
abort(404)
|
abort(404)
|
||||||
elif data == "discover":
|
elif data == "discover":
|
||||||
if current_user.check_visibility(constants.SIDEBAR_RANDOM):
|
if current_user.check_visibility(constants.SIDEBAR_RANDOM):
|
||||||
entries, __, pagination = calibre_db.fill_indexpage(page, db.Books, True, [func.randomblob(2)])
|
entries, __, pagination = calibre_db.fill_indexpage(page, 0, db.Books, True, [func.randomblob(2)])
|
||||||
pagination = Pagination(1, config.config_books_per_page, config.config_books_per_page)
|
pagination = Pagination(1, config.config_books_per_page, config.config_books_per_page)
|
||||||
return render_title_template('discover.html', entries=entries, pagination=pagination, id=book_id,
|
return render_title_template('discover.html', entries=entries, pagination=pagination, id=book_id,
|
||||||
title=_(u"Discover (Random Books)"), page="discover")
|
title=_(u"Discover (Random Books)"), page="discover")
|
||||||
|
@ -686,7 +686,7 @@ def books_list(data, sort, book_id, page):
|
||||||
elif data == "archived":
|
elif data == "archived":
|
||||||
return render_archived_books(page, order)
|
return render_archived_books(page, order)
|
||||||
else:
|
else:
|
||||||
entries, random, pagination = calibre_db.fill_indexpage(page, db.Books, True, order)
|
entries, random, pagination = calibre_db.fill_indexpage(page, 0, db.Books, True, order)
|
||||||
return render_title_template('index.html', random=random, entries=entries, pagination=pagination,
|
return render_title_template('index.html', random=random, entries=entries, pagination=pagination,
|
||||||
title=_(u"Books"), page="newest")
|
title=_(u"Books"), page="newest")
|
||||||
|
|
||||||
|
@ -721,7 +721,7 @@ def render_hot_books(page):
|
||||||
|
|
||||||
|
|
||||||
def render_author_books(page, author_id, order):
|
def render_author_books(page, author_id, order):
|
||||||
entries, __, pagination = calibre_db.fill_indexpage(page,
|
entries, __, pagination = calibre_db.fill_indexpage(page, 0,
|
||||||
db.Books,
|
db.Books,
|
||||||
db.Books.authors.any(db.Authors.id == author_id),
|
db.Books.authors.any(db.Authors.id == author_id),
|
||||||
[order[0], db.Series.name, db.Books.series_index],
|
[order[0], db.Series.name, db.Books.series_index],
|
||||||
|
@ -749,7 +749,7 @@ def render_author_books(page, author_id, order):
|
||||||
def render_publisher_books(page, book_id, order):
|
def render_publisher_books(page, book_id, order):
|
||||||
publisher = calibre_db.session.query(db.Publishers).filter(db.Publishers.id == book_id).first()
|
publisher = calibre_db.session.query(db.Publishers).filter(db.Publishers.id == book_id).first()
|
||||||
if publisher:
|
if publisher:
|
||||||
entries, random, pagination = calibre_db.fill_indexpage(page,
|
entries, random, pagination = calibre_db.fill_indexpage(page, 0,
|
||||||
db.Books,
|
db.Books,
|
||||||
db.Books.publishers.any(db.Publishers.id == book_id),
|
db.Books.publishers.any(db.Publishers.id == book_id),
|
||||||
[db.Series.name, order[0], db.Books.series_index],
|
[db.Series.name, order[0], db.Books.series_index],
|
||||||
|
@ -764,7 +764,7 @@ def render_publisher_books(page, book_id, order):
|
||||||
def render_series_books(page, book_id, order):
|
def render_series_books(page, book_id, order):
|
||||||
name = calibre_db.session.query(db.Series).filter(db.Series.id == book_id).first()
|
name = calibre_db.session.query(db.Series).filter(db.Series.id == book_id).first()
|
||||||
if name:
|
if name:
|
||||||
entries, random, pagination = calibre_db.fill_indexpage(page,
|
entries, random, pagination = calibre_db.fill_indexpage(page, 0,
|
||||||
db.Books,
|
db.Books,
|
||||||
db.Books.series.any(db.Series.id == book_id),
|
db.Books.series.any(db.Series.id == book_id),
|
||||||
[db.Books.series_index, order[0]])
|
[db.Books.series_index, order[0]])
|
||||||
|
@ -776,7 +776,7 @@ def render_series_books(page, book_id, order):
|
||||||
|
|
||||||
def render_ratings_books(page, book_id, order):
|
def render_ratings_books(page, book_id, order):
|
||||||
name = calibre_db.session.query(db.Ratings).filter(db.Ratings.id == book_id).first()
|
name = calibre_db.session.query(db.Ratings).filter(db.Ratings.id == book_id).first()
|
||||||
entries, random, pagination = calibre_db.fill_indexpage(page,
|
entries, random, pagination = calibre_db.fill_indexpage(page, 0,
|
||||||
db.Books,
|
db.Books,
|
||||||
db.Books.ratings.any(db.Ratings.id == book_id),
|
db.Books.ratings.any(db.Ratings.id == book_id),
|
||||||
[db.Books.timestamp.desc(), order[0]])
|
[db.Books.timestamp.desc(), order[0]])
|
||||||
|
@ -790,7 +790,7 @@ def render_ratings_books(page, book_id, order):
|
||||||
def render_formats_books(page, book_id, order):
|
def render_formats_books(page, book_id, order):
|
||||||
name = calibre_db.session.query(db.Data).filter(db.Data.format == book_id.upper()).first()
|
name = calibre_db.session.query(db.Data).filter(db.Data.format == book_id.upper()).first()
|
||||||
if name:
|
if name:
|
||||||
entries, random, pagination = calibre_db.fill_indexpage(page,
|
entries, random, pagination = calibre_db.fill_indexpage(page, 0,
|
||||||
db.Books,
|
db.Books,
|
||||||
db.Books.data.any(db.Data.format == book_id.upper()),
|
db.Books.data.any(db.Data.format == book_id.upper()),
|
||||||
[db.Books.timestamp.desc(), order[0]])
|
[db.Books.timestamp.desc(), order[0]])
|
||||||
|
@ -803,7 +803,7 @@ def render_formats_books(page, book_id, order):
|
||||||
def render_category_books(page, book_id, order):
|
def render_category_books(page, book_id, order):
|
||||||
name = calibre_db.session.query(db.Tags).filter(db.Tags.id == book_id).first()
|
name = calibre_db.session.query(db.Tags).filter(db.Tags.id == book_id).first()
|
||||||
if name:
|
if name:
|
||||||
entries, random, pagination = calibre_db.fill_indexpage(page,
|
entries, random, pagination = calibre_db.fill_indexpage(page, 0,
|
||||||
db.Books,
|
db.Books,
|
||||||
db.Books.tags.any(db.Tags.id == book_id),
|
db.Books.tags.any(db.Tags.id == book_id),
|
||||||
[order[0], db.Series.name, db.Books.series_index],
|
[order[0], db.Series.name, db.Books.series_index],
|
||||||
|
@ -823,7 +823,7 @@ def render_language_books(page, name, order):
|
||||||
lang_name = _(isoLanguages.get(part3=name).name)
|
lang_name = _(isoLanguages.get(part3=name).name)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
abort(404)
|
abort(404)
|
||||||
entries, random, pagination = calibre_db.fill_indexpage(page,
|
entries, random, pagination = calibre_db.fill_indexpage(page, 0,
|
||||||
db.Books,
|
db.Books,
|
||||||
db.Books.languages.any(db.Languages.lang_code == name),
|
db.Books.languages.any(db.Languages.lang_code == name),
|
||||||
[db.Books.timestamp.desc(), order[0]])
|
[db.Books.timestamp.desc(), order[0]])
|
||||||
|
@ -834,14 +834,32 @@ def render_language_books(page, name, order):
|
||||||
@web.route("/table")
|
@web.route("/table")
|
||||||
@login_required_if_no_ano
|
@login_required_if_no_ano
|
||||||
def books_table():
|
def books_table():
|
||||||
return render_title_template('book_table.html', title=_(u"Books list"), page="table")
|
# __, __, pagination = calibre_db.fill_indexpage(1, 0, db.Books, True, [db.Books.timestamp.asc()])
|
||||||
|
return render_title_template('book_table.html', title=_(u"Books list"), page="book_table") #, pagination=pagination)
|
||||||
|
|
||||||
@web.route("/ajax/listbooks")
|
@web.route("/ajax/listbooks")
|
||||||
@login_required_if_no_ano
|
@login_required_if_no_ano
|
||||||
def list_books():
|
def list_books():
|
||||||
order = [db.Books.timestamp.desc()]
|
off = request.args.get("offset") or 0
|
||||||
entries, __, __ = calibre_db.fill_indexpage(1, db.Books, True, order)
|
limit = request.args.get("limit") or config.config_books_per_page
|
||||||
js_list = json.dumps(entries, cls=db.AlchemyEncoder)
|
sort = request.args.get("sort")
|
||||||
|
if request.args.get("order") == 'asc':
|
||||||
|
order = [db.Books.timestamp.asc()]
|
||||||
|
else:
|
||||||
|
order = [db.Books.timestamp.desc()]
|
||||||
|
search = request.args.get("search")
|
||||||
|
total_count = calibre_db.session.query(db.Books).count()
|
||||||
|
if search:
|
||||||
|
entries = calibre_db.get_search_results(search, order, limit)
|
||||||
|
#ToDo not right web.py 1259
|
||||||
|
filtered_count = len(entries)
|
||||||
|
else:
|
||||||
|
entries, __, __ = calibre_db.fill_indexpage((int(off) / (int(limit)) + 1), limit, db.Books, True, order)
|
||||||
|
filtered_count = total_count
|
||||||
|
table_entries = {'totalNotFiltered': total_count, 'total': filtered_count, "rows": entries}
|
||||||
|
js_list = json.dumps(table_entries, cls=db.AlchemyEncoder)
|
||||||
|
#js_list = json.dumps(entries, cls=db.AlchemyEncoder)
|
||||||
|
|
||||||
response = make_response(js_list)
|
response = make_response(js_list)
|
||||||
response.headers["Content-Type"] = "application/json; charset=utf-8"
|
response.headers["Content-Type"] = "application/json; charset=utf-8"
|
||||||
return response
|
return response
|
||||||
|
@ -1210,7 +1228,7 @@ def render_read_books(page, are_read, as_xml=False, order=None, *args, **kwargs)
|
||||||
ub.ReadBook.read_status == ub.ReadBook.STATUS_FINISHED)
|
ub.ReadBook.read_status == ub.ReadBook.STATUS_FINISHED)
|
||||||
else:
|
else:
|
||||||
db_filter = coalesce(ub.ReadBook.read_status, 0) != ub.ReadBook.STATUS_FINISHED
|
db_filter = coalesce(ub.ReadBook.read_status, 0) != ub.ReadBook.STATUS_FINISHED
|
||||||
entries, random, pagination = calibre_db.fill_indexpage(page,
|
entries, random, pagination = calibre_db.fill_indexpage(page, 0,
|
||||||
db.Books,
|
db.Books,
|
||||||
db_filter,
|
db_filter,
|
||||||
order,
|
order,
|
||||||
|
@ -1221,7 +1239,7 @@ def render_read_books(page, are_read, as_xml=False, order=None, *args, **kwargs)
|
||||||
db_filter = db.cc_classes[config.config_read_column].value == True
|
db_filter = db.cc_classes[config.config_read_column].value == True
|
||||||
else:
|
else:
|
||||||
db_filter = coalesce(db.cc_classes[config.config_read_column].value, False) != True
|
db_filter = coalesce(db.cc_classes[config.config_read_column].value, False) != True
|
||||||
entries, random, pagination = calibre_db.fill_indexpage(page,
|
entries, random, pagination = calibre_db.fill_indexpage(page, 0,
|
||||||
db.Books,
|
db.Books,
|
||||||
db_filter,
|
db_filter,
|
||||||
order,
|
order,
|
||||||
|
@ -1259,7 +1277,7 @@ def render_archived_books(page, order):
|
||||||
|
|
||||||
archived_filter = db.Books.id.in_(archived_book_ids)
|
archived_filter = db.Books.id.in_(archived_book_ids)
|
||||||
|
|
||||||
entries, random, pagination = calibre_db.fill_indexpage_with_archived_books(page,
|
entries, random, pagination = calibre_db.fill_indexpage_with_archived_books(page, 0,
|
||||||
db.Books,
|
db.Books,
|
||||||
archived_filter,
|
archived_filter,
|
||||||
order,
|
order,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user