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
554bc6aa
Commit
554bc6aa
authored
Apr 29, 2016
by
Jan B
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #17 from cervinko/feature-rights-management
add user-permission management
parents
f7e86804
38330799
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
294 additions
and
133 deletions
+294
-133
config.py
cps/config.py
+4
-0
detail.html
cps/templates/detail.html
+1
-1
layout.html
cps/templates/layout.html
+2
-2
user_edit.html
cps/templates/user_edit.html
+23
-5
user_list.html
cps/templates/user_list.html
+11
-1
ub.py
cps/ub.py
+134
-105
web.py
cps/web.py
+119
-19
No files found.
cps/config.py
View file @
554bc6aa
...
...
@@ -60,6 +60,7 @@ TITLE_REGEX = check_setting_str(CFG, 'Advanced', 'TITLE_REGEX', '^(A|The|An|Der|
DEVELOPMENT
=
bool
(
check_setting_int
(
CFG
,
'Advanced'
,
'DEVELOPMENT'
,
0
))
PUBLIC_REG
=
bool
(
check_setting_int
(
CFG
,
'Advanced'
,
'PUBLIC_REG'
,
0
))
UPLOADING
=
bool
(
check_setting_int
(
CFG
,
'Advanced'
,
'UPLOADING'
,
0
))
ANO_SHOW_BOOKS
=
bool
(
check_setting_int
(
CFG
,
'Advanced'
,
'ANO_SHOW_BOOKS'
,
0
))
SYS_ENCODING
=
"UTF-8"
...
...
@@ -78,6 +79,8 @@ configval["DEVELOPMENT"] = DEVELOPMENT
configval
[
"TITLE_REGEX"
]
=
TITLE_REGEX
configval
[
"PUBLIC_REG"
]
=
PUBLIC_REG
configval
[
"UPLOADING"
]
=
UPLOADING
configval
[
"ANO_SHOW_BOOKS"
]
=
ANO_SHOW_BOOKS
def
save_config
(
configval
):
new_config
=
ConfigObj
()
...
...
@@ -94,6 +97,7 @@ def save_config(configval):
new_config
[
'Advanced'
][
'DEVELOPMENT'
]
=
int
(
configval
[
"DEVELOPMENT"
])
new_config
[
'Advanced'
][
'PUBLIC_REG'
]
=
int
(
configval
[
"PUBLIC_REG"
])
new_config
[
'Advanced'
][
'UPLOADING'
]
=
int
(
configval
[
"UPLOADING"
])
new_config
[
'Advanced'
][
'ANO_SHOW_BOOKS'
]
=
int
(
configval
[
"ANO_SHOW_BOOKS"
])
new_config
.
write
()
return
"Saved"
...
...
cps/templates/detail.html
View file @
554bc6aa
...
...
@@ -154,7 +154,7 @@
</div>
{% endif %}
{% if g.user.role %}
{% if g.user.role
_edit()
%}
<div
class=
"btn-toolbar"
role=
"toolbar"
>
<div
class=
"btn-group"
role=
"group"
aria-label=
"Edit/Delete book"
>
<a
href=
"{{ url_for('edit_book', book_id=entry.id) }}"
class=
"btn btn-sm btn-warning"
role=
"button"
><span
class=
"glyphicon glyphicon-edit"
></span>
Edit metadata
</a>
...
...
cps/templates/layout.html
View file @
554bc6aa
...
...
@@ -63,7 +63,7 @@
</ul>
<ul
class=
"nav navbar-nav navbar-right"
id=
"main-nav"
>
{% if g.user.is_authenticated() %}
{% if g.user.role
%}
{% if g.user.role
_upload() or g.user.role_admin()
%}
{% if g.allow_upload %}
<li>
<form
id=
"form-upload"
class=
"navbar-form"
action=
"{{ url_for('upload') }}"
method=
"post"
enctype=
"multipart/form-data"
>
...
...
@@ -74,7 +74,7 @@
</li>
{% endif %}
{% endif %}
{% if g.user.role %}
{% if g.user.role
_admin()
%}
<li><a
href=
"{{url_for('user_list')}}"
><span
class=
"glyphicon glyphicon-dashboard"
></span>
Admin
</a></li>
{% endif %}
<li><a
href=
"{{url_for('profile')}}"
><span
class=
"glyphicon glyphicon-user"
></span>
{{g.user.nickname}}
</a></li>
...
...
cps/templates/user_edit.html
View file @
554bc6aa
...
...
@@ -3,7 +3,7 @@
<div
class=
"discover"
>
<h1>
{{title}}
</h1>
<form
role=
"form"
method=
"POST"
>
{% if g.user and g.user.role and new_user %}
{% if g.user and g.user.role
_admin()
and new_user %}
<div
class=
"form-group required"
>
<label
for=
"nickname"
>
Username
</label>
<input
type=
"text"
class=
"form-control"
name=
"nickname"
id=
"nickname"
value=
"{{ content.nickname if content.nickname != None }}"
>
...
...
@@ -13,21 +13,39 @@
<label
for=
"email"
>
Email address
</label>
<input
type=
"email"
class=
"form-control"
name=
"email"
id=
"email"
value=
"{{ content.email if content.email != None }}"
required
>
</div>
{% if g.user and g.user.role_passwd() or g.user.role_admin()%}
<div
class=
"form-group"
>
<label
for=
"password"
>
Password
</label>
<input
type=
"password"
class=
"form-control"
name=
"password"
id=
"password"
value=
""
>
</div>
{% endif %}
<div
class=
"form-group"
>
<label
for=
"kindle_mail"
>
Kindle E-Mail
</label>
<input
type=
"text"
class=
"form-control"
name=
"kindle_mail"
id=
"kindle_mail"
value=
"{{ content.kindle_mail if content.kindle_mail != None }}"
>
</div>
{% if g.user and g.user.role and not profile %}
{% if g.user and g.user.role_admin() and not profile %}
<div
class=
"form-group"
>
<label
for=
"admin_role"
>
Admin user
</label>
<input
type=
"checkbox"
name=
"admin_role"
id=
"admin_role"
{%
if
content
.
role_admin
()
%}
checked
{%
endif
%}
>
</div>
<div
class=
"form-group"
>
<label
for=
"download_role"
>
Allow Downloads
</label>
<input
type=
"checkbox"
name=
"download_role"
id=
"download_role"
{%
if
content
.
role_download
()
%}
checked
{%
endif
%}
>
</div>
<div
class=
"form-group"
>
<label
for=
"upload_role"
>
Allow Uploads
</label>
<input
type=
"checkbox"
name=
"upload_role"
id=
"upload_role"
{%
if
content
.
role_upload
()
%}
checked
{%
endif
%}
>
</div>
<div
class=
"form-group"
>
<label
for=
"edit_role"
>
Allow Edit
</label>
<input
type=
"checkbox"
name=
"edit_role"
id=
"edit_role"
{%
if
content
.
role_edit
()
%}
checked
{%
endif
%}
>
</div>
<div
class=
"form-group"
>
<label
for=
"
user_role"
>
Admin user
</label>
<input
type=
"checkbox"
name=
"
admin_user"
id=
"admin_user"
{%
if
content
.
role
%}
checked
{%
endif
%}
>
<label
for=
"
passwd_role"
>
Allow Changing Password
</label>
<input
type=
"checkbox"
name=
"
passwd_role"
id=
"passwd_role"
{%
if
content
.
role_passwd
()
%}
checked
{%
endif
%}
>
</div>
{% endif %}
{% if g.user and g.user.role and not profile and not new_user %}
{% if g.user and g.user.role
_admin()
and not profile and not new_user %}
<div
class=
"checkbox"
>
<label>
<input
type=
"checkbox"
name=
"delete"
>
Delete this user
...
...
cps/templates/user_list.html
View file @
554bc6aa
...
...
@@ -9,6 +9,11 @@
<th>
Kindle
</th>
<th>
DLS
</th>
<th>
Admin
</th>
<th>
Download
</th>
<th>
Upload
</th>
<th>
Edit
</th>
<th>
Passwd
</th>
</tr>
{% for user in content %}
<tr>
...
...
@@ -16,7 +21,12 @@
<td>
{{user.email}}
</td>
<td>
{{user.kindle_mail}}
</td>
<td>
{{user.downloads.count()}}
</td>
<td>
{% if user.role %}
<span
class=
"glyphicon glyphicon-ok"
></span>
{% else %}
<span
class=
"glyphicon glyphicon-remove"
></span>
{% endif %}
</td>
<td>
{% if user.role_admin() %}
<span
class=
"glyphicon glyphicon-ok"
></span>
{% else %}
<span
class=
"glyphicon glyphicon-remove"
></span>
{% endif %}
</td>
<td>
{% if user.role_download() %}
<span
class=
"glyphicon glyphicon-ok"
></span>
{% else %}
<span
class=
"glyphicon glyphicon-remove"
></span>
{% endif %}
</td>
<td>
{% if user.role_upload() %}
<span
class=
"glyphicon glyphicon-ok"
></span>
{% else %}
<span
class=
"glyphicon glyphicon-remove"
></span>
{% endif %}
</td>
<td>
{% if user.role_edit() %}
<span
class=
"glyphicon glyphicon-ok"
></span>
{% else %}
<span
class=
"glyphicon glyphicon-remove"
></span>
{% endif %}
</td>
<td>
{% if user.role_passwd() %}
<span
class=
"glyphicon glyphicon-ok"
></span>
{% else %}
<span
class=
"glyphicon glyphicon-remove"
></span>
{% endif %}
</td>
{% endfor %}
</table>
<div
class=
"btn btn-default"
><a
href=
"{{url_for('new_user')}}"
>
Add new user
</a></div>
...
...
cps/ub.py
View file @
554bc6aa
...
...
@@ -14,157 +14,186 @@ Base = declarative_base()
ROLE_USER
=
0
ROLE_ADMIN
=
1
ROLE_DOWNLOAD
=
2
ROLE_UPLOAD
=
4
ROLE_EDIT
=
8
ROLE_PASSWD
=
16
DEFAULT_PASS
=
"admin123"
class
User
(
Base
):
__tablename__
=
'user'
id
=
Column
(
Integer
,
primary_key
=
True
)
nickname
=
Column
(
String
(
64
),
unique
=
True
)
email
=
Column
(
String
(
120
),
unique
=
True
,
default
=
""
)
role
=
Column
(
SmallInteger
,
default
=
ROLE_USER
)
password
=
Column
(
String
)
kindle_mail
=
Column
(
String
(
120
),
default
=
""
)
shelf
=
relationship
(
'Shelf'
,
backref
=
'user'
,
lazy
=
'dynamic'
)
whislist
=
relationship
(
'Whislist'
,
backref
=
'user'
,
lazy
=
'dynamic'
)
downloads
=
relationship
(
'Downloads'
,
backref
=
'user'
,
lazy
=
'dynamic'
)
def
is_authenticated
(
self
):
return
True
def
is_active
(
self
):
return
True
def
is_anonymous
(
self
):
return
False
def
get_id
(
self
):
return
unicode
(
self
.
id
)
def
__repr__
(
self
):
return
'<User
%
r>'
%
(
self
.
nickname
)
__tablename__
=
'user'
id
=
Column
(
Integer
,
primary_key
=
True
)
nickname
=
Column
(
String
(
64
),
unique
=
True
)
email
=
Column
(
String
(
120
),
unique
=
True
,
default
=
""
)
role
=
Column
(
SmallInteger
,
default
=
ROLE_USER
)
password
=
Column
(
String
)
kindle_mail
=
Column
(
String
(
120
),
default
=
""
)
shelf
=
relationship
(
'Shelf'
,
backref
=
'user'
,
lazy
=
'dynamic'
)
whislist
=
relationship
(
'Whislist'
,
backref
=
'user'
,
lazy
=
'dynamic'
)
downloads
=
relationship
(
'Downloads'
,
backref
=
'user'
,
lazy
=
'dynamic'
)
def
is_authenticated
(
self
):
return
True
def
role_admin
(
self
):
if
self
.
role
is
not
None
:
return
True
if
self
.
role
&
ROLE_ADMIN
==
ROLE_ADMIN
else
False
else
:
return
False
def
role_download
(
self
):
if
self
.
role
is
not
None
:
return
True
if
self
.
role
&
ROLE_DOWNLOAD
==
ROLE_DOWNLOAD
else
False
else
:
return
False
def
role_upload
(
self
):
if
self
.
role
is
not
None
:
return
True
if
self
.
role
&
ROLE_UPLOAD
==
ROLE_UPLOAD
else
False
else
:
return
False
def
role_edit
(
self
):
if
self
.
role
is
not
None
:
return
True
if
self
.
role
&
ROLE_EDIT
==
ROLE_EDIT
else
False
else
:
return
False
def
role_passwd
(
self
):
if
self
.
role
is
not
None
:
return
True
if
self
.
role
&
ROLE_PASSWD
==
ROLE_PASSWD
else
False
else
:
return
False
def
is_active
(
self
):
return
True
def
is_anonymous
(
self
):
return
False
def
get_id
(
self
):
return
unicode
(
self
.
id
)
def
__repr__
(
self
):
return
'<User
%
r>'
%
(
self
.
nickname
)
class
Shelf
(
Base
):
__tablename__
=
'shelf'
__tablename__
=
'shelf'
id
=
Column
(
Integer
,
primary_key
=
True
)
name
=
Column
(
String
)
is_public
=
Column
(
Integer
,
default
=
0
)
user_id
=
Column
(
Integer
,
ForeignKey
(
'user.id'
))
id
=
Column
(
Integer
,
primary_key
=
True
)
name
=
Column
(
String
)
is_public
=
Column
(
Integer
,
default
=
0
)
user_id
=
Column
(
Integer
,
ForeignKey
(
'user.id'
))
def
__repr__
(
self
):
return
'<Shelf
%
r>'
%
(
self
.
name
)
def
__repr__
(
self
):
return
'<Shelf
%
r>'
%
(
self
.
name
)
class
Whislist
(
Base
):
__tablename__
=
"wishlist"
__tablename__
=
"wishlist"
id
=
Column
(
Integer
,
primary_key
=
True
)
name
=
Column
(
String
)
is_public
=
Column
(
String
)
user_id
=
Column
(
Integer
,
ForeignKey
(
'user.id'
))
id
=
Column
(
Integer
,
primary_key
=
True
)
name
=
Column
(
String
)
is_public
=
Column
(
String
)
user_id
=
Column
(
Integer
,
ForeignKey
(
'user.id'
))
def
__init__
(
self
):
pass
def
__init__
(
self
):
pass
def
__repr__
(
self
):
return
'<Whislist
%
r>'
%
(
self
.
name
)
def
__repr__
(
self
):
return
'<Whislist
%
r>'
%
(
self
.
name
)
class
BookShelf
(
Base
):
__tablename__
=
'book_shelf_link'
__tablename__
=
'book_shelf_link'
id
=
Column
(
Integer
,
primary_key
=
True
)
book_id
=
Column
(
Integer
)
shelf
=
Column
(
Integer
,
ForeignKey
(
'shelf.id'
))
id
=
Column
(
Integer
,
primary_key
=
True
)
book_id
=
Column
(
Integer
)
shelf
=
Column
(
Integer
,
ForeignKey
(
'shelf.id'
))
def
__repr__
(
self
):
return
'<Book
%
r>'
%
(
self
.
id
)
def
__repr__
(
self
):
return
'<Book
%
r>'
%
(
self
.
id
)
class
Downloads
(
Base
):
__tablename__
=
'downloads'
__tablename__
=
'downloads'
id
=
Column
(
Integer
,
primary_key
=
True
)
book_id
=
Column
(
Integer
)
user_id
=
Column
(
Integer
,
ForeignKey
(
'user.id'
))
id
=
Column
(
Integer
,
primary_key
=
True
)
book_id
=
Column
(
Integer
)
user_id
=
Column
(
Integer
,
ForeignKey
(
'user.id'
))
def
__repr__
(
self
):
return
'<Download
%
r'
%
(
self
.
book_id
)
def
__repr__
(
self
):
return
'<Download
%
r'
%
(
self
.
book_id
)
class
Whish
(
Base
):
__tablename__
=
'whish'
__tablename__
=
'whish'
id
=
Column
(
Integer
,
primary_key
=
True
)
title
=
Column
(
String
)
url
=
Column
(
String
)
wishlist
=
Column
(
Integer
,
ForeignKey
(
'wishlist.id'
))
id
=
Column
(
Integer
,
primary_key
=
True
)
title
=
Column
(
String
)
url
=
Column
(
String
)
wishlist
=
Column
(
Integer
,
ForeignKey
(
'wishlist.id'
))
def
__repr__
(
self
):
return
'<Whish
%
r>'
%
(
self
.
title
)
def
__repr__
(
self
):
return
'<Whish
%
r>'
%
(
self
.
title
)
class
Settings
(
Base
):
__tablename__
=
'settings'
__tablename__
=
'settings'
id
=
Column
(
Integer
,
primary_key
=
True
)
mail_server
=
Column
(
String
)
mail_port
=
Column
(
Integer
,
default
=
25
)
mail_use_ssl
=
Column
(
SmallInteger
,
default
=
0
)
mail_login
=
Column
(
String
)
mail_password
=
Column
(
String
)
mail_from
=
Column
(
String
)
id
=
Column
(
Integer
,
primary_key
=
True
)
mail_server
=
Column
(
String
)
mail_port
=
Column
(
Integer
,
default
=
25
)
mail_use_ssl
=
Column
(
SmallInteger
,
default
=
0
)
mail_login
=
Column
(
String
)
mail_password
=
Column
(
String
)
mail_from
=
Column
(
String
)
def
__repr__
(
self
):
#return '<Smtp %r>' % (self.mail_server)
pass
def
__repr__
(
self
):
#return '<Smtp %r>' % (self.mail_server)
pass
def
create_default_config
():
settings
=
Settings
()
settings
.
mail_server
=
"mail.example.com"
settings
.
mail_port
=
25
settings
.
mail_use_ssl
=
0
settings
.
mail_login
=
"mail@example.com"
settings
.
mail_password
=
"mypassword"
settings
.
mail_from
=
"automailer <mail@example.com>"
settings
=
Settings
()
settings
.
mail_server
=
"mail.example.com"
settings
.
mail_port
=
25
settings
.
mail_use_ssl
=
0
settings
.
mail_login
=
"mail@example.com"
settings
.
mail_password
=
"mypassword"
settings
.
mail_from
=
"automailer <mail@example.com>"
session
.
add
(
settings
)
session
.
commit
()
session
.
add
(
settings
)
session
.
commit
()
def
get_mail_settings
():
settings
=
session
.
query
(
Settings
)
.
first
()
settings
=
session
.
query
(
Settings
)
.
first
()
if
not
settings
:
return
{}
if
not
settings
:
return
{}
data
=
{
'mail_server'
:
settings
.
mail_server
,
'mail_port'
:
settings
.
mail_port
,
'mail_use_ssl'
:
settings
.
mail_use_ssl
,
'mail_login'
:
settings
.
mail_login
,
'mail_password'
:
settings
.
mail_password
,
'mail_from'
:
settings
.
mail_from
}
data
=
{
'mail_server'
:
settings
.
mail_server
,
'mail_port'
:
settings
.
mail_port
,
'mail_use_ssl'
:
settings
.
mail_use_ssl
,
'mail_login'
:
settings
.
mail_login
,
'mail_password'
:
settings
.
mail_password
,
'mail_from'
:
settings
.
mail_from
}
return
data
return
data
def
create_admin_user
():
user
=
User
()
user
.
nickname
=
"admin"
user
.
role
=
1
user
.
password
=
generate_password_hash
(
DEFAULT_PASS
)
user
=
User
()
user
.
nickname
=
"admin"
user
.
role
=
ROLE_USER
+
ROLE_ADMIN
+
ROLE_DOWNLOAD
+
ROLE_UPLOAD
+
ROLE_EDIT
+
ROLE_PASSWD
user
.
password
=
generate_password_hash
(
DEFAULT_PASS
)
session
.
add
(
user
)
session
.
commit
()
session
.
add
(
user
)
session
.
commit
()
Session
=
sessionmaker
()
Session
.
configure
(
bind
=
engine
)
session
=
Session
()
if
not
os
.
path
.
exists
(
dbpath
):
try
:
Base
.
metadata
.
create_all
(
engine
)
create_default_config
()
create_admin_user
()
except
Exception
:
pass
try
:
Base
.
metadata
.
create_all
(
engine
)
create_default_config
()
create_admin_user
()
except
Exception
:
pass
cps/web.py
View file @
554bc6aa
...
...
@@ -14,7 +14,7 @@ from sqlalchemy.sql.expression import func
from
sqlalchemy.sql.expression
import
false
from
sqlalchemy.exc
import
IntegrityError
from
math
import
ceil
from
flask.ext.login
import
LoginManager
,
login_user
,
logout_user
,
login_required
,
current_user
from
flask.ext.login
import
LoginManager
,
login_user
,
logout_user
,
login_required
,
current_user
,
AnonymousUserMixin
from
flask.ext.principal
import
Principal
,
Identity
,
AnonymousIdentity
,
identity_changed
import
requests
,
zipfile
from
werkzeug.security
import
generate_password_hash
,
check_password_hash
...
...
@@ -43,9 +43,23 @@ app.logger.info('Starting Calibre Web...')
Principal
(
app
)
class
Anonymous
(
AnonymousUserMixin
):
def
__init__
(
self
):
self
.
nickname
=
'Guest'
self
.
role
=
-
1
def
role_admin
(
self
):
return
False
def
role_download
(
self
):
return
False
def
role_upload
(
self
):
return
False
def
role_edit
(
self
):
return
False
lm
=
LoginManager
(
app
)
lm
.
init_app
(
app
)
lm
.
login_view
=
'login'
lm
.
anonymous_user
=
Anonymous
app
.
secret_key
=
'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'
...
...
@@ -82,12 +96,13 @@ def authenticate():
'You have to login with proper credentials'
,
401
,
{
'WWW-Authenticate'
:
'Basic realm="Login Required"'
})
def
requires_basic_auth
(
f
):
def
requires_basic_auth
_if_no_ano
(
f
):
@
wraps
(
f
)
def
decorated
(
*
args
,
**
kwargs
):
auth
=
request
.
authorization
if
not
auth
or
not
check_auth
(
auth
.
username
,
auth
.
password
):
return
authenticate
()
if
config
.
ANO_SHOW_BOOKS
!=
1
:
if
not
auth
or
not
check_auth
(
auth
.
username
,
auth
.
password
):
return
authenticate
()
return
f
(
*
args
,
**
kwargs
)
return
decorated
...
...
@@ -132,6 +147,11 @@ def url_for_other_page(page):
app
.
jinja_env
.
globals
[
'url_for_other_page'
]
=
url_for_other_page
def
login_required_if_no_ano
(
func
):
if
config
.
ANO_SHOW_BOOKS
==
1
:
return
func
return
login_required
(
func
)
## custom jinja filters
@
app
.
template_filter
(
'shortentitle'
)
def
shortentitle_filter
(
s
):
...
...
@@ -147,7 +167,29 @@ def admin_required(f):
"""
@
wraps
(
f
)
def
inner
(
*
args
,
**
kwargs
):
if
int
(
current_user
.
role
)
==
1
:
if
current_user
.
role_admin
():
return
f
(
*
args
,
**
kwargs
)
abort
(
403
)
return
inner
def
download_required
(
f
):
@
wraps
(
f
)
def
inner
(
*
args
,
**
kwargs
):
if
current_user
.
role_download
()
or
current_user
.
role_admin
():
return
f
(
*
args
,
**
kwargs
)
abort
(
403
)
return
inner
def
upload_required
(
f
):
@
wraps
(
f
)
def
inner
(
*
args
,
**
kwargs
):
if
current_user
.
role_upload
()
or
current_user
.
role_admin
():
return
f
(
*
args
,
**
kwargs
)
abort
(
403
)
return
inner
def
edit_required
(
f
):
@
wraps
(
f
)
def
inner
(
*
args
,
**
kwargs
):
if
current_user
.
role_edit
()
or
current_user
.
role_admin
():
return
f
(
*
args
,
**
kwargs
)
abort
(
403
)
return
inner
...
...
@@ -160,6 +202,7 @@ def before_request():
g
.
allow_upload
=
config
.
UPLOADING
@
app
.
route
(
"/feed"
)
@
requires_basic_auth_if_no_ano
def
feed_index
():
xml
=
render_template
(
'index.xml'
)
response
=
make_response
(
xml
)
...
...
@@ -167,6 +210,7 @@ def feed_index():
return
response
@
app
.
route
(
"/feed/osd"
)
@
requires_basic_auth_if_no_ano
def
feed_osd
():
xml
=
render_template
(
'osd.xml'
)
response
=
make_response
(
xml
)
...
...
@@ -174,6 +218,7 @@ def feed_osd():
return
response
@
app
.
route
(
"/feed/search"
,
methods
=
[
"GET"
])
@
requires_basic_auth_if_no_ano
def
feed_search
():
term
=
request
.
args
.
get
(
"query"
)
if
term
:
...
...
@@ -187,6 +232,7 @@ def feed_search():
return
response
@
app
.
route
(
"/feed/new"
)
@
requires_basic_auth_if_no_ano
def
feed_new
():
off
=
request
.
args
.
get
(
"start_index"
)
if
off
:
...
...
@@ -201,6 +247,7 @@ def feed_new():
@
app
.
route
(
"/feed/discover"
)
@
requires_basic_auth_if_no_ano
def
feed_discover
():
off
=
request
.
args
.
get
(
"start_index"
)
if
off
:
...
...
@@ -214,6 +261,7 @@ def feed_discover():
return
response
@
app
.
route
(
"/feed/hot"
)
@
requires_basic_auth_if_no_ano
def
feed_hot
():
off
=
request
.
args
.
get
(
"start_index"
)
if
off
:
...
...
@@ -228,7 +276,8 @@ def feed_hot():
return
response
@
app
.
route
(
"/feed/download/<int:book_id>/<format>"
)
@
requires_basic_auth
@
requires_basic_auth_if_no_ano
@
download_required
def
get_opds_download_link
(
book_id
,
format
):
format
=
format
.
split
(
"."
)[
0
]
book
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book_id
)
.
first
()
...
...
@@ -244,6 +293,7 @@ def get_opds_download_link(book_id, format):
return
response
@
app
.
route
(
"/get_authors_json"
,
methods
=
[
'GET'
,
'POST'
])
@
login_required_if_no_ano
def
get_authors_json
():
if
request
.
method
==
"GET"
:
query
=
request
.
args
.
get
(
'q'
)
...
...
@@ -252,6 +302,7 @@ def get_authors_json():
return
json_dumps
@
app
.
route
(
"/get_tags_json"
,
methods
=
[
'GET'
,
'POST'
])
@
login_required_if_no_ano
def
get_tags_json
():
if
request
.
method
==
"GET"
:
query
=
request
.
args
.
get
(
'q'
)
...
...
@@ -260,6 +311,7 @@ def get_tags_json():
return
json_dumps
@
app
.
route
(
"/get_series_json"
,
methods
=
[
'GET'
,
'POST'
])
@
login_required_if_no_ano
def
get_series_json
():
if
request
.
method
==
"GET"
:
query
=
request
.
args
.
get
(
'q'
)
...
...
@@ -269,6 +321,7 @@ def get_series_json():
@
app
.
route
(
"/"
,
defaults
=
{
'page'
:
1
})
@
app
.
route
(
'/page/<int:page>'
)
@
login_required_if_no_ano
def
index
(
page
):
random
=
db
.
session
.
query
(
db
.
Books
)
.
order_by
(
func
.
random
())
.
limit
(
config
.
RANDOM_BOOKS
)
if
page
==
1
:
...
...
@@ -281,6 +334,7 @@ def index(page):
@
app
.
route
(
"/hot"
,
defaults
=
{
'page'
:
1
})
@
app
.
route
(
'/hot/page/<int:page>'
)
@
login_required_if_no_ano
def
hot_books
(
page
):
random
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
false
())
off
=
int
(
int
(
6
)
*
(
page
-
1
))
...
...
@@ -298,12 +352,14 @@ def hot_books(page):
return
render_template
(
'index.html'
,
random
=
random
,
entries
=
entries
,
title
=
"Hot Books (most downloaded)"
)
@
app
.
route
(
"/stats"
)
@
login_required
def
stats
():
counter
=
len
(
db
.
session
.
query
(
db
.
Books
)
.
all
())
return
render_template
(
'stats.html'
,
counter
=
counter
,
title
=
"Statistics"
)
@
app
.
route
(
"/discover"
,
defaults
=
{
'page'
:
1
})
@
app
.
route
(
'/discover/page/<int:page>'
)
@
login_required_if_no_ano
def
discover
(
page
):
if
page
==
1
:
entries
=
db
.
session
.
query
(
db
.
Books
)
.
order_by
(
func
.
randomblob
(
2
))
.
limit
(
config
.
NEWEST_BOOKS
)
...
...
@@ -314,6 +370,7 @@ def discover(page):
return
render_template
(
'discover.html'
,
entries
=
entries
,
pagination
=
pagination
,
title
=
"Random Books"
)
@
app
.
route
(
"/book/<int:id>"
)
@
login_required_if_no_ano
def
show_book
(
id
):
entries
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
id
)
.
first
()
cc
=
db
.
session
.
query
(
db
.
Custom_Columns
)
.
filter
(
db
.
Custom_Columns
.
datatype
.
notin_
(
db
.
cc_exceptions
))
.
all
()
...
...
@@ -324,11 +381,13 @@ def show_book(id):
return
render_template
(
'detail.html'
,
entry
=
entries
,
cc
=
cc
,
title
=
entries
.
title
,
books_shelfs
=
book_in_shelfs
)
@
app
.
route
(
"/category"
)
@
login_required_if_no_ano
def
category_list
():
entries
=
db
.
session
.
query
(
db
.
Tags
)
.
order_by
(
db
.
Tags
.
name
)
.
all
()
return
render_template
(
'categories.html'
,
entries
=
entries
,
title
=
"Category list"
)
@
app
.
route
(
"/category/<name>"
)
@
login_required_if_no_ano
def
category
(
name
):
random
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
false
())
if
name
!=
"all"
:
...
...
@@ -338,6 +397,7 @@ def category(name):
return
render_template
(
'index.html'
,
random
=
random
,
entries
=
entries
,
title
=
"Category:
%
s"
%
name
)
@
app
.
route
(
"/series/<name>"
)
@
login_required_if_no_ano
def
series
(
name
):
random
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
false
())
entries
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
series
.
any
(
db
.
Series
.
name
.
like
(
"
%
"
+
name
+
"
%
"
)))
.
order_by
(
db
.
Books
.
series_index
)
.
all
()
...
...
@@ -345,12 +405,14 @@ def series(name):
@
app
.
route
(
"/admin/"
)
@
login_required
def
admin
():
#return "Admin ONLY!"
abort
(
403
)
@
app
.
route
(
"/search"
,
methods
=
[
"GET"
])
@
login_required_if_no_ano
def
search
():
term
=
request
.
args
.
get
(
"query"
)
if
term
:
...
...
@@ -361,17 +423,20 @@ def search():
return
render_template
(
'search.html'
,
searchterm
=
""
)
@
app
.
route
(
"/author"
)
@
login_required_if_no_ano
def
author_list
():
entries
=
db
.
session
.
query
(
db
.
Authors
)
.
order_by
(
db
.
Authors
.
sort
)
.
all
()
return
render_template
(
'authors.html'
,
entries
=
entries
,
title
=
"Author list"
)
@
app
.
route
(
"/author/<name>"
)
@
login_required_if_no_ano
def
author
(
name
):
random
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
false
())
entries
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
authors
.
any
(
db
.
Authors
.
name
.
like
(
"
%
"
+
name
+
"
%
"
)))
.
all
()
return
render_template
(
'index.html'
,
random
=
random
,
entries
=
entries
,
title
=
"Author:
%
s"
%
name
)
@
app
.
route
(
"/cover/<path:cover_path>"
)
@
login_required_if_no_ano
def
get_cover
(
cover_path
):
return
send_from_directory
(
os
.
path
.
join
(
config
.
DB_ROOT
,
cover_path
),
"cover.jpg"
)
...
...
@@ -399,6 +464,7 @@ def read_book(book_id):
@
app
.
route
(
"/download/<int:book_id>/<format>"
)
@
login_required
@
download_required
def
get_download_link
(
book_id
,
format
):
format
=
format
.
split
(
"."
)[
0
]
book
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book_id
)
.
first
()
...
...
@@ -486,6 +552,7 @@ def logout():
@
app
.
route
(
'/send/<int:book_id>'
)
@
login_required
@
download_required
def
send_to_kindle
(
book_id
):
settings
=
ub
.
get_mail_settings
()
if
settings
.
get
(
"mail_server"
,
"mail.example.com"
)
==
"mail.example.com"
:
...
...
@@ -583,8 +650,9 @@ def profile():
downloads
.
append
(
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book
.
book_id
)
.
first
())
if
request
.
method
==
"POST"
:
to_save
=
request
.
form
.
to_dict
()
if
to_save
[
"password"
]:
content
.
password
=
generate_password_hash
(
to_save
[
"password"
])
if
current_user
.
role_passwd
()
or
current_user
.
role_admin
():
if
to_save
[
"password"
]:
content
.
password
=
generate_password_hash
(
to_save
[
"password"
])
if
to_save
[
"kindle_mail"
]
and
to_save
[
"kindle_mail"
]
!=
content
.
kindle_mail
:
content
.
kindle_mail
=
to_save
[
"kindle_mail"
]
if
to_save
[
"email"
]
and
to_save
[
"email"
]
!=
content
.
email
:
...
...
@@ -619,10 +687,17 @@ def new_user():
content
.
password
=
generate_password_hash
(
to_save
[
"password"
])
content
.
nickname
=
to_save
[
"nickname"
]
content
.
email
=
to_save
[
"email"
]
if
"admin_user"
in
to_save
:
content
.
role
=
1
else
:
content
.
role
=
0
content
.
role
=
0
if
"admin_role"
in
to_save
:
content
.
role
=
content
.
role
+
ub
.
ROLE_ADMIN
if
"download_role"
in
to_save
:
content
.
role
=
content
.
role
+
ub
.
ROLE_DOWNLOAD
if
"upload_role"
in
to_save
:
content
.
role
=
content
.
role
+
ub
.
ROLE_UPLOAD
if
"edit_role"
in
to_save
:
content
.
role
=
content
.
role
+
ub
.
ROLE_EDIT
if
"passwd_role"
in
to_save
:
content
.
role
=
content
.
role
+
ub
.
ROLE_PASSWD
try
:
ub
.
session
.
add
(
content
)
ub
.
session
.
commit
()
...
...
@@ -673,10 +748,32 @@ def edit_user(user_id):
else
:
if
to_save
[
"password"
]:
content
.
password
=
generate_password_hash
(
to_save
[
"password"
])
if
"admin_user"
in
to_save
and
content
.
role
!=
1
:
content
.
role
=
1
elif
not
"admin_user"
in
to_save
and
content
.
role
==
1
:
content
.
role
=
0
if
"admin_role"
in
to_save
and
not
content
.
role_admin
():
content
.
role
=
content
.
role
+
ub
.
ROLE_ADMIN
elif
not
"admin_role"
in
to_save
and
content
.
role_admin
():
content
.
role
=
content
.
role
-
ub
.
ROLE_ADMIN
if
"download_role"
in
to_save
and
not
content
.
role_download
():
content
.
role
=
content
.
role
+
ub
.
ROLE_DOWNLOAD
elif
not
"download_role"
in
to_save
and
content
.
role_download
():
content
.
role
=
content
.
role
-
ub
.
ROLE_DOWNLOAD
if
"upload_role"
in
to_save
and
not
content
.
role_upload
():
content
.
role
=
content
.
role
+
ub
.
ROLE_UPLOAD
elif
not
"upload_role"
in
to_save
and
content
.
role_upload
():
content
.
role
=
content
.
role
-
ub
.
ROLE_UPLOAD
if
"edit_role"
in
to_save
and
not
content
.
role_edit
():
content
.
role
=
content
.
role
+
ub
.
ROLE_EDIT
elif
not
"edit_role"
in
to_save
and
content
.
role_edit
():
content
.
role
=
content
.
role
-
ub
.
ROLE_EDIT
if
"passwd_role"
in
to_save
and
not
content
.
role_passwd
():
content
.
role
=
content
.
role
+
ub
.
ROLE_PASSWD
elif
not
"passwd_role"
in
to_save
and
content
.
role_passwd
():
content
.
role
=
content
.
role
-
ub
.
ROLE_PASSWD
if
to_save
[
"email"
]
and
to_save
[
"email"
]
!=
content
.
email
:
content
.
email
=
to_save
[
"email"
]
if
to_save
[
"kindle_mail"
]
and
to_save
[
"kindle_mail"
]
!=
content
.
kindle_mail
:
...
...
@@ -691,7 +788,7 @@ def edit_user(user_id):
@
app
.
route
(
"/admin/book/<int:book_id>"
,
methods
=
[
'GET'
,
'POST'
])
@
login_required
@
admin
_required
@
edit
_required
def
edit_book
(
book_id
):
## create the function for sorting...
db
.
session
.
connection
()
.
connection
.
connection
.
create_function
(
"title_sort"
,
1
,
db
.
title_sort
)
...
...
@@ -933,7 +1030,7 @@ def edit_book(book_id):
@
app
.
route
(
"/upload"
,
methods
=
[
"GET"
,
"POST"
])
@
login_required
@
admin
_required
@
upload
_required
def
upload
():
if
not
config
.
UPLOADING
:
abort
(
404
)
...
...
@@ -996,4 +1093,7 @@ def upload():
for
author
in
db_book
.
authors
:
author_names
.
append
(
author
.
name
)
cc
=
db
.
session
.
query
(
db
.
Custom_Columns
)
.
filter
(
db
.
Custom_Columns
.
datatype
.
notin_
(
db
.
cc_exceptions
))
.
all
()
return
render_template
(
'edit_book.html'
,
book
=
db_book
,
authors
=
author_names
,
cc
=
cc
)
if
current_user
.
role_edit
()
or
current_user
.
role_admin
():
return
render_template
(
'edit_book.html'
,
book
=
db_book
,
authors
=
author_names
,
cc
=
cc
)
book_in_shelfs
=
[]
return
render_template
(
'detail.html'
,
entry
=
db_book
,
cc
=
cc
,
title
=
db_book
.
title
,
books_shelfs
=
book_in_shelfs
)
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