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
Show 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|
...
@@ -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
))
DEVELOPMENT
=
bool
(
check_setting_int
(
CFG
,
'Advanced'
,
'DEVELOPMENT'
,
0
))
PUBLIC_REG
=
bool
(
check_setting_int
(
CFG
,
'Advanced'
,
'PUBLIC_REG'
,
0
))
PUBLIC_REG
=
bool
(
check_setting_int
(
CFG
,
'Advanced'
,
'PUBLIC_REG'
,
0
))
UPLOADING
=
bool
(
check_setting_int
(
CFG
,
'Advanced'
,
'UPLOADING'
,
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"
SYS_ENCODING
=
"UTF-8"
...
@@ -78,6 +79,8 @@ configval["DEVELOPMENT"] = DEVELOPMENT
...
@@ -78,6 +79,8 @@ configval["DEVELOPMENT"] = DEVELOPMENT
configval
[
"TITLE_REGEX"
]
=
TITLE_REGEX
configval
[
"TITLE_REGEX"
]
=
TITLE_REGEX
configval
[
"PUBLIC_REG"
]
=
PUBLIC_REG
configval
[
"PUBLIC_REG"
]
=
PUBLIC_REG
configval
[
"UPLOADING"
]
=
UPLOADING
configval
[
"UPLOADING"
]
=
UPLOADING
configval
[
"ANO_SHOW_BOOKS"
]
=
ANO_SHOW_BOOKS
def
save_config
(
configval
):
def
save_config
(
configval
):
new_config
=
ConfigObj
()
new_config
=
ConfigObj
()
...
@@ -94,6 +97,7 @@ def save_config(configval):
...
@@ -94,6 +97,7 @@ def save_config(configval):
new_config
[
'Advanced'
][
'DEVELOPMENT'
]
=
int
(
configval
[
"DEVELOPMENT"
])
new_config
[
'Advanced'
][
'DEVELOPMENT'
]
=
int
(
configval
[
"DEVELOPMENT"
])
new_config
[
'Advanced'
][
'PUBLIC_REG'
]
=
int
(
configval
[
"PUBLIC_REG"
])
new_config
[
'Advanced'
][
'PUBLIC_REG'
]
=
int
(
configval
[
"PUBLIC_REG"
])
new_config
[
'Advanced'
][
'UPLOADING'
]
=
int
(
configval
[
"UPLOADING"
])
new_config
[
'Advanced'
][
'UPLOADING'
]
=
int
(
configval
[
"UPLOADING"
])
new_config
[
'Advanced'
][
'ANO_SHOW_BOOKS'
]
=
int
(
configval
[
"ANO_SHOW_BOOKS"
])
new_config
.
write
()
new_config
.
write
()
return
"Saved"
return
"Saved"
...
...
cps/templates/detail.html
View file @
554bc6aa
...
@@ -154,7 +154,7 @@
...
@@ -154,7 +154,7 @@
</div>
</div>
{% endif %}
{% endif %}
{% if g.user.role %}
{% if g.user.role
_edit()
%}
<div
class=
"btn-toolbar"
role=
"toolbar"
>
<div
class=
"btn-toolbar"
role=
"toolbar"
>
<div
class=
"btn-group"
role=
"group"
aria-label=
"Edit/Delete book"
>
<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>
<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 @@
...
@@ -63,7 +63,7 @@
</ul>
</ul>
<ul
class=
"nav navbar-nav navbar-right"
id=
"main-nav"
>
<ul
class=
"nav navbar-nav navbar-right"
id=
"main-nav"
>
{% if g.user.is_authenticated() %}
{% if g.user.is_authenticated() %}
{% if g.user.role
%}
{% if g.user.role
_upload() or g.user.role_admin()
%}
{% if g.allow_upload %}
{% if g.allow_upload %}
<li>
<li>
<form
id=
"form-upload"
class=
"navbar-form"
action=
"{{ url_for('upload') }}"
method=
"post"
enctype=
"multipart/form-data"
>
<form
id=
"form-upload"
class=
"navbar-form"
action=
"{{ url_for('upload') }}"
method=
"post"
enctype=
"multipart/form-data"
>
...
@@ -74,7 +74,7 @@
...
@@ -74,7 +74,7 @@
</li>
</li>
{% endif %}
{% endif %}
{% 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>
<li><a
href=
"{{url_for('user_list')}}"
><span
class=
"glyphicon glyphicon-dashboard"
></span>
Admin
</a></li>
{% endif %}
{% endif %}
<li><a
href=
"{{url_for('profile')}}"
><span
class=
"glyphicon glyphicon-user"
></span>
{{g.user.nickname}}
</a></li>
<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 @@
...
@@ -3,7 +3,7 @@
<div
class=
"discover"
>
<div
class=
"discover"
>
<h1>
{{title}}
</h1>
<h1>
{{title}}
</h1>
<form
role=
"form"
method=
"POST"
>
<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"
>
<div
class=
"form-group required"
>
<label
for=
"nickname"
>
Username
</label>
<label
for=
"nickname"
>
Username
</label>
<input
type=
"text"
class=
"form-control"
name=
"nickname"
id=
"nickname"
value=
"{{ content.nickname if content.nickname != None }}"
>
<input
type=
"text"
class=
"form-control"
name=
"nickname"
id=
"nickname"
value=
"{{ content.nickname if content.nickname != None }}"
>
...
@@ -13,21 +13,39 @@
...
@@ -13,21 +13,39 @@
<label
for=
"email"
>
Email address
</label>
<label
for=
"email"
>
Email address
</label>
<input
type=
"email"
class=
"form-control"
name=
"email"
id=
"email"
value=
"{{ content.email if content.email != None }}"
required
>
<input
type=
"email"
class=
"form-control"
name=
"email"
id=
"email"
value=
"{{ content.email if content.email != None }}"
required
>
</div>
</div>
{% if g.user and g.user.role_passwd() or g.user.role_admin()%}
<div
class=
"form-group"
>
<div
class=
"form-group"
>
<label
for=
"password"
>
Password
</label>
<label
for=
"password"
>
Password
</label>
<input
type=
"password"
class=
"form-control"
name=
"password"
id=
"password"
value=
""
>
<input
type=
"password"
class=
"form-control"
name=
"password"
id=
"password"
value=
""
>
</div>
</div>
{% endif %}
<div
class=
"form-group"
>
<div
class=
"form-group"
>
<label
for=
"kindle_mail"
>
Kindle E-Mail
</label>
<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 }}"
>
<input
type=
"text"
class=
"form-control"
name=
"kindle_mail"
id=
"kindle_mail"
value=
"{{ content.kindle_mail if content.kindle_mail != None }}"
>
</div>
</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"
>
<div
class=
"form-group"
>
<label
for=
"
user_role"
>
Admin user
</label>
<label
for=
"
passwd_role"
>
Allow Changing Password
</label>
<input
type=
"checkbox"
name=
"
admin_user"
id=
"admin_user"
{%
if
content
.
role
%}
checked
{%
endif
%}
>
<input
type=
"checkbox"
name=
"
passwd_role"
id=
"passwd_role"
{%
if
content
.
role_passwd
()
%}
checked
{%
endif
%}
>
</div>
</div>
{% endif %}
{% 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"
>
<div
class=
"checkbox"
>
<label>
<label>
<input
type=
"checkbox"
name=
"delete"
>
Delete this user
<input
type=
"checkbox"
name=
"delete"
>
Delete this user
...
...
cps/templates/user_list.html
View file @
554bc6aa
...
@@ -9,6 +9,11 @@
...
@@ -9,6 +9,11 @@
<th>
Kindle
</th>
<th>
Kindle
</th>
<th>
DLS
</th>
<th>
DLS
</th>
<th>
Admin
</th>
<th>
Admin
</th>
<th>
Download
</th>
<th>
Upload
</th>
<th>
Edit
</th>
<th>
Passwd
</th>
</tr>
</tr>
{% for user in content %}
{% for user in content %}
<tr>
<tr>
...
@@ -16,7 +21,12 @@
...
@@ -16,7 +21,12 @@
<td>
{{user.email}}
</td>
<td>
{{user.email}}
</td>
<td>
{{user.kindle_mail}}
</td>
<td>
{{user.kindle_mail}}
</td>
<td>
{{user.downloads.count()}}
</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 %}
{% endfor %}
</table>
</table>
<div
class=
"btn btn-default"
><a
href=
"{{url_for('new_user')}}"
>
Add new user
</a></div>
<div
class=
"btn btn-default"
><a
href=
"{{url_for('new_user')}}"
>
Add new user
</a></div>
...
...
cps/ub.py
View file @
554bc6aa
...
@@ -14,6 +14,10 @@ Base = declarative_base()
...
@@ -14,6 +14,10 @@ Base = declarative_base()
ROLE_USER
=
0
ROLE_USER
=
0
ROLE_ADMIN
=
1
ROLE_ADMIN
=
1
ROLE_DOWNLOAD
=
2
ROLE_UPLOAD
=
4
ROLE_EDIT
=
8
ROLE_PASSWD
=
16
DEFAULT_PASS
=
"admin123"
DEFAULT_PASS
=
"admin123"
class
User
(
Base
):
class
User
(
Base
):
...
@@ -31,6 +35,31 @@ class User(Base):
...
@@ -31,6 +35,31 @@ class User(Base):
def
is_authenticated
(
self
):
def
is_authenticated
(
self
):
return
True
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
):
def
is_active
(
self
):
return
True
return
True
...
@@ -150,7 +179,7 @@ def get_mail_settings():
...
@@ -150,7 +179,7 @@ def get_mail_settings():
def
create_admin_user
():
def
create_admin_user
():
user
=
User
()
user
=
User
()
user
.
nickname
=
"admin"
user
.
nickname
=
"admin"
user
.
role
=
1
user
.
role
=
ROLE_USER
+
ROLE_ADMIN
+
ROLE_DOWNLOAD
+
ROLE_UPLOAD
+
ROLE_EDIT
+
ROLE_PASSWD
user
.
password
=
generate_password_hash
(
DEFAULT_PASS
)
user
.
password
=
generate_password_hash
(
DEFAULT_PASS
)
session
.
add
(
user
)
session
.
add
(
user
)
...
...
cps/web.py
View file @
554bc6aa
...
@@ -14,7 +14,7 @@ from sqlalchemy.sql.expression import func
...
@@ -14,7 +14,7 @@ from sqlalchemy.sql.expression import func
from
sqlalchemy.sql.expression
import
false
from
sqlalchemy.sql.expression
import
false
from
sqlalchemy.exc
import
IntegrityError
from
sqlalchemy.exc
import
IntegrityError
from
math
import
ceil
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
from
flask.ext.principal
import
Principal
,
Identity
,
AnonymousIdentity
,
identity_changed
import
requests
,
zipfile
import
requests
,
zipfile
from
werkzeug.security
import
generate_password_hash
,
check_password_hash
from
werkzeug.security
import
generate_password_hash
,
check_password_hash
...
@@ -43,9 +43,23 @@ app.logger.info('Starting Calibre Web...')
...
@@ -43,9 +43,23 @@ app.logger.info('Starting Calibre Web...')
Principal
(
app
)
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
=
LoginManager
(
app
)
lm
.
init_app
(
app
)
lm
.
init_app
(
app
)
lm
.
login_view
=
'login'
lm
.
login_view
=
'login'
lm
.
anonymous_user
=
Anonymous
app
.
secret_key
=
'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'
app
.
secret_key
=
'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'
...
@@ -82,10 +96,11 @@ def authenticate():
...
@@ -82,10 +96,11 @@ def authenticate():
'You have to login with proper credentials'
,
401
,
'You have to login with proper credentials'
,
401
,
{
'WWW-Authenticate'
:
'Basic realm="Login Required"'
})
{
'WWW-Authenticate'
:
'Basic realm="Login Required"'
})
def
requires_basic_auth
(
f
):
def
requires_basic_auth
_if_no_ano
(
f
):
@
wraps
(
f
)
@
wraps
(
f
)
def
decorated
(
*
args
,
**
kwargs
):
def
decorated
(
*
args
,
**
kwargs
):
auth
=
request
.
authorization
auth
=
request
.
authorization
if
config
.
ANO_SHOW_BOOKS
!=
1
:
if
not
auth
or
not
check_auth
(
auth
.
username
,
auth
.
password
):
if
not
auth
or
not
check_auth
(
auth
.
username
,
auth
.
password
):
return
authenticate
()
return
authenticate
()
return
f
(
*
args
,
**
kwargs
)
return
f
(
*
args
,
**
kwargs
)
...
@@ -132,6 +147,11 @@ def url_for_other_page(page):
...
@@ -132,6 +147,11 @@ def url_for_other_page(page):
app
.
jinja_env
.
globals
[
'url_for_other_page'
]
=
url_for_other_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
## custom jinja filters
@
app
.
template_filter
(
'shortentitle'
)
@
app
.
template_filter
(
'shortentitle'
)
def
shortentitle_filter
(
s
):
def
shortentitle_filter
(
s
):
...
@@ -147,7 +167,29 @@ def admin_required(f):
...
@@ -147,7 +167,29 @@ def admin_required(f):
"""
"""
@
wraps
(
f
)
@
wraps
(
f
)
def
inner
(
*
args
,
**
kwargs
):
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
)
return
f
(
*
args
,
**
kwargs
)
abort
(
403
)
abort
(
403
)
return
inner
return
inner
...
@@ -160,6 +202,7 @@ def before_request():
...
@@ -160,6 +202,7 @@ def before_request():
g
.
allow_upload
=
config
.
UPLOADING
g
.
allow_upload
=
config
.
UPLOADING
@
app
.
route
(
"/feed"
)
@
app
.
route
(
"/feed"
)
@
requires_basic_auth_if_no_ano
def
feed_index
():
def
feed_index
():
xml
=
render_template
(
'index.xml'
)
xml
=
render_template
(
'index.xml'
)
response
=
make_response
(
xml
)
response
=
make_response
(
xml
)
...
@@ -167,6 +210,7 @@ def feed_index():
...
@@ -167,6 +210,7 @@ def feed_index():
return
response
return
response
@
app
.
route
(
"/feed/osd"
)
@
app
.
route
(
"/feed/osd"
)
@
requires_basic_auth_if_no_ano
def
feed_osd
():
def
feed_osd
():
xml
=
render_template
(
'osd.xml'
)
xml
=
render_template
(
'osd.xml'
)
response
=
make_response
(
xml
)
response
=
make_response
(
xml
)
...
@@ -174,6 +218,7 @@ def feed_osd():
...
@@ -174,6 +218,7 @@ def feed_osd():
return
response
return
response
@
app
.
route
(
"/feed/search"
,
methods
=
[
"GET"
])
@
app
.
route
(
"/feed/search"
,
methods
=
[
"GET"
])
@
requires_basic_auth_if_no_ano
def
feed_search
():
def
feed_search
():
term
=
request
.
args
.
get
(
"query"
)
term
=
request
.
args
.
get
(
"query"
)
if
term
:
if
term
:
...
@@ -187,6 +232,7 @@ def feed_search():
...
@@ -187,6 +232,7 @@ def feed_search():
return
response
return
response
@
app
.
route
(
"/feed/new"
)
@
app
.
route
(
"/feed/new"
)
@
requires_basic_auth_if_no_ano
def
feed_new
():
def
feed_new
():
off
=
request
.
args
.
get
(
"start_index"
)
off
=
request
.
args
.
get
(
"start_index"
)
if
off
:
if
off
:
...
@@ -201,6 +247,7 @@ def feed_new():
...
@@ -201,6 +247,7 @@ def feed_new():
@
app
.
route
(
"/feed/discover"
)
@
app
.
route
(
"/feed/discover"
)
@
requires_basic_auth_if_no_ano
def
feed_discover
():
def
feed_discover
():
off
=
request
.
args
.
get
(
"start_index"
)
off
=
request
.
args
.
get
(
"start_index"
)
if
off
:
if
off
:
...
@@ -214,6 +261,7 @@ def feed_discover():
...
@@ -214,6 +261,7 @@ def feed_discover():
return
response
return
response
@
app
.
route
(
"/feed/hot"
)
@
app
.
route
(
"/feed/hot"
)
@
requires_basic_auth_if_no_ano
def
feed_hot
():
def
feed_hot
():
off
=
request
.
args
.
get
(
"start_index"
)
off
=
request
.
args
.
get
(
"start_index"
)
if
off
:
if
off
:
...
@@ -228,7 +276,8 @@ def feed_hot():
...
@@ -228,7 +276,8 @@ def feed_hot():
return
response
return
response
@
app
.
route
(
"/feed/download/<int:book_id>/<format>"
)
@
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
):
def
get_opds_download_link
(
book_id
,
format
):
format
=
format
.
split
(
"."
)[
0
]
format
=
format
.
split
(
"."
)[
0
]
book
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book_id
)
.
first
()
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):
...
@@ -244,6 +293,7 @@ def get_opds_download_link(book_id, format):
return
response
return
response
@
app
.
route
(
"/get_authors_json"
,
methods
=
[
'GET'
,
'POST'
])
@
app
.
route
(
"/get_authors_json"
,
methods
=
[
'GET'
,
'POST'
])
@
login_required_if_no_ano
def
get_authors_json
():
def
get_authors_json
():
if
request
.
method
==
"GET"
:
if
request
.
method
==
"GET"
:
query
=
request
.
args
.
get
(
'q'
)
query
=
request
.
args
.
get
(
'q'
)
...
@@ -252,6 +302,7 @@ def get_authors_json():
...
@@ -252,6 +302,7 @@ def get_authors_json():
return
json_dumps
return
json_dumps
@
app
.
route
(
"/get_tags_json"
,
methods
=
[
'GET'
,
'POST'
])
@
app
.
route
(
"/get_tags_json"
,
methods
=
[
'GET'
,
'POST'
])
@
login_required_if_no_ano
def
get_tags_json
():
def
get_tags_json
():
if
request
.
method
==
"GET"
:
if
request
.
method
==
"GET"
:
query
=
request
.
args
.
get
(
'q'
)
query
=
request
.
args
.
get
(
'q'
)
...
@@ -260,6 +311,7 @@ def get_tags_json():
...
@@ -260,6 +311,7 @@ def get_tags_json():
return
json_dumps
return
json_dumps
@
app
.
route
(
"/get_series_json"
,
methods
=
[
'GET'
,
'POST'
])
@
app
.
route
(
"/get_series_json"
,
methods
=
[
'GET'
,
'POST'
])
@
login_required_if_no_ano
def
get_series_json
():
def
get_series_json
():
if
request
.
method
==
"GET"
:
if
request
.
method
==
"GET"
:
query
=
request
.
args
.
get
(
'q'
)
query
=
request
.
args
.
get
(
'q'
)
...
@@ -269,6 +321,7 @@ def get_series_json():
...
@@ -269,6 +321,7 @@ def get_series_json():
@
app
.
route
(
"/"
,
defaults
=
{
'page'
:
1
})
@
app
.
route
(
"/"
,
defaults
=
{
'page'
:
1
})
@
app
.
route
(
'/page/<int:page>'
)
@
app
.
route
(
'/page/<int:page>'
)
@
login_required_if_no_ano
def
index
(
page
):
def
index
(
page
):
random
=
db
.
session
.
query
(
db
.
Books
)
.
order_by
(
func
.
random
())
.
limit
(
config
.
RANDOM_BOOKS
)
random
=
db
.
session
.
query
(
db
.
Books
)
.
order_by
(
func
.
random
())
.
limit
(
config
.
RANDOM_BOOKS
)
if
page
==
1
:
if
page
==
1
:
...
@@ -281,6 +334,7 @@ def index(page):
...
@@ -281,6 +334,7 @@ def index(page):
@
app
.
route
(
"/hot"
,
defaults
=
{
'page'
:
1
})
@
app
.
route
(
"/hot"
,
defaults
=
{
'page'
:
1
})
@
app
.
route
(
'/hot/page/<int:page>'
)
@
app
.
route
(
'/hot/page/<int:page>'
)
@
login_required_if_no_ano
def
hot_books
(
page
):
def
hot_books
(
page
):
random
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
false
())
random
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
false
())
off
=
int
(
int
(
6
)
*
(
page
-
1
))
off
=
int
(
int
(
6
)
*
(
page
-
1
))
...
@@ -298,12 +352,14 @@ def hot_books(page):
...
@@ -298,12 +352,14 @@ def hot_books(page):
return
render_template
(
'index.html'
,
random
=
random
,
entries
=
entries
,
title
=
"Hot Books (most downloaded)"
)
return
render_template
(
'index.html'
,
random
=
random
,
entries
=
entries
,
title
=
"Hot Books (most downloaded)"
)
@
app
.
route
(
"/stats"
)
@
app
.
route
(
"/stats"
)
@
login_required
def
stats
():
def
stats
():
counter
=
len
(
db
.
session
.
query
(
db
.
Books
)
.
all
())
counter
=
len
(
db
.
session
.
query
(
db
.
Books
)
.
all
())
return
render_template
(
'stats.html'
,
counter
=
counter
,
title
=
"Statistics"
)
return
render_template
(
'stats.html'
,
counter
=
counter
,
title
=
"Statistics"
)
@
app
.
route
(
"/discover"
,
defaults
=
{
'page'
:
1
})
@
app
.
route
(
"/discover"
,
defaults
=
{
'page'
:
1
})
@
app
.
route
(
'/discover/page/<int:page>'
)
@
app
.
route
(
'/discover/page/<int:page>'
)
@
login_required_if_no_ano
def
discover
(
page
):
def
discover
(
page
):
if
page
==
1
:
if
page
==
1
:
entries
=
db
.
session
.
query
(
db
.
Books
)
.
order_by
(
func
.
randomblob
(
2
))
.
limit
(
config
.
NEWEST_BOOKS
)
entries
=
db
.
session
.
query
(
db
.
Books
)
.
order_by
(
func
.
randomblob
(
2
))
.
limit
(
config
.
NEWEST_BOOKS
)
...
@@ -314,6 +370,7 @@ def discover(page):
...
@@ -314,6 +370,7 @@ def discover(page):
return
render_template
(
'discover.html'
,
entries
=
entries
,
pagination
=
pagination
,
title
=
"Random Books"
)
return
render_template
(
'discover.html'
,
entries
=
entries
,
pagination
=
pagination
,
title
=
"Random Books"
)
@
app
.
route
(
"/book/<int:id>"
)
@
app
.
route
(
"/book/<int:id>"
)
@
login_required_if_no_ano
def
show_book
(
id
):
def
show_book
(
id
):
entries
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
id
)
.
first
()
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
()
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):
...
@@ -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
)
return
render_template
(
'detail.html'
,
entry
=
entries
,
cc
=
cc
,
title
=
entries
.
title
,
books_shelfs
=
book_in_shelfs
)
@
app
.
route
(
"/category"
)
@
app
.
route
(
"/category"
)
@
login_required_if_no_ano
def
category_list
():
def
category_list
():
entries
=
db
.
session
.
query
(
db
.
Tags
)
.
order_by
(
db
.
Tags
.
name
)
.
all
()
entries
=
db
.
session
.
query
(
db
.
Tags
)
.
order_by
(
db
.
Tags
.
name
)
.
all
()
return
render_template
(
'categories.html'
,
entries
=
entries
,
title
=
"Category list"
)
return
render_template
(
'categories.html'
,
entries
=
entries
,
title
=
"Category list"
)
@
app
.
route
(
"/category/<name>"
)
@
app
.
route
(
"/category/<name>"
)
@
login_required_if_no_ano
def
category
(
name
):
def
category
(
name
):
random
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
false
())
random
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
false
())
if
name
!=
"all"
:
if
name
!=
"all"
:
...
@@ -338,6 +397,7 @@ def category(name):
...
@@ -338,6 +397,7 @@ def category(name):
return
render_template
(
'index.html'
,
random
=
random
,
entries
=
entries
,
title
=
"Category:
%
s"
%
name
)
return
render_template
(
'index.html'
,
random
=
random
,
entries
=
entries
,
title
=
"Category:
%
s"
%
name
)
@
app
.
route
(
"/series/<name>"
)
@
app
.
route
(
"/series/<name>"
)
@
login_required_if_no_ano
def
series
(
name
):
def
series
(
name
):
random
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
false
())
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
()
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):
...
@@ -345,12 +405,14 @@ def series(name):
@
app
.
route
(
"/admin/"
)
@
app
.
route
(
"/admin/"
)
@
login_required
def
admin
():
def
admin
():
#return "Admin ONLY!"
#return "Admin ONLY!"
abort
(
403
)
abort
(
403
)
@
app
.
route
(
"/search"
,
methods
=
[
"GET"
])
@
app
.
route
(
"/search"
,
methods
=
[
"GET"
])
@
login_required_if_no_ano
def
search
():
def
search
():
term
=
request
.
args
.
get
(
"query"
)
term
=
request
.
args
.
get
(
"query"
)
if
term
:
if
term
:
...
@@ -361,17 +423,20 @@ def search():
...
@@ -361,17 +423,20 @@ def search():
return
render_template
(
'search.html'
,
searchterm
=
""
)
return
render_template
(
'search.html'
,
searchterm
=
""
)
@
app
.
route
(
"/author"
)
@
app
.
route
(
"/author"
)
@
login_required_if_no_ano
def
author_list
():
def
author_list
():
entries
=
db
.
session
.
query
(
db
.
Authors
)
.
order_by
(
db
.
Authors
.
sort
)
.
all
()
entries
=
db
.
session
.
query
(
db
.
Authors
)
.
order_by
(
db
.
Authors
.
sort
)
.
all
()
return
render_template
(
'authors.html'
,
entries
=
entries
,
title
=
"Author list"
)
return
render_template
(
'authors.html'
,
entries
=
entries
,
title
=
"Author list"
)
@
app
.
route
(
"/author/<name>"
)
@
app
.
route
(
"/author/<name>"
)
@
login_required_if_no_ano
def
author
(
name
):
def
author
(
name
):
random
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
false
())
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
()
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
)
return
render_template
(
'index.html'
,
random
=
random
,
entries
=
entries
,
title
=
"Author:
%
s"
%
name
)
@
app
.
route
(
"/cover/<path:cover_path>"
)
@
app
.
route
(
"/cover/<path:cover_path>"
)
@
login_required_if_no_ano
def
get_cover
(
cover_path
):
def
get_cover
(
cover_path
):
return
send_from_directory
(
os
.
path
.
join
(
config
.
DB_ROOT
,
cover_path
),
"cover.jpg"
)
return
send_from_directory
(
os
.
path
.
join
(
config
.
DB_ROOT
,
cover_path
),
"cover.jpg"
)
...
@@ -399,6 +464,7 @@ def read_book(book_id):
...
@@ -399,6 +464,7 @@ def read_book(book_id):
@
app
.
route
(
"/download/<int:book_id>/<format>"
)
@
app
.
route
(
"/download/<int:book_id>/<format>"
)
@
login_required
@
login_required
@
download_required
def
get_download_link
(
book_id
,
format
):
def
get_download_link
(
book_id
,
format
):
format
=
format
.
split
(
"."
)[
0
]
format
=
format
.
split
(
"."
)[
0
]
book
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book_id
)
.
first
()
book
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book_id
)
.
first
()
...
@@ -486,6 +552,7 @@ def logout():
...
@@ -486,6 +552,7 @@ def logout():
@
app
.
route
(
'/send/<int:book_id>'
)
@
app
.
route
(
'/send/<int:book_id>'
)
@
login_required
@
login_required
@
download_required
def
send_to_kindle
(
book_id
):
def
send_to_kindle
(
book_id
):
settings
=
ub
.
get_mail_settings
()
settings
=
ub
.
get_mail_settings
()
if
settings
.
get
(
"mail_server"
,
"mail.example.com"
)
==
"mail.example.com"
:
if
settings
.
get
(
"mail_server"
,
"mail.example.com"
)
==
"mail.example.com"
:
...
@@ -583,6 +650,7 @@ def profile():
...
@@ -583,6 +650,7 @@ def profile():
downloads
.
append
(
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book
.
book_id
)
.
first
())
downloads
.
append
(
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book
.
book_id
)
.
first
())
if
request
.
method
==
"POST"
:
if
request
.
method
==
"POST"
:
to_save
=
request
.
form
.
to_dict
()
to_save
=
request
.
form
.
to_dict
()
if
current_user
.
role_passwd
()
or
current_user
.
role_admin
():
if
to_save
[
"password"
]:
if
to_save
[
"password"
]:
content
.
password
=
generate_password_hash
(
to_save
[
"password"
])
content
.
password
=
generate_password_hash
(
to_save
[
"password"
])
if
to_save
[
"kindle_mail"
]
and
to_save
[
"kindle_mail"
]
!=
content
.
kindle_mail
:
if
to_save
[
"kindle_mail"
]
and
to_save
[
"kindle_mail"
]
!=
content
.
kindle_mail
:
...
@@ -619,10 +687,17 @@ def new_user():
...
@@ -619,10 +687,17 @@ def new_user():
content
.
password
=
generate_password_hash
(
to_save
[
"password"
])
content
.
password
=
generate_password_hash
(
to_save
[
"password"
])
content
.
nickname
=
to_save
[
"nickname"
]
content
.
nickname
=
to_save
[
"nickname"
]
content
.
email
=
to_save
[
"email"
]
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
:
try
:
ub
.
session
.
add
(
content
)
ub
.
session
.
add
(
content
)
ub
.
session
.
commit
()
ub
.
session
.
commit
()
...
@@ -673,10 +748,32 @@ def edit_user(user_id):
...
@@ -673,10 +748,32 @@ def edit_user(user_id):
else
:
else
:
if
to_save
[
"password"
]:
if
to_save
[
"password"
]:
content
.
password
=
generate_password_hash
(
to_save
[
"password"
])
content
.
password
=
generate_password_hash
(
to_save
[
"password"
])
if
"admin_user"
in
to_save
and
content
.
role
!=
1
:
content
.
role
=
1
if
"admin_role"
in
to_save
and
not
content
.
role_admin
():
elif
not
"admin_user"
in
to_save
and
content
.
role
==
1
:
content
.
role
=
content
.
role
+
ub
.
ROLE_ADMIN
content
.
role
=
0
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
:
if
to_save
[
"email"
]
and
to_save
[
"email"
]
!=
content
.
email
:
content
.
email
=
to_save
[
"email"
]
content
.
email
=
to_save
[
"email"
]
if
to_save
[
"kindle_mail"
]
and
to_save
[
"kindle_mail"
]
!=
content
.
kindle_mail
:
if
to_save
[
"kindle_mail"
]
and
to_save
[
"kindle_mail"
]
!=
content
.
kindle_mail
:
...
@@ -691,7 +788,7 @@ def edit_user(user_id):
...
@@ -691,7 +788,7 @@ def edit_user(user_id):
@
app
.
route
(
"/admin/book/<int:book_id>"
,
methods
=
[
'GET'
,
'POST'
])
@
app
.
route
(
"/admin/book/<int:book_id>"
,
methods
=
[
'GET'
,
'POST'
])
@
login_required
@
login_required
@
admin
_required
@
edit
_required
def
edit_book
(
book_id
):
def
edit_book
(
book_id
):
## create the function for sorting...
## create the function for sorting...
db
.
session
.
connection
()
.
connection
.
connection
.
create_function
(
"title_sort"
,
1
,
db
.
title_sort
)
db
.
session
.
connection
()
.
connection
.
connection
.
create_function
(
"title_sort"
,
1
,
db
.
title_sort
)
...
@@ -933,7 +1030,7 @@ def edit_book(book_id):
...
@@ -933,7 +1030,7 @@ def edit_book(book_id):
@
app
.
route
(
"/upload"
,
methods
=
[
"GET"
,
"POST"
])
@
app
.
route
(
"/upload"
,
methods
=
[
"GET"
,
"POST"
])
@
login_required
@
login_required
@
admin
_required
@
upload
_required
def
upload
():
def
upload
():
if
not
config
.
UPLOADING
:
if
not
config
.
UPLOADING
:
abort
(
404
)
abort
(
404
)
...
@@ -996,4 +1093,7 @@ def upload():
...
@@ -996,4 +1093,7 @@ def upload():
for
author
in
db_book
.
authors
:
for
author
in
db_book
.
authors
:
author_names
.
append
(
author
.
name
)
author_names
.
append
(
author
.
name
)
cc
=
db
.
session
.
query
(
db
.
Custom_Columns
)
.
filter
(
db
.
Custom_Columns
.
datatype
.
notin_
(
db
.
cc_exceptions
))
.
all
()
cc
=
db
.
session
.
query
(
db
.
Custom_Columns
)
.
filter
(
db
.
Custom_Columns
.
datatype
.
notin_
(
db
.
cc_exceptions
))
.
all
()
if
current_user
.
role_edit
()
or
current_user
.
role_admin
():
return
render_template
(
'edit_book.html'
,
book
=
db_book
,
authors
=
author_names
,
cc
=
cc
)
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