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
f163ef22
Commit
f163ef22
authored
Mar 26, 2016
by
Jan Broer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
make pretty filenames for downloads; remove random books section on most pages
parent
2b846b1e
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
56 additions
and
15 deletions
+56
-15
db.py
cps/db.py
+4
-5
helper.py
cps/helper.py
+24
-0
index.html
cps/templates/index.html
+2
-0
web.py
cps/web.py
+26
-10
No files found.
cps/db.py
View file @
f163ef22
...
@@ -155,6 +155,7 @@ class Books(Base):
...
@@ -155,6 +155,7 @@ class Books(Base):
id
=
Column
(
Integer
,
primary_key
=
True
)
id
=
Column
(
Integer
,
primary_key
=
True
)
title
=
Column
(
String
)
title
=
Column
(
String
)
sort
=
Column
(
String
)
sort
=
Column
(
String
)
author_sort
=
Column
(
String
)
timestamp
=
Column
(
String
)
timestamp
=
Column
(
String
)
pubdate
=
Column
(
String
)
pubdate
=
Column
(
String
)
series_index
=
Column
(
String
)
series_index
=
Column
(
String
)
...
@@ -170,9 +171,10 @@ class Books(Base):
...
@@ -170,9 +171,10 @@ class Books(Base):
ratings
=
relationship
(
'Ratings'
,
secondary
=
books_ratings_link
,
backref
=
'books'
)
ratings
=
relationship
(
'Ratings'
,
secondary
=
books_ratings_link
,
backref
=
'books'
)
languages
=
relationship
(
'Languages'
,
secondary
=
books_languages_link
,
backref
=
'books'
)
languages
=
relationship
(
'Languages'
,
secondary
=
books_languages_link
,
backref
=
'books'
)
def
__init__
(
self
,
title
,
sort
,
timestamp
,
pubdate
,
series_index
,
last_modified
,
path
,
has_cover
,
authors
,
tags
):
def
__init__
(
self
,
title
,
sort
,
author_sort
,
timestamp
,
pubdate
,
series_index
,
last_modified
,
path
,
has_cover
,
authors
,
tags
):
self
.
title
=
title
self
.
title
=
title
self
.
sort
=
sort
self
.
sort
=
sort
self
.
author_sort
=
author_sort
self
.
timestamp
=
timestamp
self
.
timestamp
=
timestamp
self
.
pubdate
=
pubdate
self
.
pubdate
=
pubdate
self
.
series_index
=
series_index
self
.
series_index
=
series_index
...
@@ -181,11 +183,8 @@ class Books(Base):
...
@@ -181,11 +183,8 @@ class Books(Base):
self
.
has_cover
=
has_cover
self
.
has_cover
=
has_cover
self
.
tags
=
tags
self
.
tags
=
tags
def
__repr__
(
self
):
def
__repr__
(
self
):
return
u"<Books('{0},{1}{2}{3}{4}{5}{6}{7}')>"
.
format
(
self
.
title
,
self
.
sort
,
self
.
timestamp
,
self
.
pubdate
,
self
.
series_index
,
self
.
last_modified
,
self
.
path
,
self
.
has_cover
)
return
u"<Books('{0},{1}{2}{3}{4}{5}{6}{7}{8}')>"
.
format
(
self
.
title
,
self
.
sort
,
self
.
author_sort
,
self
.
timestamp
,
self
.
pubdate
,
self
.
series_index
,
self
.
last_modified
,
self
.
path
,
self
.
has_cover
)
Base
.
metadata
.
create_all
(
engine
)
Base
.
metadata
.
create_all
(
engine
)
Session
=
sessionmaker
()
Session
=
sessionmaker
()
...
...
cps/helper.py
View file @
f163ef22
...
@@ -8,6 +8,8 @@ import smtplib
...
@@ -8,6 +8,8 @@ import smtplib
import
sys
import
sys
import
os
import
os
import
traceback
import
traceback
import
re
import
unicodedata
from
StringIO
import
StringIO
from
StringIO
import
StringIO
from
email
import
encoders
from
email
import
encoders
from
email.MIMEBase
import
MIMEBase
from
email.MIMEBase
import
MIMEBase
...
@@ -125,3 +127,25 @@ def get_attachment(file_path):
...
@@ -125,3 +127,25 @@ def get_attachment(file_path):
message
=
(
'The requested file could not be read. Maybe wrong '
message
=
(
'The requested file could not be read. Maybe wrong '
'permissions?'
)
'permissions?'
)
return
None
return
None
def
get_valid_filename
(
value
):
"""
Returns the given string converted to a string that can be used for a clean
filename. Limits num characters to 128 max.
"""
value
=
value
[:
128
]
re_slugify
=
re
.
compile
(
'[^
\
w
\
s-]'
,
re
.
UNICODE
)
value
=
unicodedata
.
normalize
(
'NFKD'
,
value
)
re_slugify
=
re
.
compile
(
'[^
\
w
\
s-]'
,
re
.
UNICODE
)
value
=
unicode
(
re_slugify
.
sub
(
''
,
value
)
.
strip
())
value
=
re
.
sub
(
'[
\
s]+'
,
'_'
,
value
,
flags
=
re
.
U
)
return
value
def
get_normalized_author
(
value
):
"""
Normalizes sorted author name
"""
value
=
unicodedata
.
normalize
(
'NFKD'
,
value
)
value
=
re
.
sub
(
'[^
\
w,
\
s]'
,
''
,
value
,
flags
=
re
.
U
)
value
=
" "
.
join
(
value
.
split
(
", "
)[::
-
1
])
return
value
cps/templates/index.html
View file @
f163ef22
{% extends "layout.html" %}
{% extends "layout.html" %}
{% block body %}
{% block body %}
{% if random.count() > 0 %}
<div
class=
"discover"
>
<div
class=
"discover"
>
<h2>
Discover (Random Books)
</h2>
<h2>
Discover (Random Books)
</h2>
<div
class=
"row"
>
<div
class=
"row"
>
...
@@ -34,6 +35,7 @@
...
@@ -34,6 +35,7 @@
{% endfor %}
{% endfor %}
</div>
</div>
</div>
</div>
{% endif %}
<div
class=
"discover load-more"
>
<div
class=
"discover load-more"
>
<h2>
{{title}}
</h2>
<h2>
{{title}}
</h2>
<div
class=
"row"
>
<div
class=
"row"
>
...
...
cps/web.py
View file @
f163ef22
...
@@ -7,6 +7,7 @@ from flask import Flask, render_template, session, request, Response, redirect,
...
@@ -7,6 +7,7 @@ from flask import Flask, render_template, session, request, Response, redirect,
from
cps
import
db
,
config
,
ub
,
helper
from
cps
import
db
,
config
,
ub
,
helper
import
os
import
os
from
sqlalchemy.sql.expression
import
func
from
sqlalchemy.sql.expression
import
func
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
...
@@ -15,6 +16,7 @@ import requests, zipfile
...
@@ -15,6 +16,7 @@ import requests, zipfile
from
werkzeug.security
import
generate_password_hash
,
check_password_hash
from
werkzeug.security
import
generate_password_hash
,
check_password_hash
from
functools
import
wraps
from
functools
import
wraps
import
base64
import
base64
from
sqlalchemy.sql
import
*
app
=
(
Flask
(
__name__
))
app
=
(
Flask
(
__name__
))
...
@@ -179,7 +181,7 @@ def feed_discover():
...
@@ -179,7 +181,7 @@ def feed_discover():
entries
=
db
.
session
.
query
(
db
.
Books
)
.
order_by
(
func
.
random
())
.
limit
(
config
.
NEWEST_BOOKS
)
entries
=
db
.
session
.
query
(
db
.
Books
)
.
order_by
(
func
.
random
())
.
limit
(
config
.
NEWEST_BOOKS
)
off
=
0
off
=
0
xml
=
render_template
(
'feed.xml'
,
entries
=
entries
,
next_url
=
"/feed/discover?start_index=
%
d"
%
(
int
(
config
.
NEWEST_BOOKS
)
+
int
(
off
)))
xml
=
render_template
(
'feed.xml'
,
entries
=
entries
,
next_url
=
"/feed/discover?start_index=
%
d"
%
(
int
(
config
.
NEWEST_BOOKS
)
+
int
(
off
)))
response
=
make_response
(
xml
)
response
=
make_response
(
xml
)
response
.
headers
[
"Content-Type"
]
=
"application/xml"
response
.
headers
[
"Content-Type"
]
=
"application/xml"
return
response
return
response
...
@@ -204,8 +206,13 @@ def get_opds_download_link(book_id, format):
...
@@ -204,8 +206,13 @@ def get_opds_download_link(book_id, format):
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
()
data
=
db
.
session
.
query
(
db
.
Data
)
.
filter
(
db
.
Data
.
book
==
book
.
id
)
.
filter
(
db
.
Data
.
format
==
format
.
upper
())
.
first
()
data
=
db
.
session
.
query
(
db
.
Data
)
.
filter
(
db
.
Data
.
book
==
book
.
id
)
.
filter
(
db
.
Data
.
format
==
format
.
upper
())
.
first
()
helper
.
update_download
(
book_id
,
int
(
current_user
.
id
))
helper
.
update_download
(
book_id
,
int
(
current_user
.
id
))
author
=
helper
.
get_normalized_author
(
book
.
author_sort
)
file_name
=
book
.
title
if
len
(
author
)
>
0
:
file_name
=
author
+
'-'
+
file_name
file_name
=
helper
.
get_valid_filename
(
file_name
)
response
=
make_response
(
send_from_directory
(
os
.
path
.
join
(
config
.
DB_ROOT
,
book
.
path
),
data
.
name
+
"."
+
format
))
response
=
make_response
(
send_from_directory
(
os
.
path
.
join
(
config
.
DB_ROOT
,
book
.
path
),
data
.
name
+
"."
+
format
))
response
.
headers
[
"Content-Disposition"
]
=
"attachment; filename=
%
s.
%
s"
%
(
data
.
name
,
format
)
response
.
headers
[
"Content-Disposition"
]
=
"attachment; filename=
%
s.
%
s"
%
(
file_
name
,
format
)
return
response
return
response
@
app
.
route
(
"/"
,
defaults
=
{
'page'
:
1
})
@
app
.
route
(
"/"
,
defaults
=
{
'page'
:
1
})
...
@@ -223,7 +230,7 @@ def index(page):
...
@@ -223,7 +230,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>'
)
def
hot_books
(
page
):
def
hot_books
(
page
):
random
=
db
.
session
.
query
(
db
.
Books
)
.
order_by
(
func
.
random
())
.
limit
(
config
.
RANDOM_BOOKS
)
random
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
false
()
)
# if page == 1:
# if page == 1:
# entries = db.session.query(db.Books).filter(db.Books.ratings.any(db.Ratings.rating > 9)).order_by(db.Books.last_modified.desc()).limit(config.NEWEST_BOOKS)
# entries = db.session.query(db.Books).filter(db.Books.ratings.any(db.Ratings.rating > 9)).order_by(db.Books.last_modified.desc()).limit(config.NEWEST_BOOKS)
# else:
# else:
...
@@ -236,9 +243,13 @@ def hot_books(page):
...
@@ -236,9 +243,13 @@ def hot_books(page):
entries
=
list
()
entries
=
list
()
for
book
in
hot_books
:
for
book
in
hot_books
:
entries
.
append
(
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book
.
Downloads
.
book_id
)
.
first
())
entries
.
append
(
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book
.
Downloads
.
book_id
)
.
first
())
numBooks
=
len
(
all_books
.
all
())
pages
=
int
(
ceil
(
numBooks
/
float
(
config
.
NEWEST_BOOKS
)))
if
pages
>
1
:
pagination
=
Pagination
(
page
,
config
.
NEWEST_BOOKS
,
len
(
all_books
.
all
()))
pagination
=
Pagination
(
page
,
config
.
NEWEST_BOOKS
,
len
(
all_books
.
all
()))
return
render_template
(
'index.html'
,
random
=
random
,
entries
=
entries
,
pagination
=
pagination
,
title
=
"Hot Books (most downloaded)"
)
return
render_template
(
'index.html'
,
random
=
random
,
entries
=
entries
,
pagination
=
pagination
,
title
=
"Hot Books (most downloaded)"
)
else
:
return
render_template
(
'index.html'
,
random
=
random
,
entries
=
entries
,
title
=
"Hot Books (most downloaded)"
)
@
app
.
route
(
"/stats"
)
@
app
.
route
(
"/stats"
)
def
stats
():
def
stats
():
...
@@ -272,7 +283,7 @@ def category_list():
...
@@ -272,7 +283,7 @@ def category_list():
@
app
.
route
(
"/category/<name>"
)
@
app
.
route
(
"/category/<name>"
)
def
category
(
name
):
def
category
(
name
):
random
=
db
.
session
.
query
(
db
.
Books
)
.
order_by
(
func
.
random
())
.
limit
(
config
.
RANDOM_BOOKS
)
random
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
false
()
)
if
name
!=
"all"
:
if
name
!=
"all"
:
entries
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
tags
.
any
(
db
.
Tags
.
name
.
like
(
"
%
"
+
name
+
"
%
"
)))
.
order_by
(
db
.
Books
.
last_modified
.
desc
())
.
all
()
entries
=
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
tags
.
any
(
db
.
Tags
.
name
.
like
(
"
%
"
+
name
+
"
%
"
)))
.
order_by
(
db
.
Books
.
last_modified
.
desc
())
.
all
()
else
:
else
:
...
@@ -281,7 +292,7 @@ def category(name):
...
@@ -281,7 +292,7 @@ def category(name):
@
app
.
route
(
"/series/<name>"
)
@
app
.
route
(
"/series/<name>"
)
def
series
(
name
):
def
series
(
name
):
random
=
db
.
session
.
query
(
db
.
Books
)
.
order_by
(
func
.
random
())
.
limit
(
config
.
RANDOM_BOOKS
)
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
()
return
render_template
(
'index.html'
,
random
=
random
,
entries
=
entries
,
title
=
"Series:
%
s"
%
name
)
return
render_template
(
'index.html'
,
random
=
random
,
entries
=
entries
,
title
=
"Series:
%
s"
%
name
)
...
@@ -309,7 +320,7 @@ def author_list():
...
@@ -309,7 +320,7 @@ def author_list():
@
app
.
route
(
"/author/<name>"
)
@
app
.
route
(
"/author/<name>"
)
def
author
(
name
):
def
author
(
name
):
random
=
db
.
session
.
query
(
db
.
Books
)
.
order_by
(
func
.
random
())
.
limit
(
config
.
RANDOM_BOOKS
)
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
)
...
@@ -346,8 +357,13 @@ def get_download_link(book_id, format):
...
@@ -346,8 +357,13 @@ def get_download_link(book_id, format):
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
()
data
=
db
.
session
.
query
(
db
.
Data
)
.
filter
(
db
.
Data
.
book
==
book
.
id
)
.
filter
(
db
.
Data
.
format
==
format
.
upper
())
.
first
()
data
=
db
.
session
.
query
(
db
.
Data
)
.
filter
(
db
.
Data
.
book
==
book
.
id
)
.
filter
(
db
.
Data
.
format
==
format
.
upper
())
.
first
()
helper
.
update_download
(
book_id
,
int
(
current_user
.
id
))
helper
.
update_download
(
book_id
,
int
(
current_user
.
id
))
author
=
helper
.
get_normalized_author
(
book
.
author_sort
)
file_name
=
book
.
title
if
len
(
author
)
>
0
:
file_name
=
author
+
'-'
+
file_name
file_name
=
helper
.
get_valid_filename
(
file_name
)
response
=
make_response
(
send_from_directory
(
os
.
path
.
join
(
config
.
DB_ROOT
,
book
.
path
),
data
.
name
+
"."
+
format
))
response
=
make_response
(
send_from_directory
(
os
.
path
.
join
(
config
.
DB_ROOT
,
book
.
path
),
data
.
name
+
"."
+
format
))
response
.
headers
[
"Content-Disposition"
]
=
"attachment; filename=
%
s.
%
s"
%
(
data
.
name
,
format
)
response
.
headers
[
"Content-Disposition"
]
=
"attachment; filename=
%
s.
%
s"
%
(
file_
name
,
format
)
return
response
return
response
@
app
.
route
(
'/register'
,
methods
=
[
'GET'
,
'POST'
])
@
app
.
route
(
'/register'
,
methods
=
[
'GET'
,
'POST'
])
...
...
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