]>
git.gir.st - subscriptionfeed.git/blob - app/reddit/__init__.py
5 #from flask_login import current_user, login_required
6 from flask_login
import LoginManager
, UserMixin
, current_user
, login_user
, logout_user
, login_required
7 from flask
import Blueprint
, render_template
, request
, redirect
, flash
, url_for
, jsonify
, g
9 from ..common
.common
import *
11 frontend
= Blueprint('reddit', __name__
,
12 template_folder
='templates',
13 static_folder
='static',
14 static_url_path
='/static/rd')
16 @frontend.route('/feed/subreddits')
17 # disabled for guest user: @login_required
19 return "reddit feed: TODO"
20 if current_user
.is_anonymous
:
23 token
= current_user
.token
24 page
= int(request
.args
.get('page', 0))
25 with sqlite3
.connect(cf
['global']['database']) as conn
:
28 SELECT videos.id, channel_id, name, title, published, flags.display
30 JOIN channels ON videos.channel_id = channels.id
31 LEFT JOIN flags ON (videos.id = flags.video_id) AND (flags.user = ?)
33 (SELECT channel_id FROM subscriptions WHERE user = ?)
34 AND flags.display IS NOT 'hidden'
35 ORDER BY (display = 'pinned') DESC, crawled DESC
37 OFFSET 36*?""", (token
, token
, page
))
40 'channel_id': channel_id
,
43 'published': published
,
44 'pinned': display
== 'pinned',
45 } for (video_id
, channel_id
, author
, title
, published
, display
) in c
.fetchall()]
46 return render_template('index.html.j2', rows
=rows
, page
=page
)
48 @frontend.route('/manage/subreddits')
49 # disabled for guest user: @login_required
50 def subscription_manager():
51 return "reddit feed: TODO"
52 if current_user
.is_anonymous
:
55 token
= current_user
.token
56 with sqlite3
.connect(cf
['global']['database']) as conn
:
57 #with conn.cursor() as c:
60 SELECT subscriptions.channel_id, name,
61 (subscribed_until < datetime('now')) AS obsolete
63 left JOIN channels ON channels.id = subscriptions.channel_id
64 left JOIN websub ON channels.id = websub.channel_id
66 AND subscriptions.type IN ('channel', 'playlist')
67 ORDER BY obsolete=0, name COLLATE NOCASE ASC""", (token
,))
69 'channel_id': channel_id
,
70 'author': author
or channel_id
,
71 'subscribed_until': subscribed_until
72 } for (channel_id
, author
, subscribed_until
) in c
.fetchall()]
73 return render_template('subscription_manager.html.j2', rows
=rows
)
75 @frontend.route('/feed/subreddits', methods
=['POST'])
78 return "reddit feed: TODO"
79 token
= current_user
.token
80 action
= next(request
.form
.keys(), None)
81 if action
in ['pin', 'unpin', 'hide']:
82 video_id
= request
.form
.get(action
)
88 with sqlite3
.connect(cf
['global']['database']) as conn
:
89 #with conn.cursor() as c:
92 INSERT OR REPLACE INTO flags (user, video_id, display)
94 """, (token
, video_id
, display
))
96 flash("unsupported action", "error")
97 return redirect(request
.url
, code
=303)
99 @frontend.route('/manage/subreddits', methods
=['POST'])
101 def manage_subscriptions():
102 return "reddit feed: TODO"
103 token
= current_user
.token
104 if 'subscribe' in request
.form
:
105 channel_id
= request
.form
.get("subscribe")
106 match
= re
.search(r
"(UC[A-Za-z0-9_-]{22})", channel_id
)
108 channel_id
= match
.group(1)
110 match
= re
.search(r
"((?:PL|LL|EC|UU|FL|UL|OL)[A-Za-z0-9_-]{10,})", channel_id
)
111 if match
: # NOTE: PL-playlists are 32chars, others differ in length.
112 flash("playlists not (yet?) supported.", "error")
113 return redirect(request
.url
, code
=303) # TODO: dedup redirection
115 flash("not a valid/subscribable URI", "error")
116 return redirect(request
.url
, code
=303) # TODO: dedup redirection
117 with sqlite3
.connect(cf
['global']['database']) as conn
:
118 #with conn.cursor() as c:
121 INSERT OR IGNORE INTO subscriptions (user, channel_id)
123 """, (token
, channel_id
))
124 # TODO: sql-error-handling, asynchronically calling update-subs.pl
126 elif 'unsubscribe' in request
.form
:
127 channel_id
= request
.form
.get("unsubscribe")
128 with sqlite3
.connect(cf
['global']['database']) as conn
:
129 #with conn.cursor() as c:
132 DELETE FROM subscriptions
133 WHERE user = ? AND channel_id = ?
134 """, (token
, channel_id
))
135 # TODO: sql-error-handling, report success
138 flash("unsupported action", "error")
140 return redirect(request
.url
, code
=303)
142 @frontend.route('/r/')
145 @frontend.route('/r/<subreddit>')
146 def reddit(subreddit
="videos"):
147 count
= int(request
.args
.get('count', 0))
148 before
= request
.args
.get('before')
149 after
= request
.args
.get('after')
150 query
= '&'.join([f
"{k}={v}" for k
,v
in [('count',count
), ('before',before
), ('after',after
)] if v
])
151 r
= requests
.get(f
"https://old.reddit.com/r/{subreddit}.json?{query}", headers
={'User-Agent':'Mozilla/5.0'})
152 if not r
.ok
or not 'data' in r
.json():
153 return r
.text
+"error retrieving reddit data", 502
155 good
= [e
for e
in r
.json()['data']['children'] if e
['data']['score'] > 1]
156 bad
= [e
for e
in r
.json()['data']['children'] if e
['data']['score'] <=1]
158 for entry
in (good
+bad
):
160 if e
['domain'] not in ['youtube.com', 'youtu.be', 'invidio.us']:
162 video_id
= re
.match(r
'^https?://(?:www.|m.)?(?:youtube.com/watch\?(?:.*&)?v=|youtu.be/|youtube.com/embed/)([-_0-9A-Za-z]+)', e
['url']).group(1)
163 if not video_id
: continue
165 'video_id': video_id
,
167 'url': e
['permalink'],
168 'n_comments': e
['num_comments'],
169 'n_karma': e
['score'],
171 before
= r
.json()['data']['before']
172 after
= r
.json()['data']['after']
173 return render_template('reddit.html.j2', subreddit
=subreddit
, rows
=videos
, before
=before
, after
=after
, count
=count
)