]>
git.gir.st - subscriptionfeed.git/blob - app/reddit/__init__.py
3 from flask_login
import current_user
, login_required
4 from flask
import Blueprint
, render_template
, request
, redirect
, flash
, url_for
5 from werkzeug
.exceptions
import BadRequest
, BadGateway
7 from ..common
.common
import *
10 frontend
= Blueprint('reddit', __name__
,
11 template_folder
='templates',
12 static_folder
='static',
13 static_url_path
='/static/rd')
15 @frontend.route('/feed/subreddits')
16 @frontend.route('/r/<subreddit>/')
17 def reddit(subreddit
=None):
18 token
= getattr(current_user
, 'token', 'guest')
19 after
= request
.args
.get('after')
20 use_client_side_client
= cf
.getboolean('reddit', 'use_client_side_client', fallback
=False)
22 sortorder
= request
.args
.get('s', "hot")
23 timerange
= request
.args
.get('t', None)
25 if subreddit
and not re
.fullmatch(r
"[-+_0-9A-Za-z]{2,21}", subreddit
):
26 raise BadRequest("invalid subreddit")
27 if sortorder
not in ("hot", "new", "rising", "controversial", "top"):
28 raise BadRequest("invalid sort order")
29 if timerange
not in (None, "hour", "day", "week", "month", "year", "all"):
30 raise BadRequest("invalid top time range")
32 all_subreddits
= get_subreddits(token
)
33 subreddits
= subreddit
.split("+") if subreddit
else all_subreddits
34 title
= f
"/r/{subreddit}" if subreddit
else "my subreddits"
36 if not use_client_side_client
and subreddits
:
38 data
= fetch_reddit(subreddits
,
39 sorted_by
=sortorder
, time
=timerange
, limit
=36, after
=after
)
40 videos
= parse_reddit_videos(data
)
41 next_page
= data
['data']['after']
42 except RedditException
as e
:
43 raise BadGateway(f
"error retrieving reddit data: {e}")
45 # set pin/hide stati of retrieved videos
46 video_ids
= [v
['video_id'] for v
in videos
]
47 pinned
, hidden
= fetch_video_flags(token
, video_ids
)
49 {**v
, 'pinned': v
['video_id'] in pinned
}
51 if v
['video_id'] not in hidden
and v
['n_karma']>0
52 ], key
=lambda v
:v
['pinned'], reverse
=True)
53 else: # not subscribed to anything (or client side client)
57 return render_template('reddit.html.j2', title
=title
, rows
=videos
,
58 client_side_client
=use_client_side_client
, subreddit
=subreddits
,
59 subreddits
=all_subreddits
, next_page
=next_page
)
61 @frontend.route('/manage/subreddits')
62 # disabled for guest user: @login_required
63 def subscription_manager():
64 token
= getattr(current_user
, 'token', 'guest')
65 subreddits
= get_subreddits(token
)
66 return render_template('subreddit_manager.html.j2', subreddits
=subreddits
)
68 @frontend.route('/manage/subreddits', methods
=['POST'])
70 def manage_subscriptions():
71 token
= current_user
.token
72 if 'subscribe' in request
.form
:
73 subreddit
= request
.form
.get("subscribe")
74 match
= re
.search(r
"(?:(?:https?://)?(?:old.|www.|\w\w.)?reddit.com)?(?:/?r/)?([-+_0-9A-Za-z]{2,21})", subreddit
)
76 subreddit
= match
.group(1)
78 flash("invalid subreddit", "error")
79 return redirect(request
.url
, code
=303)
80 with sqlite3
.connect(cf
['global']['database']) as conn
:
83 INSERT OR IGNORE INTO subreddits (user, subreddit)
85 """, (token
, subreddit
))
87 elif 'unsubscribe' in request
.form
:
88 subreddit
= request
.form
.get("unsubscribe")
89 with sqlite3
.connect(cf
['global']['database']) as conn
:
92 DELETE FROM subreddits
93 WHERE user = ? AND subreddit = ?
94 """, (token
, subreddit
))
95 # TODO: sql-error-handling, report success
98 flash("unsupported action", "error")
100 return redirect(request
.url
, code
=303)
102 def get_subreddits(token
):
103 with sqlite3
.connect(cf
['global']['database']) as conn
:
109 ORDER BY subreddit COLLATE NOCASE ASC
111 subreddits
= [sr
for (sr
,) in c
.fetchall()]
114 @frontend.app_template_filter('trim3')
117 return n
# not a number
118 elif round(n
, 1) >= 10_000:
119 return "%.0fk" % (n
/1000)
121 return "%.1fk" % (n
/1000)
125 @frontend.before_app_request
126 def inject_reddit_button():
127 if not 'header_items' in g
:
129 g
.header_items
.append({
131 'url': url_for('reddit.reddit'),
132 'parent': frontend
.name
,