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
Hide 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):
id
=
Column
(
Integer
,
primary_key
=
True
)
title
=
Column
(
String
)
sort
=
Column
(
String
)
author_sort
=
Column
(
String
)
timestamp
=
Column
(
String
)
pubdate
=
Column
(
String
)
series_index
=
Column
(
String
)
...
...
@@ -170,9 +171,10 @@ class Books(Base):
ratings
=
relationship
(
'Ratings'
,
secondary
=
books_ratings_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
.
sort
=
sort
self
.
author_sort
=
author_sort
self
.
timestamp
=
timestamp
self
.
pubdate
=
pubdate
self
.
series_index
=
series_index
...
...
@@ -181,11 +183,8 @@ class Books(Base):
self
.
has_cover
=
has_cover
self
.
tags
=
tags
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
)
Session
=
sessionmaker
()
...
...
cps/helper.py
View file @
f163ef22
...
...
@@ -8,6 +8,8 @@ import smtplib
import
sys
import
os
import
traceback
import
re
import
unicodedata
from
StringIO
import
StringIO
from
email
import
encoders
from
email.MIMEBase
import
MIMEBase
...
...
@@ -125,3 +127,25 @@ def get_attachment(file_path):
message
=
(
'The requested file could not be read. Maybe wrong '
'permissions?'
)
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" %}
{% block body %}
{% if random.count() > 0 %}
<div
class=
"discover"
>
<h2>
Discover (Random Books)
</h2>
<div
class=
"row"
>
...
...
@@ -34,6 +35,7 @@
{% endfor %}
</div>
</div>
{% endif %}
<div
class=
"discover load-more"
>
<h2>
{{title}}
</h2>
<div
class=
"row"
>
...
...
cps/web.py
View file @
f163ef22
...
...
@@ -7,6 +7,7 @@ from flask import Flask, render_template, session, request, Response, redirect,
from
cps
import
db
,
config
,
ub
,
helper
import
os
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
...
...
@@ -15,6 +16,7 @@ import requests, zipfile
from
werkzeug.security
import
generate_password_hash
,
check_password_hash
from
functools
import
wraps
import
base64
from
sqlalchemy.sql
import
*
app
=
(
Flask
(
__name__
))
...
...
@@ -179,7 +181,7 @@ def feed_discover():
entries
=
db
.
session
.
query
(
db
.
Books
)
.
order_by
(
func
.
random
())
.
limit
(
config
.
NEWEST_BOOKS
)
off
=
0
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"
return
response
...
...
@@ -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
()
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
))
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
.
headers
[
"Content-Disposition"
]
=
"attachment; filename=
%
s.
%
s"
%
(
data
.
name
,
format
)
response
.
headers
[
"Content-Disposition"
]
=
"attachment; filename=
%
s.
%
s"
%
(
file_
name
,
format
)
return
response
@
app
.
route
(
"/"
,
defaults
=
{
'page'
:
1
})
...
...
@@ -223,7 +230,7 @@ def index(page):
@
app
.
route
(
"/hot"
,
defaults
=
{
'page'
:
1
})
@
app
.
route
(
'/hot/page/<int: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:
# 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:
...
...
@@ -236,9 +243,13 @@ def hot_books(page):
entries
=
list
()
for
book
in
hot_books
:
entries
.
append
(
db
.
session
.
query
(
db
.
Books
)
.
filter
(
db
.
Books
.
id
==
book
.
Downloads
.
book_id
)
.
first
())
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)"
)
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
()))
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"
)
def
stats
():
...
...
@@ -272,7 +283,7 @@ def category_list():
@
app
.
route
(
"/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"
:
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
:
...
...
@@ -281,7 +292,7 @@ def category(name):
@
app
.
route
(
"/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
()
return
render_template
(
'index.html'
,
random
=
random
,
entries
=
entries
,
title
=
"Series:
%
s"
%
name
)
...
...
@@ -309,7 +320,7 @@ def author_list():
@
app
.
route
(
"/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
()
return
render_template
(
'index.html'
,
random
=
random
,
entries
=
entries
,
title
=
"Author:
%
s"
%
name
)
...
...
@@ -346,8 +357,13 @@ def get_download_link(book_id, format):
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
()
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
.
headers
[
"Content-Disposition"
]
=
"attachment; filename=
%
s.
%
s"
%
(
data
.
name
,
format
)
response
.
headers
[
"Content-Disposition"
]
=
"attachment; filename=
%
s.
%
s"
%
(
file_
name
,
format
)
return
response
@
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