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
0db837c0
Commit
0db837c0
authored
Jul 26, 2021
by
cbartondock
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' of
https://github.com/janeczku/calibre-web
parents
6ef792d6
53dae328
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
175 additions
and
141 deletions
+175
-141
admin.py
cps/admin.py
+4
-4
constants.py
cps/constants.py
+3
-0
db.py
cps/db.py
+4
-0
kobo.py
cps/kobo.py
+7
-8
shelf.py
cps/shelf.py
+29
-23
main.js
cps/static/js/main.js
+4
-1
table.js
cps/static/js/table.js
+62
-58
user_edit.html
cps/templates/user_edit.html
+29
-29
web.py
cps/web.py
+33
-18
No files found.
cps/admin.py
View file @
0db837c0
...
...
@@ -1370,11 +1370,11 @@ def _delete_user(content):
if
content
.
name
!=
"Guest"
:
# Delete all books in shelfs belonging to user, all shelfs of user, downloadstat of user, read status
# and user itself
ub
.
session
.
query
(
ub
.
ReadBook
)
.
filter
(
ub
.
User
.
id
==
ub
.
ReadBook
.
user_id
)
.
delete
()
ub
.
session
.
query
(
ub
.
Downloads
)
.
filter
(
ub
.
User
.
id
==
ub
.
Downloads
.
user_id
)
.
delete
()
for
us
in
ub
.
session
.
query
(
ub
.
Shelf
)
.
filter
(
ub
.
User
.
id
==
ub
.
Shelf
.
user_id
):
ub
.
session
.
query
(
ub
.
ReadBook
)
.
filter
(
content
.
id
==
ub
.
ReadBook
.
user_id
)
.
delete
()
ub
.
session
.
query
(
ub
.
Downloads
)
.
filter
(
content
.
id
==
ub
.
Downloads
.
user_id
)
.
delete
()
for
us
in
ub
.
session
.
query
(
ub
.
Shelf
)
.
filter
(
content
.
id
==
ub
.
Shelf
.
user_id
):
ub
.
session
.
query
(
ub
.
BookShelf
)
.
filter
(
us
.
id
==
ub
.
BookShelf
.
shelf
)
.
delete
()
ub
.
session
.
query
(
ub
.
Shelf
)
.
filter
(
ub
.
User
.
id
==
ub
.
Shelf
.
user_id
)
.
delete
()
ub
.
session
.
query
(
ub
.
Shelf
)
.
filter
(
content
.
id
==
ub
.
Shelf
.
user_id
)
.
delete
()
ub
.
session
.
query
(
ub
.
User
)
.
filter
(
ub
.
User
.
id
==
content
.
id
)
.
delete
()
ub
.
session_commit
()
log
.
info
(
u"User {} deleted"
.
format
(
content
.
name
))
...
...
cps/constants.py
View file @
0db837c0
...
...
@@ -20,6 +20,9 @@ from __future__ import division, print_function, unicode_literals
import
sys
import
os
from
collections
import
namedtuple
from
sqlalchemy
import
__version__
as
sql_version
sqlalchemy_version2
=
([
int
(
x
)
for
x
in
sql_version
.
split
(
'.'
)]
>=
[
2
,
0
,
0
])
# if installed via pip this variable is set to true (empty file with name .HOMEDIR present)
HOME_CONFIG
=
os
.
path
.
isfile
(
os
.
path
.
join
(
os
.
path
.
dirname
(
os
.
path
.
abspath
(
__file__
)),
'.HOMEDIR'
))
...
...
cps/db.py
View file @
0db837c0
...
...
@@ -690,6 +690,8 @@ class CalibreDB():
randm
=
false
()
off
=
int
(
int
(
pagesize
)
*
(
page
-
1
))
query
=
self
.
session
.
query
(
database
)
if
len
(
join
)
==
6
:
query
=
query
.
outerjoin
(
join
[
0
],
join
[
1
])
.
outerjoin
(
join
[
2
])
.
outerjoin
(
join
[
3
],
join
[
4
])
.
outerjoin
(
join
[
5
])
if
len
(
join
)
==
3
:
query
=
query
.
outerjoin
(
join
[
0
],
join
[
1
])
.
outerjoin
(
join
[
2
])
elif
len
(
join
)
==
2
:
...
...
@@ -755,6 +757,8 @@ class CalibreDB():
for
authorterm
in
authorterms
:
q
.
append
(
Books
.
authors
.
any
(
func
.
lower
(
Authors
.
name
)
.
ilike
(
"
%
"
+
authorterm
+
"
%
"
)))
query
=
self
.
session
.
query
(
Books
)
if
len
(
join
)
==
6
:
query
=
query
.
outerjoin
(
join
[
0
],
join
[
1
])
.
outerjoin
(
join
[
2
])
.
outerjoin
(
join
[
3
],
join
[
4
])
.
outerjoin
(
join
[
5
])
if
len
(
join
)
==
3
:
query
=
query
.
outerjoin
(
join
[
0
],
join
[
1
])
.
outerjoin
(
join
[
2
])
elif
len
(
join
)
==
2
:
...
...
cps/kobo.py
View file @
0db837c0
...
...
@@ -44,11 +44,11 @@ from werkzeug.datastructures import Headers
from
sqlalchemy
import
func
from
sqlalchemy.sql.expression
import
and_
,
or_
from
sqlalchemy.exc
import
StatementError
from
sqlalchemy
import
__version__
as
sql_version
from
sqlalchemy.sql
import
select
import
requests
from
.
import
config
,
logger
,
kobo_auth
,
db
,
calibre_db
,
helper
,
shelf
as
shelf_lib
,
ub
from
.constants
import
sqlalchemy_version2
from
.helper
import
get_download_link
from
.services
import
SyncToken
as
SyncToken
from
.web
import
download_required
...
...
@@ -66,7 +66,6 @@ kobo_auth.register_url_value_preprocessor(kobo)
log
=
logger
.
create
()
sql2
=
([
int
(
x
)
for
x
in
sql_version
.
split
(
'.'
)]
>=
[
2
,
0
,
0
])
def
get_store_url_for_current_request
():
# Programmatically modify the current url to point to the official Kobo store
...
...
@@ -159,7 +158,7 @@ def HandleSyncRequest():
only_kobo_shelves
=
current_user
.
kobo_only_shelves_sync
if
only_kobo_shelves
:
if
sql2
:
if
sql
alchemy_version
2
:
changed_entries
=
select
(
db
.
Books
,
ub
.
ArchivedBook
.
last_modified
,
ub
.
BookShelf
.
date_added
,
...
...
@@ -183,7 +182,7 @@ def HandleSyncRequest():
.
distinct
()
)
else
:
if
sql2
:
if
sql
alchemy_version
2
:
changed_entries
=
select
(
db
.
Books
,
ub
.
ArchivedBook
.
last_modified
,
ub
.
ArchivedBook
.
is_archived
)
else
:
changed_entries
=
calibre_db
.
session
.
query
(
db
.
Books
,
...
...
@@ -202,7 +201,7 @@ def HandleSyncRequest():
changed_entries
=
changed_entries
.
filter
(
db
.
Books
.
id
>
sync_token
.
books_last_id
)
reading_states_in_new_entitlements
=
[]
if
sql2
:
if
sql
alchemy_version
2
:
books
=
calibre_db
.
session
.
execute
(
changed_entries
.
limit
(
SYNC_ITEM_LIMIT
))
else
:
books
=
changed_entries
.
limit
(
SYNC_ITEM_LIMIT
)
...
...
@@ -246,7 +245,7 @@ def HandleSyncRequest():
new_books_last_created
=
max
(
ts_created
,
new_books_last_created
)
if
sql2
:
if
sql
alchemy_version
2
:
max_change
=
calibre_db
.
session
.
execute
(
changed_entries
.
filter
(
ub
.
ArchivedBook
.
is_archived
)
.
order_by
(
func
.
datetime
(
ub
.
ArchivedBook
.
last_modified
)
.
desc
()))
\
...
...
@@ -260,7 +259,7 @@ def HandleSyncRequest():
new_archived_last_modified
=
max
(
new_archived_last_modified
,
max_change
)
# no. of books returned
if
sql2
:
if
sql
alchemy_version
2
:
entries
=
calibre_db
.
session
.
execute
(
changed_entries
)
.
all
()
book_count
=
len
(
entries
)
else
:
...
...
@@ -697,7 +696,7 @@ def sync_shelves(sync_token, sync_results, only_kobo_shelves=False):
})
extra_filters
.
append
(
ub
.
Shelf
.
kobo_sync
)
if
sql2
:
if
sql
alchemy_version
2
:
shelflist
=
ub
.
session
.
execute
(
select
(
ub
.
Shelf
)
.
outerjoin
(
ub
.
BookShelf
)
.
filter
(
or_
(
func
.
datetime
(
ub
.
Shelf
.
last_modified
)
>
sync_token
.
tags_last_modified
,
func
.
datetime
(
ub
.
BookShelf
.
date_added
)
>
sync_token
.
tags_last_modified
),
...
...
cps/shelf.py
View file @
0db837c0
...
...
@@ -72,10 +72,9 @@ def add_to_shelf(shelf_id, book_id):
if
not
check_shelf_edit_permissions
(
shelf
):
if
not
xhr
:
flash
(
_
(
u"Sorry you are not allowed to add a book to the the shelf:
%(shelfname)
s"
,
shelfname
=
shelf
.
name
),
category
=
"error"
)
flash
(
_
(
u"Sorry you are not allowed to add a book to that shelf"
),
category
=
"error"
)
return
redirect
(
url_for
(
'web.index'
))
return
"Sorry you are not allowed to add a book to the th
e shelf:
%
s"
%
shelf
.
name
,
403
return
"Sorry you are not allowed to add a book to the th
at shelf"
,
403
book_in_shelf
=
ub
.
session
.
query
(
ub
.
BookShelf
)
.
filter
(
ub
.
BookShelf
.
shelf
==
shelf_id
,
ub
.
BookShelf
.
book_id
==
book_id
)
.
first
()
...
...
@@ -228,18 +227,21 @@ def remove_from_shelf(shelf_id, book_id):
@
login_required
def
create_shelf
():
shelf
=
ub
.
Shelf
()
return
create_edit_shelf
(
shelf
,
title
=
_
(
u"Create a Shelf"
),
page
=
"shelfcreate"
)
return
create_edit_shelf
(
shelf
,
page_
title
=
_
(
u"Create a Shelf"
),
page
=
"shelfcreate"
)
@
shelf
.
route
(
"/shelf/edit/<int:shelf_id>"
,
methods
=
[
"GET"
,
"POST"
])
@
login_required
def
edit_shelf
(
shelf_id
):
shelf
=
ub
.
session
.
query
(
ub
.
Shelf
)
.
filter
(
ub
.
Shelf
.
id
==
shelf_id
)
.
first
()
return
create_edit_shelf
(
shelf
,
title
=
_
(
u"Edit a shelf"
),
page
=
"shelfedit"
,
shelf_id
=
shelf_id
)
if
not
check_shelf_edit_permissions
(
shelf
):
flash
(
_
(
u"Sorry you are not allowed to edit this shelf"
),
category
=
"error"
)
return
redirect
(
url_for
(
'web.index'
))
return
create_edit_shelf
(
shelf
,
page_title
=
_
(
u"Edit a shelf"
),
page
=
"shelfedit"
,
shelf_id
=
shelf_id
)
# if shelf ID is set, we are editing a shelf
def
create_edit_shelf
(
shelf
,
title
,
page
,
shelf_id
=
False
):
def
create_edit_shelf
(
shelf
,
page_
title
,
page
,
shelf_id
=
False
):
sync_only_selected_shelves
=
current_user
.
kobo_only_shelves_sync
# calibre_db.session.query(ub.Shelf).filter(ub.Shelf.user_id == current_user.id).filter(ub.Shelf.kobo_sync).count()
if
request
.
method
==
"POST"
:
...
...
@@ -247,20 +249,20 @@ def create_edit_shelf(shelf, title, page, shelf_id=False):
shelf
.
is_public
=
1
if
to_save
.
get
(
"is_public"
)
else
0
if
config
.
config_kobo_sync
:
shelf
.
kobo_sync
=
True
if
to_save
.
get
(
"kobo_sync"
)
else
False
if
check_shelf_is_unique
(
shelf
,
to_sav
e
,
shelf_id
):
shelf
.
name
=
to_save
[
"title"
]
shelf_title
=
to_save
.
get
(
"title"
,
""
)
if
check_shelf_is_unique
(
shelf
,
shelf_titl
e
,
shelf_id
):
shelf
.
name
=
shelf_title
if
not
shelf_id
:
shelf
.
user_id
=
int
(
current_user
.
id
)
ub
.
session
.
add
(
shelf
)
shelf_action
=
"created"
flash_text
=
_
(
u"Shelf
%(title)
s created"
,
title
=
to_save
[
"title"
]
)
flash_text
=
_
(
u"Shelf
%(title)
s created"
,
title
=
shelf_title
)
else
:
shelf_action
=
"changed"
flash_text
=
_
(
u"Shelf
%(title)
s changed"
,
title
=
to_save
[
"title"
]
)
flash_text
=
_
(
u"Shelf
%(title)
s changed"
,
title
=
shelf_title
)
try
:
ub
.
session
.
commit
()
log
.
info
(
u"Shelf {} {}"
.
format
(
to_save
[
"title"
]
,
shelf_action
))
log
.
info
(
u"Shelf {} {}"
.
format
(
shelf_title
,
shelf_action
))
flash
(
flash_text
,
category
=
"success"
)
return
redirect
(
url_for
(
'shelf.show_shelf'
,
shelf_id
=
shelf
.
id
))
except
(
OperationalError
,
InvalidRequestError
)
as
ex
:
...
...
@@ -274,37 +276,37 @@ def create_edit_shelf(shelf, title, page, shelf_id=False):
flash
(
_
(
u"There was an error"
),
category
=
"error"
)
return
render_title_template
(
'shelf_edit.html'
,
shelf
=
shelf
,
title
=
title
,
title
=
page_
title
,
page
=
page
,
kobo_sync_enabled
=
config
.
config_kobo_sync
,
sync_only_selected_shelves
=
sync_only_selected_shelves
)
def
check_shelf_is_unique
(
shelf
,
t
o_sav
e
,
shelf_id
=
False
):
def
check_shelf_is_unique
(
shelf
,
t
itl
e
,
shelf_id
=
False
):
if
shelf_id
:
ident
=
ub
.
Shelf
.
id
!=
shelf_id
else
:
ident
=
true
()
if
shelf
.
is_public
==
1
:
is_shelf_name_unique
=
ub
.
session
.
query
(
ub
.
Shelf
)
\
.
filter
((
ub
.
Shelf
.
name
==
t
o_save
[
"title"
]
)
&
(
ub
.
Shelf
.
is_public
==
1
))
\
.
filter
((
ub
.
Shelf
.
name
==
t
itle
)
&
(
ub
.
Shelf
.
is_public
==
1
))
\
.
filter
(
ident
)
\
.
first
()
is
None
if
not
is_shelf_name_unique
:
log
.
error
(
"A public shelf with the name '{}' already exists."
.
format
(
t
o_save
[
"title"
]
))
flash
(
_
(
u"A public shelf with the name '
%(title)
s' already exists."
,
title
=
t
o_save
[
"title"
]
),
log
.
error
(
"A public shelf with the name '{}' already exists."
.
format
(
t
itle
))
flash
(
_
(
u"A public shelf with the name '
%(title)
s' already exists."
,
title
=
t
itle
),
category
=
"error"
)
else
:
is_shelf_name_unique
=
ub
.
session
.
query
(
ub
.
Shelf
)
\
.
filter
((
ub
.
Shelf
.
name
==
t
o_save
[
"title"
]
)
&
(
ub
.
Shelf
.
is_public
==
0
)
&
.
filter
((
ub
.
Shelf
.
name
==
t
itle
)
&
(
ub
.
Shelf
.
is_public
==
0
)
&
(
ub
.
Shelf
.
user_id
==
int
(
current_user
.
id
)))
\
.
filter
(
ident
)
\
.
first
()
is
None
if
not
is_shelf_name_unique
:
log
.
error
(
"A private shelf with the name '{}' already exists."
.
format
(
t
o_save
[
"title"
]
))
flash
(
_
(
u"A private shelf with the name '
%(title)
s' already exists."
,
title
=
t
o_save
[
"title"
]
),
log
.
error
(
"A private shelf with the name '{}' already exists."
.
format
(
t
itle
))
flash
(
_
(
u"A private shelf with the name '
%(title)
s' already exists."
,
title
=
t
itle
),
category
=
"error"
)
return
is_shelf_name_unique
...
...
@@ -378,7 +380,9 @@ def order_shelf(shelf_id):
def
change_shelf_order
(
shelf_id
,
order
):
result
=
calibre_db
.
session
.
query
(
db
.
Books
)
.
join
(
ub
.
BookShelf
,
ub
.
BookShelf
.
book_id
==
db
.
Books
.
id
)
\
result
=
calibre_db
.
session
.
query
(
db
.
Books
)
.
outerjoin
(
db
.
books_series_link
,
db
.
Books
.
id
==
db
.
books_series_link
.
c
.
book
)
\
.
outerjoin
(
db
.
Series
)
.
join
(
ub
.
BookShelf
,
ub
.
BookShelf
.
book_id
==
db
.
Books
.
id
)
\
.
filter
(
ub
.
BookShelf
.
shelf
==
shelf_id
)
.
order_by
(
*
order
)
.
all
()
for
index
,
entry
in
enumerate
(
result
):
book
=
ub
.
session
.
query
(
ub
.
BookShelf
)
.
filter
(
ub
.
BookShelf
.
shelf
==
shelf_id
)
\
...
...
@@ -408,9 +412,11 @@ def render_show_shelf(shelf_type, shelf_id, page_no, sort_param):
if
sort_param
==
'old'
:
change_shelf_order
(
shelf_id
,
[
db
.
Books
.
timestamp
])
if
sort_param
==
'authaz'
:
change_shelf_order
(
shelf_id
,
[
db
.
Books
.
author_sort
.
asc
()])
change_shelf_order
(
shelf_id
,
[
db
.
Books
.
author_sort
.
asc
()
,
db
.
Series
.
name
,
db
.
Books
.
series_index
])
if
sort_param
==
'authza'
:
change_shelf_order
(
shelf_id
,
[
db
.
Books
.
author_sort
.
desc
()])
change_shelf_order
(
shelf_id
,
[
db
.
Books
.
author_sort
.
desc
(),
db
.
Series
.
name
.
desc
(),
db
.
Books
.
series_index
.
desc
()])
page
=
"shelf.html"
pagesize
=
0
else
:
...
...
cps/static/js/main.js
View file @
0db837c0
...
...
@@ -611,7 +611,10 @@ $(function() {
if
(
xhr
.
status
<
400
)
{
$
(
"#spinning_success"
).
hide
();
clearInterval
(
rebootInterval
);
handle_response
(
data
.
result
);
if
(
data
.
result
)
{
handle_response
(
data
.
result
);
data
.
result
=
""
;
}
}
},
});
...
...
cps/static/js/table.js
View file @
0db837c0
...
...
@@ -661,33 +661,34 @@ function move_header_elements() {
}
});
$
(
".multi_selector"
).
selectpicker
();
if
(
!
$
.
_data
(
$
(
".multi_head"
).
get
(
0
),
"events"
)
)
{
// Functions have to be here, otherwise the callbacks are not fired if visible columns are changed
$
(
".multi_head"
).
on
(
"click"
,
function
()
{
var
val
=
$
(
this
).
data
(
"set"
);
var
field
=
$
(
this
).
data
(
"name"
);
var
result
=
$
(
'#user-table'
).
bootstrapTable
(
'getSelections'
).
map
(
a
=>
a
.
id
);
var
values
=
$
(
"#"
+
field
).
val
();
confirmDialog
(
"restrictions"
,
"GeneralChangeModal"
,
0
,
function
()
{
$
.
ajax
({
method
:
"post"
,
url
:
window
.
location
.
pathname
+
"/../../ajax/editlistusers/"
+
field
,
data
:
{
"pk"
:
result
,
"value"
:
values
,
"action"
:
val
},
success
:
function
(
data
)
{
handleListServerResponse
(
data
);
},
error
:
function
(
data
)
{
handleListServerResponse
([{
type
:
"danger"
,
message
:
data
.
responseText
}])
},
});
}
);
});
if
(
$
(
".multi_head"
).
length
)
{
if
(
!
$
.
_data
(
$
(
".multi_head"
).
get
(
0
),
"events"
))
{
// Functions have to be here, otherwise the callbacks are not fired if visible columns are changed
$
(
".multi_head"
).
on
(
"click"
,
function
()
{
var
val
=
$
(
this
).
data
(
"set"
);
var
field
=
$
(
this
).
data
(
"name"
);
var
result
=
$
(
'#user-table'
).
bootstrapTable
(
'getSelections'
).
map
(
a
=>
a
.
id
);
var
values
=
$
(
"#"
+
field
).
val
();
confirmDialog
(
"restrictions"
,
"GeneralChangeModal"
,
0
,
function
()
{
$
.
ajax
({
method
:
"post"
,
url
:
window
.
location
.
pathname
+
"/../../ajax/editlistusers/"
+
field
,
data
:
{
"pk"
:
result
,
"value"
:
values
,
"action"
:
val
},
success
:
function
(
data
)
{
handleListServerResponse
(
data
);
},
error
:
function
(
data
)
{
handleListServerResponse
([{
type
:
"danger"
,
message
:
data
.
responseText
}])
},
});
}
);
});
}
}
$
(
"#user_delete_selection"
).
click
(
function
()
{
...
...
@@ -699,38 +700,41 @@ function move_header_elements() {
$
(
"#select_default_language"
).
on
(
"change"
,
function
()
{
selectHeader
(
this
,
"default_language"
);
});
if
(
!
$
.
_data
(
$
(
".check_head"
).
get
(
0
),
"events"
)
)
{
$
(
".check_head"
).
on
(
"change"
,
function
()
{
var
val
=
$
(
this
).
data
(
"set"
);
var
name
=
$
(
this
).
data
(
"name"
);
var
data
=
$
(
this
).
data
(
"val"
);
checkboxHeader
(
val
,
name
,
data
);
});
if
(
$
(
".check_head"
).
length
)
{
if
(
!
$
.
_data
(
$
(
".check_head"
).
get
(
0
),
"events"
))
{
$
(
".check_head"
).
on
(
"change"
,
function
()
{
var
val
=
$
(
this
).
data
(
"set"
);
var
name
=
$
(
this
).
data
(
"name"
);
var
data
=
$
(
this
).
data
(
"val"
);
checkboxHeader
(
val
,
name
,
data
);
});
}
}
if
(
!
$
.
_data
(
$
(
".button_head"
).
get
(
0
),
"events"
)
)
{
$
(
".button_head"
).
on
(
"click"
,
function
()
{
var
result
=
$
(
'#user-table'
).
bootstrapTable
(
'getSelections'
).
map
(
a
=>
a
.
id
);
confirmDialog
(
"btndeluser"
,
"GeneralDeleteModal"
,
0
,
function
()
{
$
.
ajax
({
method
:
"post"
,
url
:
window
.
location
.
pathname
+
"/../../ajax/deleteuser"
,
data
:
{
"userid"
:
result
},
success
:
function
(
data
)
{
selections
=
selections
.
filter
((
el
)
=>
!
result
.
includes
(
el
));
handleListServerResponse
(
data
);
},
error
:
function
(
data
)
{
handleListServerResponse
([{
type
:
"danger"
,
message
:
data
.
responseText
}])
},
});
}
);
});
if
(
$
(
".button_head"
).
length
)
{
if
(
!
$
.
_data
(
$
(
".button_head"
).
get
(
0
),
"events"
))
{
$
(
".button_head"
).
on
(
"click"
,
function
()
{
var
result
=
$
(
'#user-table'
).
bootstrapTable
(
'getSelections'
).
map
(
a
=>
a
.
id
);
confirmDialog
(
"btndeluser"
,
"GeneralDeleteModal"
,
0
,
function
()
{
$
.
ajax
({
method
:
"post"
,
url
:
window
.
location
.
pathname
+
"/../../ajax/deleteuser"
,
data
:
{
"userid"
:
result
},
success
:
function
(
data
)
{
selections
=
selections
.
filter
((
el
)
=>
!
result
.
includes
(
el
));
handleListServerResponse
(
data
);
},
error
:
function
(
data
)
{
handleListServerResponse
([{
type
:
"danger"
,
message
:
data
.
responseText
}])
},
});
}
);
});
}
}
}
...
...
cps/templates/user_edit.html
View file @
0db837c0
...
...
@@ -67,15 +67,14 @@
</div>
{% endif %}
<div
class=
"col-sm-6"
>
{% for element in sidebar %}
{% if element['config_show'] %}
<div
class=
"form-group"
>
<input
type=
"checkbox"
name=
"show_{{element['visibility']}}"
id=
"show_{{element['visibility']}}"
{%
if
content
.
check_visibility
(
element
['
visibility
'])
%}
checked
{%
endif
%}
>
<label
for=
"show_{{element['visibility']}}"
>
{{element['show_text']}}
</label>
</div>
{% endif %}
{% endfor %}
{% for element in sidebar %}
{% if element['config_show'] %}
<div
class=
"form-group"
>
<input
type=
"checkbox"
name=
"show_{{element['visibility']}}"
id=
"show_{{element['visibility']}}"
{%
if
content
.
check_visibility
(
element
['
visibility
'])
%}
checked
{%
endif
%}
>
<label
for=
"show_{{element['visibility']}}"
>
{{element['show_text']}}
</label>
</div>
{% endif %}
{% endfor %}
<div
class=
"form-group"
>
<input
type=
"checkbox"
name=
"Show_detail_random"
id=
"Show_detail_random"
{%
if
content
.
show_detail_random
()
%}
checked
{%
endif
%}
>
<label
for=
"Show_detail_random"
>
{{_('Show Random Books in Detail View')}}
</label>
...
...
@@ -84,6 +83,7 @@
<a
href=
"#"
id=
"get_user_tags"
class=
"btn btn-default"
data-id=
"{{content.id}}"
data-toggle=
"modal"
data-target=
"#restrictModal"
>
{{_('Add Allowed/Denied Tags')}}
</a>
<a
href=
"#"
id=
"get_user_column_values"
data-id=
"{{content.id}}"
class=
"btn btn-default"
data-toggle=
"modal"
data-target=
"#restrictModal"
>
{{_('Add allowed/Denied Custom Column Values')}}
</a>
{% endif %}
</div>
</div>
<div
class=
"col-sm-6"
>
{% if g.user and g.user.role_admin() and not profile %}
...
...
@@ -131,32 +131,32 @@
</div>
{% endif %}
</div>
<div
class=
"col-sm-12"
>
<div
id=
"user_submit"
class=
"btn btn-default"
>
{{_('Save')}}
</div>
{% if not profile %}
<div
class=
"btn btn-default"
data-back=
"{{ url_for('admin.admin') }}"
id=
"back"
>
{{_('Cancel')}}
</div>
{% endif %}
{% if g.user and g.user.role_admin() and not profile and not new_user and not content.role_anonymous() %}
<div
class=
"btn btn-danger"
id=
"btndeluser"
data-value=
"{{ content.id }}"
data-remote=
"false"
>
{{_('Delete User')}}
</div>
{% endif %}
<div
class=
"col-sm-12"
>
<div
id=
"user_submit"
class=
"btn btn-default"
>
{{_('Save')}}
</div>
{% if not profile %}
<div
class=
"btn btn-default"
data-back=
"{{ url_for('admin.admin') }}"
id=
"back"
>
{{_('Cancel')}}
</div>
{% endif %}
{% if g.user and g.user.role_admin() and not profile and not new_user and not content.role_anonymous() %}
<div
class=
"btn btn-danger"
id=
"btndeluser"
data-value=
"{{ content.id }}"
data-remote=
"false"
>
{{_('Delete User')}}
</div>
{% endif %}
</div>
</form>
</div>
<div
class=
"modal fade"
id=
"modal_kobo_token"
tabindex=
"-1"
role=
"dialog"
aria-labelledby=
"kobo_tokenModalLabel"
>
<div
class=
"modal-dialog modal-lg"
role=
"document"
>
<div
class=
"modal-content"
>
<div
class=
"modal-header"
>
<button
type=
"button"
class=
"close"
data-dismiss=
"modal"
aria-label=
"Close"
><span
aria-hidden=
"true"
>
×
</span></button>
<h4
class=
"modal-title"
id=
"kobo_tokenModalLabel"
>
{{_('Generate Kobo Auth URL')}}
</h4>
</div>
<div
class=
"modal-body"
>
...
</div>
<div
class=
"modal-footer"
>
<button
type=
"button"
id=
"kobo_close"
class=
"btn btn-default"
data-dismiss=
"modal"
>
{{_('Close')}}
</button>
</div>
</div>
<div
class=
"modal fade"
id=
"modal_kobo_token"
tabindex=
"-1"
role=
"dialog"
aria-labelledby=
"kobo_tokenModalLabel"
>
<div
class=
"modal-dialog modal-lg"
role=
"document"
>
<div
class=
"modal-content"
>
<div
class=
"modal-header"
>
<button
type=
"button"
class=
"close"
data-dismiss=
"modal"
aria-label=
"Close"
><span
aria-hidden=
"true"
>
×
</span></button>
<h4
class=
"modal-title"
id=
"kobo_tokenModalLabel"
>
{{_('Generate Kobo Auth URL')}}
</h4>
</div>
<div
class=
"modal-body"
>
...
</div>
<div
class=
"modal-footer"
>
<button
type=
"button"
id=
"kobo_close"
class=
"btn btn-default"
data-dismiss=
"modal"
>
{{_('Close')}}
</button>
</div>
</div>
</div>
</div>
{% endblock %}
{% block modal %}
...
...
cps/web.py
View file @
0db837c0
...
...
@@ -360,9 +360,9 @@ def get_sort_function(sort, data):
if
sort
==
'old'
:
order
=
[
db
.
Books
.
timestamp
]
if
sort
==
'authaz'
:
order
=
[
db
.
Books
.
author_sort
.
asc
()]
order
=
[
db
.
Books
.
author_sort
.
asc
()
,
db
.
Series
.
name
,
db
.
Books
.
series_index
]
if
sort
==
'authza'
:
order
=
[
db
.
Books
.
author_sort
.
desc
()]
order
=
[
db
.
Books
.
author_sort
.
desc
()
,
db
.
Series
.
name
.
desc
(),
db
.
Books
.
series_index
.
desc
()
]
if
sort
==
'seriesasc'
:
order
=
[
db
.
Books
.
series_index
.
asc
()]
if
sort
==
'seriesdesc'
:
...
...
@@ -410,7 +410,10 @@ def render_books_list(data, sort, book_id, page):
return
render_adv_search_results
(
term
,
offset
,
order
,
config
.
config_books_per_page
)
else
:
website
=
data
or
"newest"
entries
,
random
,
pagination
=
calibre_db
.
fill_indexpage
(
page
,
0
,
db
.
Books
,
True
,
order
)
entries
,
random
,
pagination
=
calibre_db
.
fill_indexpage
(
page
,
0
,
db
.
Books
,
True
,
order
,
db
.
books_series_link
,
db
.
Books
.
id
==
db
.
books_series_link
.
c
.
book
,
db
.
Series
)
return
render_title_template
(
'index.html'
,
random
=
random
,
entries
=
entries
,
pagination
=
pagination
,
title
=
_
(
u"Books"
),
page
=
website
)
...
...
@@ -509,8 +512,10 @@ def render_author_books(page, author_id, order):
flash
(
_
(
u"Oops! Selected book title is unavailable. File does not exist or is not accessible"
),
category
=
"error"
)
return
redirect
(
url_for
(
"web.index"
))
author
=
calibre_db
.
session
.
query
(
db
.
Authors
)
.
get
(
author_id
)
if
constants
.
sqlalchemy_version2
:
author
=
calibre_db
.
session
.
get
(
db
.
Authors
,
author_id
)
else
:
author
=
calibre_db
.
session
.
query
(
db
.
Authors
)
.
get
(
author_id
)
author_name
=
author
.
name
.
replace
(
'|'
,
','
)
author_info
=
None
...
...
@@ -713,7 +718,8 @@ def render_prepare_search_form(cc):
def
render_search_results
(
term
,
offset
=
None
,
order
=
None
,
limit
=
None
):
entries
,
result_count
,
pagination
=
calibre_db
.
get_search_results
(
term
,
offset
,
order
,
limit
)
join
=
db
.
books_series_link
,
db
.
Books
.
id
==
db
.
books_series_link
.
c
.
book
,
db
.
Series
entries
,
result_count
,
pagination
=
calibre_db
.
get_search_results
(
term
,
offset
,
order
,
limit
,
*
join
)
return
render_title_template
(
'search.html'
,
searchterm
=
term
,
pagination
=
pagination
,
...
...
@@ -775,8 +781,10 @@ def list_books():
order
=
[
db
.
Publishers
.
name
.
asc
()]
if
order
==
"asc"
else
[
db
.
Publishers
.
name
.
desc
()]
join
=
db
.
books_publishers_link
,
db
.
Books
.
id
==
db
.
books_publishers_link
.
c
.
book
,
db
.
Publishers
elif
sort
==
"authors"
:
order
=
[
db
.
Authors
.
name
.
asc
()]
if
order
==
"asc"
else
[
db
.
Authors
.
name
.
desc
()]
join
=
db
.
books_authors_link
,
db
.
Books
.
id
==
db
.
books_authors_link
.
c
.
book
,
db
.
Authors
order
=
[
db
.
Authors
.
name
.
asc
(),
db
.
Series
.
name
,
db
.
Books
.
series_index
]
if
order
==
"asc"
\
else
[
db
.
Authors
.
name
.
desc
(),
db
.
Series
.
name
.
desc
(),
db
.
Books
.
series_index
.
desc
()]
join
=
db
.
books_authors_link
,
db
.
Books
.
id
==
db
.
books_authors_link
.
c
.
book
,
db
.
Authors
,
\
db
.
books_series_link
,
db
.
Books
.
id
==
db
.
books_series_link
.
c
.
book
,
db
.
Series
elif
sort
==
"languages"
:
order
=
[
db
.
Languages
.
lang_code
.
asc
()]
if
order
==
"asc"
else
[
db
.
Languages
.
lang_code
.
desc
()]
join
=
db
.
books_languages_link
,
db
.
Books
.
id
==
db
.
books_languages_link
.
c
.
book
,
db
.
Languages
...
...
@@ -793,7 +801,7 @@ def list_books():
filtered_count
=
len
(
books
)
else
:
books
=
calibre_db
.
session
.
query
(
db
.
Books
)
.
filter
(
calibre_db
.
common_filters
())
.
all
()
entries
=
calibre_db
.
get_checkbox_sorted
(
books
,
state
,
off
,
limit
,
order
)
entries
=
calibre_db
.
get_checkbox_sorted
(
books
,
state
,
off
,
limit
,
order
)
elif
search
:
entries
,
filtered_count
,
__
=
calibre_db
.
get_search_results
(
search
,
off
,
order
,
limit
,
*
join
)
else
:
...
...
@@ -1242,7 +1250,9 @@ def render_adv_search_results(term, offset=None, order=None, limit=None):
cc
=
get_cc_columns
(
filter_config_custom_read
=
True
)
calibre_db
.
session
.
connection
()
.
connection
.
connection
.
create_function
(
"lower"
,
1
,
db
.
lcase
)
q
=
calibre_db
.
session
.
query
(
db
.
Books
)
.
filter
(
calibre_db
.
common_filters
(
True
))
q
=
calibre_db
.
session
.
query
(
db
.
Books
)
.
outerjoin
(
db
.
books_series_link
,
db
.
Books
.
id
==
db
.
books_series_link
.
c
.
book
)
\
.
outerjoin
(
db
.
Series
)
\
.
filter
(
calibre_db
.
common_filters
(
True
))
# parse multiselects to a complete dict
tags
=
dict
()
...
...
@@ -1587,15 +1597,14 @@ def change_profile(kobo_support, local_oauth_check, oauth_status, translations,
if
to_save
.
get
(
"password"
):
current_user
.
password
=
generate_password_hash
(
to_save
[
"password"
])
try
:
if
to_save
.
get
(
"allowed_tags"
,
current_user
.
allowed_tags
)
!=
current_user
.
allowed_tags
:
current_user
.
allowed_tags
=
to_save
[
"allowed_tags"
]
.
strip
()
if
to_save
.
get
(
"kindle_mail"
,
current_user
.
kindle_mail
)
!=
current_user
.
kindle_mail
:
current_user
.
kindle_mail
=
valid_email
(
to_save
[
"kindle_mail"
])
if
to_save
.
get
(
"email"
,
current_user
.
email
)
!=
current_user
.
email
:
current_user
.
email
=
check_email
(
to_save
[
"email"
])
if
to_save
.
get
(
"name"
,
current_user
.
name
)
!=
current_user
.
name
:
# Query User name, if not existing, change
current_user
.
name
=
check_username
(
to_save
[
"name"
])
if
current_user
.
role_admin
():
if
to_save
.
get
(
"name"
,
current_user
.
name
)
!=
current_user
.
name
:
# Query User name, if not existing, change
current_user
.
name
=
check_username
(
to_save
[
"name"
])
current_user
.
random_books
=
1
if
to_save
.
get
(
"show_random"
)
==
"on"
else
0
if
to_save
.
get
(
"default_language"
):
current_user
.
default_language
=
to_save
[
"default_language"
]
...
...
@@ -1605,10 +1614,16 @@ def change_profile(kobo_support, local_oauth_check, oauth_status, translations,
except
Exception
as
ex
:
flash
(
str
(
ex
),
category
=
"error"
)
return
render_title_template
(
"user_edit.html"
,
content
=
current_user
,
title
=
_
(
u"
%(name)
s's profile"
,
name
=
current_user
.
name
),
page
=
"me"
,
return
render_title_template
(
"user_edit.html"
,
content
=
current_user
,
translations
=
translations
,
profile
=
1
,
languages
=
languages
,
title
=
_
(
u"
%(name)
s's profile"
,
name
=
current_user
.
name
),
page
=
"me"
,
kobo_support
=
kobo_support
,
registered_oauth
=
local_oauth_check
,
oauth_status
=
oauth_status
)
registered_oauth
=
local_oauth_check
,
oauth_status
=
oauth_status
)
val
=
0
for
key
,
__
in
to_save
.
items
():
...
...
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