]>
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
6 from ..common
.common
import *
8 frontend
= Blueprint('reddit', __name__
,
9 template_folder
='templates',
10 static_folder
='static',
11 static_url_path
='/static/rd')
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')
21 sortorder
= request
.args
.get('s', "hot") # TODO: verify!
22 timerange
= request
.args
.get('t', None) # TODO: verify!
24 all_subreddits
= get_subreddits(token
)
25 subreddits
= [subreddit
] if subreddit
else all_subreddits
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
37 # set pin/hide stati of retrieved videos
38 with sqlite3
.connect(cf
['global']['database']) as conn
:
41 SELECT post_id,display,video_id,title,subreddit
43 LEFT JOIN reddit_posts ON reddit_posts.id = reddit_flags.post_id
45 AND display IS NOT NULL
49 # on user's feed: show all pinned videos
50 # on /r/...: only show pinned videos that are on the page anyways
51 if not subreddit
: # only on /feed/reddit
52 videos
= [ # prepend pinned posts
56 'url': f
"https://old.reddit.com/r/{sr}/comments/{post_id}/",
63 for post_id
,display
,video_id
,title
,sr
in flags
64 if display
== 'pinned'
65 ] + [ # followed by non-pinned, non-hidden videos
67 if v
['post_id'] not in [post
for post
,_
,_
,_
,_
in flags
]
70 pinned
= [post
for post
,disp
,_
,_
,_
in flags
if disp
== 'pinned']
71 hidden
= [post
for post
,disp
,_
,_
,_
in flags
if disp
== 'hidden']
73 {**v
, 'pinned': v
['post_id'] in pinned
}
75 if v
['post_id'] not in hidden
78 title
= f
"/r/{subreddit}" if subreddit
else "my subreddits"
79 return render_template('reddit.html.j2', title
=title
, rows
=videos
,
80 subreddits
=all_subreddits
, before
=before
, after
=after
, count
=count
)
82 @frontend.route('/manage/subreddits')
83 # disabled for guest user: @login_required
84 def subscription_manager():
85 token
= getattr(current_user
, 'token', 'guest')
86 subreddits
= get_subreddits(token
)
87 return render_template('subreddit_manager.html.j2', subreddits
=subreddits
)
89 @frontend.route('/feed/subreddits', methods
=['POST'])
90 @frontend.route('/r/<subreddit>', methods
=['POST'])
92 def feed_post(subreddit
=None):
93 token
= current_user
.token
95 action
= next(request
.form
.keys(), None)
96 if action
in ['pin', 'unpin', 'hide']:
97 post_id
= request
.form
.get(action
)
98 if not re
.match(r
"^[a-z0-9]+$", post_id
):
99 return "invalid post id", 400
106 with sqlite3
.connect(cf
['global']['database']) as conn
:
108 # if the post was pinned, we need to be able to retrieve it
109 # independently from if it is shown in the feed. so we check if we
110 # know about it, or download and store it.
113 SELECT count(*) FROM reddit_posts WHERE id = ?
115 if c
.fetchone()[0] < 1:
116 post
= parse_reddit_videos(fetch_reddit_post(post_id
))[0] # TODO: if exception, abort pinning
118 INSERT INTO reddit_posts (id,subreddit,title,video_id)
123 html
.unescape(post
['title']),
128 INSERT OR REPLACE INTO reddit_flags (user, post_id, display)
130 """, (token
, post_id
, display
))
132 flash("unsupported action", "error")
133 return redirect(request
.url
, code
=303)
135 @frontend.route('/manage/subreddits', methods
=['POST'])
137 def manage_subscriptions():
138 token
= current_user
.token
139 if 'subscribe' in request
.form
:
140 subreddit
= request
.form
.get("subscribe")
141 match
= re
.search(r
"(?:(?:https?://)?(?:old.|www.|\w\w.)?reddit.com)?(?:/?r/)?([-+_0-9A-Za-z]{2,21})", subreddit
)
143 subreddit
= match
.group(1)
145 flash("invalid subreddit", "error")
146 return redirect(request
.url
, code
=303)
147 with sqlite3
.connect(cf
['global']['database']) as conn
:
150 INSERT OR IGNORE INTO subreddits (user, subreddit)
152 """, (token
, subreddit
))
154 elif 'unsubscribe' in request
.form
:
155 subreddit
= request
.form
.get("unsubscribe")
156 with sqlite3
.connect(cf
['global']['database']) as conn
:
159 DELETE FROM subreddits
160 WHERE user = ? AND subreddit = ?
161 """, (token
, subreddit
))
162 # TODO: sql-error-handling, report success
165 flash("unsupported action", "error")
167 return redirect(request
.url
, code
=303)
169 def get_subreddits(token
):
170 with sqlite3
.connect(cf
['global']['database']) as conn
:
176 ORDER BY subreddit COLLATE NOCASE ASC
178 subreddits
= [sr
for (sr
,) in c
.fetchall()]
181 @frontend.app_template_filter('trim3')
184 return n
# not a number
185 elif round(n
, 1) >= 10_000:
186 return "%.0fk" % (n
/1000)
188 return "%.1fk" % (n
/1000)