import re import sqlite3 from flask_login import current_user, login_required from flask import Blueprint, render_template, request, redirect, flash, url_for from ..common.common import * from .lib import * frontend = Blueprint('reddit', __name__, template_folder='templates', static_folder='static', static_url_path='/static/rd') @frontend.route('/feed/subreddits') @frontend.route('/r/') def reddit(subreddit=None): token = getattr(current_user, 'token', 'guest') count = int(request.args.get('count', 0)) before = request.args.get('before') after = request.args.get('after') sortorder = request.args.get('s', "hot") # TODO: verify! timerange = request.args.get('t', None) # TODO: verify! all_subreddits = get_subreddits(token) subreddits = [subreddit] if subreddit else all_subreddits try: data = fetch_reddit(subreddits, sorted_by=sortorder, time=timerange, limit=36, count=count, before=before, after=after) videos = parse_reddit_videos(data) before = data['data']['before'] after = data['data']['after'] except RedditException as e: return f"error retrieving reddit data: {e}", 502 # TODO: better # set pin/hide stati of retrieved videos video_ids = [v['video_id'] for v in videos] pinned, hidden = fetch_video_flags(token, video_ids) videos = sorted([ {**v, 'pinned': v['video_id'] in pinned} for v in videos if v['video_id'] not in hidden ], key=lambda v:v['pinned'], reverse=True) title = f"/r/{subreddit}" if subreddit else "my subreddits" return render_template('reddit.html.j2', title=title, rows=videos, subreddits=all_subreddits, before=before, after=after, count=count) @frontend.route('/manage/subreddits') # disabled for guest user: @login_required def subscription_manager(): token = getattr(current_user, 'token', 'guest') subreddits = get_subreddits(token) return render_template('subreddit_manager.html.j2', subreddits=subreddits) @frontend.route('/manage/subreddits', methods=['POST']) @login_required def manage_subscriptions(): token = current_user.token if 'subscribe' in request.form: subreddit = request.form.get("subscribe") match = re.search(r"(?:(?:https?://)?(?:old.|www.|\w\w.)?reddit.com)?(?:/?r/)?([-+_0-9A-Za-z]{2,21})", subreddit) if match: subreddit = match.group(1) else: flash("invalid subreddit", "error") return redirect(request.url, code=303) with sqlite3.connect(cf['global']['database']) as conn: c = conn.cursor() c.execute(""" INSERT OR IGNORE INTO subreddits (user, subreddit) VALUES (?, ?) """, (token, subreddit)) elif 'unsubscribe' in request.form: subreddit = request.form.get("unsubscribe") with sqlite3.connect(cf['global']['database']) as conn: c = conn.cursor() c.execute(""" DELETE FROM subreddits WHERE user = ? AND subreddit = ? """, (token, subreddit)) # TODO: sql-error-handling, report success else: flash("unsupported action", "error") return redirect(request.url, code=303) def get_subreddits(token): with sqlite3.connect(cf['global']['database']) as conn: c = conn.cursor() c.execute(""" SELECT subreddit FROM subreddits WHERE user = ? ORDER BY subreddit COLLATE NOCASE ASC """, (token,)) subreddits = [sr for (sr,) in c.fetchall()] return subreddits @frontend.app_template_filter('trim3') def trim3(n): if type(n) != int: return n # not a number elif round(n, 1) >= 10_000: return "%.0fk" % (n/1000) elif n >= 1_000: return "%.1fk" % (n/1000) else: return "%d" % n @frontend.before_app_request def inject_reddit_button(): if not 'header_items' in g: g.header_items = [] g.header_items.append({ 'name': 'reddit', 'url': url_for('reddit.reddit'), 'parent': frontend.name, 'priority': 5 })