1- import asyncio
2- import functools
31import random
42import re
53import urllib .parse
1210
1311reddit_re = re .compile (r'.*(((www\.)?reddit\.com/r|redd\.it)[^ ]+)' , re .I )
1412
15- base_url = "http://reddit.com/r/{}/.json "
13+ base_url = "http://reddit.com/r/{}"
1614short_url = "http://redd.it/{}"
1715
1816
17+ def api_request (url , bot ):
18+ url = url .rstrip ('/' ) + "/.json"
19+ r = requests .get (url , headers = {'User-Agent' : bot .user_agent })
20+ r .raise_for_status ()
21+ return r .json ()
22+
23+
1924def format_output (item , show_url = False ):
2025 """ takes a reddit post and returns a formatted string """
2126 item ["title" ] = formatting .truncate (item ["title" ], 70 )
@@ -40,74 +45,60 @@ def format_output(item, show_url=False):
4045 " - \x02 {author}\x02 , {timesince} ago{warning}" .format (** item )
4146
4247
43- @hook .regex (reddit_re )
48+ @hook .regex (reddit_re , singlethread = True )
4449def reddit_url (match , bot ):
4550 url = match .group (1 )
46- url = url .rstrip ('/' ) # Remove any trailing '/'
4751
4852 if "redd.it" in url :
4953 url = "https://" + url
5054 response = requests .get (url )
5155 response .raise_for_status ()
52- url = response .url . rstrip ( '/' ) + "/.json"
56+ url = response .url
5357
5458 if not urllib .parse .urlparse (url ).scheme :
55- url = "https://" + url + "/.json"
56-
57- # the reddit API gets grumpy if we don't include headers
58- headers = {'User-Agent' : bot .user_agent }
59- r = requests .get (url , headers = headers )
60- r .raise_for_status ()
59+ url = "https://" + url
6160
62- data = r . json ( )
61+ data = api_request ( url , bot )
6362 item = data [0 ]["data" ]["children" ][0 ]["data" ]
6463
6564 return format_output (item )
6665
6766
68- @asyncio .coroutine
69- @hook .command (autohelp = False )
70- def reddit (text , bot , loop , reply ):
67+ @hook .command (autohelp = False , singlethread = True )
68+ def reddit (text , bot , reply ):
7169 """<subreddit> [n] - gets a random post from <subreddit>, or gets the [n]th post in the subreddit"""
7270 id_num = None
73- headers = {'User-Agent' : bot .user_agent }
7471
7572 if text :
7673 # clean and split the input
7774 parts = text .lower ().strip ().split ()
75+ url = base_url .format (parts .pop (0 ).strip ())
7876
7977 # find the requested post number (if any)
80- if len (parts ) > 1 :
81- url = base_url .format (parts [0 ].strip ())
78+ if parts :
8279 try :
8380 id_num = int (parts [1 ]) - 1
8481 except ValueError :
8582 return "Invalid post number."
86- else :
87- url = base_url .format (parts [0 ].strip ())
8883 else :
89- url = "http://reddit.com/.json "
84+ url = "http://reddit.com"
9085
9186 try :
92- # Again, identify with Reddit using an User Agent, otherwise get a 429
93- inquiry = yield from loop .run_in_executor (None , functools .partial (requests .get , url , headers = headers ))
94- inquiry .raise_for_status ()
95- if inquiry .status_code != 200 :
96- return "r/{} either does not exist or is private." .format (text )
97- data = inquiry .json ()
87+ data = api_request (url , bot )
9888 except Exception as e :
9989 reply ("Error: " + str (e ))
10090 raise
91+
10192 data = data ["data" ]["children" ]
10293
10394 # get the requested/random post
10495 if id_num is not None :
10596 try :
106- item = data [id_num ][ "data" ]
97+ item = data [id_num ]
10798 except IndexError :
10899 length = len (data )
109100 return "Invalid post number. Number must be between 1 and {}." .format (length )
110101 else :
111- item = random .choice (data )[ "data" ]
102+ item = random .choice (data )
112103
113- return format_output (item , show_url = True )
104+ return format_output (item [ "data" ] , show_url = True )
0 commit comments