Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
D
douban-api-proxy
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
captainwong
douban-api-proxy
Commits
4038cb5b
Commit
4038cb5b
authored
Jun 08, 2020
by
Ozzieisaacs
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Internal paged Search prepared
Search for table list is working
parent
62865897
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
82 additions
and
48 deletions
+82
-48
db.py
cps/db.py
+8
-3
opds.py
cps/opds.py
+1
-1
table.js
cps/static/js/table.js
+28
-2
book_edit.html
cps/templates/book_edit.html
+1
-28
book_table.html
cps/templates/book_table.html
+4
-5
layout.html
cps/templates/layout.html
+1
-1
modal_dialogs.html
cps/templates/modal_dialogs.html
+31
-0
search.html
cps/templates/search.html
+1
-1
web.py
cps/web.py
+7
-7
No files found.
cps/db.py
View file @
4038cb5b
...
...
@@ -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
,
o
rder
=
None
,
limit
=-
1
):
def
get_search_results
(
self
,
term
,
o
ffset
=
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
+
"
%
"
)))
re
turn
self
.
session
.
query
(
Books
)
.
filter
(
self
.
common_filters
(
True
))
.
filter
(
re
sult
=
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
):
...
...
cps/opds.py
View file @
4038cb5b
...
...
@@ -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
)
...
...
cps/static/js/table.js
View file @
4038cb5b
...
...
@@ -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
(
""
);
}
cps/templates/book_edit.html
View file @
4038cb5b
...
...
@@ -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"
>
...
...
cps/templates/book_table.html
View file @
4038cb5b
...
...
@@ -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>
...
...
cps/templates/layout.html
View file @
4038cb5b
{% from 'modal_
restriction.html' import restrict_modal
%}
{% from 'modal_
dialogs.html' import restrict_modal, delete_book
%}
<!DOCTYPE html>
<html
lang=
"{{ g.user.locale }}"
>
<head>
...
...
cps/templates/modal_
restriction
.html
→
cps/templates/modal_
dialogs
.html
View file @
4038cb5b
...
...
@@ -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 %}
cps/templates/search.html
View file @
4038cb5b
...
...
@@ -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"
>
...
...
cps/web.py
View file @
4038cb5b
...
...
@@ -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
)
\
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment