]> git.gir.st - subscriptionfeed.git/blob - app/reddit/__init__.py
avoid int(request.args.get('page'))
[subscriptionfeed.git] / app / reddit / __init__.py
1 import re
2 import sqlite3
3 from flask_login import current_user, login_required
4 from flask import Blueprint, render_template, request, redirect, flash, url_for
5
6 from ..common.common import *
7 from .lib import *
8
9 frontend = Blueprint('reddit', __name__,
10 template_folder='templates',
11 static_folder='static',
12 static_url_path='/static/rd')
13
14 @frontend.route('/feed/subreddits')
15 @frontend.route('/r/<subreddit>/')
16 def reddit(subreddit=None):
17 token = getattr(current_user, 'token', 'guest')
18 count = request.args.get('count', 0, type=int)
19 before = request.args.get('before')
20 after = request.args.get('after')
21
22 sortorder = request.args.get('s', "hot") # TODO: verify!
23 timerange = request.args.get('t', None) # TODO: verify!
24
25 all_subreddits = get_subreddits(token)
26 subreddits = [subreddit] if subreddit else all_subreddits
27
28 if subreddits:
29 try:
30 data = fetch_reddit(subreddits,
31 sorted_by=sortorder, time=timerange, limit=36,
32 count=count, before=before, after=after)
33 videos = parse_reddit_videos(data)
34 before = data['data']['before']
35 after = data['data']['after']
36 except RedditException as e:
37 return f"error retrieving reddit data: <xmp>{e}</xmp>", 502 # TODO: better
38
39 # set pin/hide stati of retrieved videos
40 video_ids = [v['video_id'] for v in videos]
41 pinned, hidden = fetch_video_flags(token, video_ids)
42 videos = sorted([
43 {**v, 'pinned': v['video_id'] in pinned}
44 for v in videos
45 if v['video_id'] not in hidden
46 ], key=lambda v:v['pinned'], reverse=True)
47 else: # not subscribed to anything
48 videos = []
49
50 title = f"/r/{subreddit}" if subreddit else "my subreddits"
51 return render_template('reddit.html.j2', title=title, rows=videos,
52 subreddits=all_subreddits, before=before, after=after, count=count)
53
54 @frontend.route('/manage/subreddits')
55 # disabled for guest user: @login_required
56 def subscription_manager():
57 token = getattr(current_user, 'token', 'guest')
58 subreddits = get_subreddits(token)
59 return render_template('subreddit_manager.html.j2', subreddits=subreddits)
60
61 @frontend.route('/manage/subreddits', methods=['POST'])
62 @login_required
63 def manage_subscriptions():
64 token = current_user.token
65 if 'subscribe' in request.form:
66 subreddit = request.form.get("subscribe")
67 match = re.search(r"(?:(?:https?://)?(?:old.|www.|\w\w.)?reddit.com)?(?:/?r/)?([-+_0-9A-Za-z]{2,21})", subreddit)
68 if match:
69 subreddit = match.group(1)
70 else:
71 flash("invalid subreddit", "error")
72 return redirect(request.url, code=303)
73 with sqlite3.connect(cf['global']['database']) as conn:
74 c = conn.cursor()
75 c.execute("""
76 INSERT OR IGNORE INTO subreddits (user, subreddit)
77 VALUES (?, ?)
78 """, (token, subreddit))
79
80 elif 'unsubscribe' in request.form:
81 subreddit = request.form.get("unsubscribe")
82 with sqlite3.connect(cf['global']['database']) as conn:
83 c = conn.cursor()
84 c.execute("""
85 DELETE FROM subreddits
86 WHERE user = ? AND subreddit = ?
87 """, (token, subreddit))
88 # TODO: sql-error-handling, report success
89
90 else:
91 flash("unsupported action", "error")
92
93 return redirect(request.url, code=303)
94
95 def get_subreddits(token):
96 with sqlite3.connect(cf['global']['database']) as conn:
97 c = conn.cursor()
98 c.execute("""
99 SELECT subreddit
100 FROM subreddits
101 WHERE user = ?
102 ORDER BY subreddit COLLATE NOCASE ASC
103 """, (token,))
104 subreddits = [sr for (sr,) in c.fetchall()]
105 return subreddits
106
107 @frontend.app_template_filter('trim3')
108 def trim3(n):
109 if type(n) != int:
110 return n # not a number
111 elif round(n, 1) >= 10_000:
112 return "%.0fk" % (n/1000)
113 elif n >= 1_000:
114 return "%.1fk" % (n/1000)
115 else:
116 return "%d" % n
117
118 @frontend.before_app_request
119 def inject_reddit_button():
120 if not 'header_items' in g:
121 g.header_items = []
122 g.header_items.append({
123 'name': 'reddit',
124 'url': url_for('reddit.reddit'),
125 'parent': frontend.name,
126 'priority': 5
127 })
Imprint / Impressum