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