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