Internal paged Search prepared
Search for table list is working
This commit is contained in:
parent
628658972c
commit
4038cb5b85
9 changed files with 82 additions and 48 deletions
11
cps/db.py
11
cps/db.py
|
@ -631,21 +631,26 @@ class CalibreDB(threading.Thread):
|
|||
.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
|
||||
def get_search_results(self, term, order=None, limit=-1):
|
||||
def get_search_results(self, term, offset=None, order=None, limit=None):
|
||||
order = order or [Books.sort]
|
||||
if offset != None and limit != None:
|
||||
offset = int(offset)
|
||||
limit = offset + int(limit)
|
||||
term.strip().lower()
|
||||
self.session.connection().connection.connection.create_function("lower", 1, lcase)
|
||||
q = list()
|
||||
authorterms = re.split("[, ]+", term)
|
||||
for authorterm in authorterms:
|
||||
q.append(Books.authors.any(func.lower(Authors.name).ilike("%" + authorterm + "%")))
|
||||
return self.session.query(Books).filter(self.common_filters(True)).filter(
|
||||
result = self.session.query(Books).filter(self.common_filters(True)).filter(
|
||||
or_(Books.tags.any(func.lower(Tags.name).ilike("%" + term + "%")),
|
||||
Books.series.any(func.lower(Series.name).ilike("%" + term + "%")),
|
||||
Books.authors.any(and_(*q)),
|
||||
Books.publishers.any(func.lower(Publishers.name).ilike("%" + term + "%")),
|
||||
func.lower(Books.title).ilike("%" + term + "%")
|
||||
)).order_by(*order).limit(limit).all()
|
||||
)).order_by(*order).all()
|
||||
result_count = len(result)
|
||||
return result[offset:limit], result_count
|
||||
|
||||
# Creates for all stored languages a translated speaking name in the array for the UI
|
||||
def speaking_language(self, languages=None):
|
||||
|
|
|
@ -408,7 +408,7 @@ def get_metadata_calibre_companion(uuid, library):
|
|||
|
||||
def feed_search(term):
|
||||
if term:
|
||||
entries = calibre_db.get_search_results(term)
|
||||
entries, __ = calibre_db.get_search_results(term)
|
||||
entriescount = len(entries) if len(entries) > 0 else 1
|
||||
pagination = Pagination(1, entriescount, entriescount)
|
||||
return render_xml_template('feed.xml', searchterm=term, entries=entries, pagination=pagination)
|
||||
|
|
|
@ -100,6 +100,33 @@ $(function() {
|
|||
$(e.currentTarget).find("#btndeletedomain").data("domainId", domainId);
|
||||
});
|
||||
|
||||
$("#delete_confirm").click(function() {
|
||||
//get data-id attribute of the clicked element
|
||||
var deleteId = $(this).data("deleteid");
|
||||
$.ajax({
|
||||
method:"get",
|
||||
url: window.location.pathname + "/../../delete"/+deleteId,
|
||||
});
|
||||
});
|
||||
|
||||
//triggered when modal is about to be shown
|
||||
$("#deleteModal").on("show.bs.modal", function(e) {
|
||||
//get data-id attribute of the clicked element and store in button
|
||||
var bookId = $(e.relatedTarget).data("delete-id");
|
||||
$(e.currentTarget).find("#delete_confirm").data("deleteid", bookId);
|
||||
});
|
||||
// receive result from request, dismiss modal dialog, show flash message
|
||||
// insert after navbar
|
||||
/*$("#deleteModal").on("hidden.bs.modal", function () {
|
||||
<div class="row-fluid text-center" style="margin-top: -20px;">
|
||||
<div id="flash_success" class="alert alert-success">{{ message[1] }}</div>
|
||||
</div>*/
|
||||
|
||||
// to save current setting
|
||||
// coresponding event: onColumnSwitch
|
||||
//$table.bootstrapTable('getVisibleColumns')
|
||||
//$table.bootstrapTable('getHiddenColumns').
|
||||
|
||||
$("#restrictModal").on("hidden.bs.modal", function () {
|
||||
// Destroy table and remove hooks for buttons
|
||||
$("#restrict-elements-table").unbind();
|
||||
|
@ -223,9 +250,8 @@ function RestrictionActions (value, row) {
|
|||
/* Function for deleting books */
|
||||
function EbookActions (value, row) {
|
||||
return [
|
||||
"<div class=\"danger remove\" listbook-id=\"" + row.id + "\" title=\"Remove\">",
|
||||
"<div class='danger remove' data-toggle='modal' data-target=\"#deleteModal\" data-delete-id=\"" + row.id + "\" title=\"Remove\">",
|
||||
"<i class=\"glyphicon glyphicon-trash\"></i>",
|
||||
"</div>"
|
||||
].join("");
|
||||
}
|
||||
|
||||
|
|
|
@ -192,34 +192,7 @@
|
|||
{% endblock %}
|
||||
|
||||
{% block modal %}
|
||||
{% if g.user.role_delete_books() %}
|
||||
<div class="modal fade" id="deleteModal" role="dialog" aria-labelledby="metaDeleteLabel">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-danger text-center">
|
||||
<span>{{_('Are you really sure?')}}</span>
|
||||
</div>
|
||||
<div class="modal-body text-center">
|
||||
<p>
|
||||
<span>{{_('This book will be permanently erased from database')}}</span>
|
||||
<span>{{_('and hard disk')}}</span>
|
||||
</p>
|
||||
{% if config.config_kobo_sync %}
|
||||
<p>
|
||||
<span>{{_('Important Kobo Note: deleted books will remain on any paired Kobo device.')}}</span>
|
||||
<span>{{_('Books must first be archived and the device synced before a book can safely be deleted.')}}</span>
|
||||
</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<a href="{{ url_for('editbook.delete_book', book_id=book.id) }}" id="delete_confirm" class="btn btn-danger">{{_('Delete')}}</a>
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">{{_('Cancel')}}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{{ delete_book(book.id) }}
|
||||
|
||||
<div class="modal fade" id="metaModal" tabindex="-1" role="dialog" aria-labelledby="metaModalLabel">
|
||||
<div class="modal-dialog modal-lg" role="document">
|
||||
|
|
|
@ -5,12 +5,7 @@
|
|||
{% endblock %}
|
||||
{% block body %}
|
||||
<h2 class="{{page}}">{{_(title)}}</h2>
|
||||
<!--
|
||||
|
||||
|
||||
-->
|
||||
<table class="table table-no-bordered table-striped"
|
||||
data-toggle="table"
|
||||
data-side-pagination="server"
|
||||
data-pagination="true"
|
||||
data-pagination-detail-h-align=" hidden"
|
||||
|
@ -23,6 +18,7 @@
|
|||
data-search="true"
|
||||
data-search-align="left"
|
||||
data-show-search-button="false"
|
||||
data-search-on-enter-key="true"
|
||||
data-checkbox-header="false"
|
||||
data-maintain-meta-data="true">
|
||||
<thead>
|
||||
|
@ -47,6 +43,9 @@
|
|||
</thead>
|
||||
</table>
|
||||
{% endblock %}
|
||||
{% block modal %}
|
||||
{{ delete_book(0) }}
|
||||
{% endblock %}
|
||||
{% block js %}
|
||||
<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>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{% from 'modal_restriction.html' import restrict_modal %}
|
||||
{% from 'modal_dialogs.html' import restrict_modal, delete_book %}
|
||||
<!DOCTYPE html>
|
||||
<html lang="{{ g.user.locale }}">
|
||||
<head>
|
||||
|
|
|
@ -37,3 +37,34 @@
|
|||
</div>
|
||||
</div>
|
||||
{% endmacro %}
|
||||
{% macro delete_book(bookid) %}
|
||||
{% if g.user.role_delete_books() %}
|
||||
<div class="modal fade" id="deleteModal" role="dialog" aria-labelledby="metaDeleteLabel">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-danger text-center">
|
||||
<span>{{_('Are you really sure?')}}</span>
|
||||
</div>
|
||||
<div class="modal-body text-center">
|
||||
<p>
|
||||
<span>{{_('This book will be permanently erased from database')}}</span>
|
||||
<span>{{_('and hard disk')}}</span>
|
||||
</p>
|
||||
{% if config.config_kobo_sync %}
|
||||
<p>
|
||||
<span>{{_('Important Kobo Note: deleted books will remain on any paired Kobo device.')}}</span>
|
||||
<span>{{_('Books must first be archived and the device synced before a book can safely be deleted.')}}</span>
|
||||
</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<input type="button" class="btn btn-danger" value="{{_('Delete')}}" name="delete_confirm" id="delete_confirm" data-dismiss="modal">
|
||||
<!--a href="{{ url_for('editbook.delete_book', book_id=bookid) }}" id="delete_confirm" class="btn btn-danger">{{_('Delete')}}</a-->
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">{{_('Cancel')}}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endmacro %}
|
|
@ -5,7 +5,7 @@
|
|||
<h2>{{_('No Results Found')}} {{adv_searchterm}}</h2>
|
||||
<p>{{_('Search Term:')}} {{adv_searchterm}}</p>
|
||||
{% else %}
|
||||
<h2>{{entries|length}} {{_('Results for:')}} {{adv_searchterm}}</h2>
|
||||
<h2>{{result_count}} {{_('Results for:')}} {{adv_searchterm}}</h2>
|
||||
{% if g.user.is_authenticated %}
|
||||
{% if g.user.shelf.all() or g.shelves_access %}
|
||||
<div id="shelf-actions" class="btn-toolbar" role="toolbar">
|
||||
|
|
14
cps/web.py
14
cps/web.py
|
@ -832,13 +832,13 @@ def render_language_books(page, name, order):
|
|||
|
||||
|
||||
@web.route("/table")
|
||||
@login_required_if_no_ano
|
||||
@login_required
|
||||
def books_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")
|
||||
@login_required_if_no_ano
|
||||
@login_required
|
||||
def list_books():
|
||||
off = request.args.get("offset") or 0
|
||||
limit = request.args.get("limit") or config.config_books_per_page
|
||||
|
@ -850,9 +850,7 @@ def list_books():
|
|||
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)
|
||||
entries, filtered_count = calibre_db.get_search_results(search, off, order, limit)
|
||||
else:
|
||||
entries, __, __ = calibre_db.fill_indexpage((int(off) / (int(limit)) + 1), limit, db.Books, True, order)
|
||||
filtered_count = total_count
|
||||
|
@ -1035,7 +1033,7 @@ def reconnect():
|
|||
def search():
|
||||
term = request.args.get("query")
|
||||
if term:
|
||||
entries = calibre_db.get_search_results(term)
|
||||
entries, result_count = calibre_db.get_search_results(term)
|
||||
ids = list()
|
||||
for element in entries:
|
||||
ids.append(element.id)
|
||||
|
@ -1044,11 +1042,13 @@ def search():
|
|||
searchterm=term,
|
||||
adv_searchterm=term,
|
||||
entries=entries,
|
||||
result_count=result_count,
|
||||
title=_(u"Search"),
|
||||
page="search")
|
||||
else:
|
||||
return render_title_template('search.html',
|
||||
searchterm="",
|
||||
result_count=0,
|
||||
title=_(u"Search"),
|
||||
page="search")
|
||||
|
||||
|
@ -1192,7 +1192,7 @@ def advanced_search():
|
|||
ids.append(element.id)
|
||||
searched_ids[current_user.id] = ids
|
||||
return render_title_template('search.html', adv_searchterm=searchterm,
|
||||
entries=q, title=_(u"search"), page="search")
|
||||
entries=q, result_count=len(q), title=_(u"search"), page="search")
|
||||
# prepare data for search-form
|
||||
tags = calibre_db.session.query(db.Tags)\
|
||||
.join(db.books_tags_link)\
|
||||
|
|
Loading…
Reference in a new issue