mirror of
https://github.com/nikdoof/test-auth.git
synced 2025-12-17 19:59:29 +00:00
Abstract out the backend API call system to a generic class, Added Flair management
This commit is contained in:
@@ -17,6 +17,74 @@ class NotLoggedIn(Exception):
|
|||||||
class LoginError(Exception):
|
class LoginError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
REDDIT = "http://www.reddit.com"
|
||||||
|
|
||||||
|
class RedditAPI:
|
||||||
|
"""
|
||||||
|
Generic class for authenticated Reddit API access
|
||||||
|
"""
|
||||||
|
|
||||||
|
REDDIT_API_LOGIN = "%s/api/login" % REDDIT
|
||||||
|
|
||||||
|
def __init__(self, username=None, password=None):
|
||||||
|
if username and password:
|
||||||
|
self.login(username, password)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _url(api, sr=None):
|
||||||
|
# Inspired by the offical reddit client
|
||||||
|
|
||||||
|
if api[0] == '/':
|
||||||
|
api = api[1:]
|
||||||
|
|
||||||
|
if sr:
|
||||||
|
url = '%s/r/%s/%s' % (REDDIT, sr, api)
|
||||||
|
else:
|
||||||
|
url = '%s/%s' % (REDDIT, api)
|
||||||
|
|
||||||
|
return '%s.json' % url
|
||||||
|
|
||||||
|
def login(self, username, password):
|
||||||
|
data = { 'user': username,
|
||||||
|
'passwd': password,
|
||||||
|
'api_type': 'json' }
|
||||||
|
url = "%s/%s" % (self.REDDIT_API_LOGIN, username)
|
||||||
|
|
||||||
|
jsondoc = self._request(url, data, method='POST')
|
||||||
|
|
||||||
|
if jsondoc and 'json' in jsondoc:
|
||||||
|
if 'data' in jsondoc['json']:
|
||||||
|
self.login_cookie = jsondoc['json']['data']['cookie']
|
||||||
|
self.modhash = jsondoc['json']['data']['modhash']
|
||||||
|
if self.login_cookie:
|
||||||
|
return True
|
||||||
|
elif 'errors' in jsondoc['json']:
|
||||||
|
raise LoginError(jsondoc['json']['errors'])
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
def _request(self, url, data, method='GET'):
|
||||||
|
if not hasattr(self, '_opener'):
|
||||||
|
self._opener = urllib2.build_opener(urllib2.HTTPCookieProcessor())
|
||||||
|
urllib2.install_opener(self._opener)
|
||||||
|
|
||||||
|
data = urllib.urlencode(data)
|
||||||
|
if method == 'GET':
|
||||||
|
if '?' in url:
|
||||||
|
url = '%s&%s' % (url, data)
|
||||||
|
else:
|
||||||
|
url = '%s?%s' % (url, data)
|
||||||
|
data = None
|
||||||
|
|
||||||
|
print url
|
||||||
|
resp = self._opener.open(urllib2.Request(url, data))
|
||||||
|
resptxt = resp.read()
|
||||||
|
if resp.info()['Content-Type'] == 'text/plain':
|
||||||
|
logging.info('returning plaintext')
|
||||||
|
return resptxt
|
||||||
|
return json.loads(resptxt)
|
||||||
|
|
||||||
|
|
||||||
class Comment(dict):
|
class Comment(dict):
|
||||||
""" Abstraction for comment data provided by JSON
|
""" Abstraction for comment data provided by JSON
|
||||||
Comments can be identifed by Kind = 1 """
|
Comments can be identifed by Kind = 1 """
|
||||||
@@ -63,7 +131,8 @@ class Message(dict):
|
|||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.__unicode__()
|
return self.__unicode__()
|
||||||
|
|
||||||
class Inbox():
|
|
||||||
|
class Inbox(RedditAPI):
|
||||||
"""
|
"""
|
||||||
Reddit Inbox class, accesses a user's inbox and provides a iterable
|
Reddit Inbox class, accesses a user's inbox and provides a iterable
|
||||||
list of messages
|
list of messages
|
||||||
@@ -74,33 +143,8 @@ class Inbox():
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
REDDIT = "http://www.reddit.com"
|
REDDIT_API_INBOX = '/message/inbox/'
|
||||||
REDDIT_API_LOGIN = "%s/api/login" % REDDIT
|
REDDIT_API_COMPOSE = '/api/compose/'
|
||||||
REDDIT_API_INBOX = "%s/message/inbox/.json?mark=false" % REDDIT
|
|
||||||
REDDIT_API_COMPOSE = "%s/api/compose/" % REDDIT
|
|
||||||
|
|
||||||
def __init__(self, username=None, password=None):
|
|
||||||
if username and password:
|
|
||||||
self.login(username, password)
|
|
||||||
|
|
||||||
def login(self, username, password):
|
|
||||||
data = { 'user': username,
|
|
||||||
'passwd': password,
|
|
||||||
'api_type': 'json' }
|
|
||||||
url = "%s/%s" % (self.REDDIT_API_LOGIN, username)
|
|
||||||
|
|
||||||
jsondoc = json.load(self._url_request(url, data))
|
|
||||||
|
|
||||||
if jsondoc and 'json' in jsondoc:
|
|
||||||
if 'data' in jsondoc['json']:
|
|
||||||
self.login_cookie = jsondoc['json']['data']['cookie']
|
|
||||||
self.modhash = jsondoc['json']['data']['modhash']
|
|
||||||
if self.login_cookie:
|
|
||||||
return True
|
|
||||||
elif 'errors' in jsondoc['json']:
|
|
||||||
raise LoginError(jsondoc['json']['errors'])
|
|
||||||
|
|
||||||
return False
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def _inbox_data(self):
|
def _inbox_data(self):
|
||||||
@@ -109,7 +153,7 @@ class Inbox():
|
|||||||
raise NotLoggedIn
|
raise NotLoggedIn
|
||||||
|
|
||||||
if not hasattr(self, '__inbox_cache') or not len(self.__inbox_cache):
|
if not hasattr(self, '__inbox_cache') or not len(self.__inbox_cache):
|
||||||
inbox = json.load(self._opener.open(self.REDDIT_API_INBOX))
|
inbox = self._request(self._url(self.REDDIT_API_INBOX), {'mark': 'false'}, method='GET')
|
||||||
|
|
||||||
if inbox and 'data' in inbox:
|
if inbox and 'data' in inbox:
|
||||||
self.__inbox_cache = []
|
self.__inbox_cache = []
|
||||||
@@ -120,14 +164,6 @@ class Inbox():
|
|||||||
|
|
||||||
return self.__inbox_cache
|
return self.__inbox_cache
|
||||||
|
|
||||||
def _url_request(self, url, data):
|
|
||||||
if not hasattr(self, '_opener'):
|
|
||||||
self._opener = urllib2.build_opener(urllib2.HTTPCookieProcessor())
|
|
||||||
urllib2.install_opener(self._opener)
|
|
||||||
|
|
||||||
req = urllib2.Request(url, urllib.urlencode(data))
|
|
||||||
return self._opener.open(req)
|
|
||||||
|
|
||||||
def __len__(self):
|
def __len__(self):
|
||||||
return len(self._inbox_data)
|
return len(self._inbox_data)
|
||||||
|
|
||||||
@@ -146,6 +182,47 @@ class Inbox():
|
|||||||
'text': text.encode('utf-8'),
|
'text': text.encode('utf-8'),
|
||||||
'uh': self.modhash,
|
'uh': self.modhash,
|
||||||
'thing_id': '' }
|
'thing_id': '' }
|
||||||
url = "%s" % (self.REDDIT_API_COMPOSE)
|
url = self._url(self.REDDIT_API_COMPOSE)
|
||||||
|
jsondoc = self._request(url, data, method='POST')
|
||||||
|
|
||||||
jsondoc = json.load(self._url_request(url, data))
|
|
||||||
|
class Flair(RedditAPI):
|
||||||
|
"""
|
||||||
|
Manages a subreddit's flair list
|
||||||
|
"""
|
||||||
|
|
||||||
|
REDDIT_API_FLAIR = "/api/flair"
|
||||||
|
REDDIT_API_FLAIRLIST = "/api/flairlist"
|
||||||
|
|
||||||
|
def flairlist(self, subreddit, start=None):
|
||||||
|
|
||||||
|
if not self.login_cookie:
|
||||||
|
raise NotLoggedIn
|
||||||
|
|
||||||
|
data = { 'r': subreddit, 'limit': 1000, 'uh': self.modhash }
|
||||||
|
if start: data['after'] = start
|
||||||
|
url = self._url(self.REDDIT_API_FLAIRLIST, subreddit)
|
||||||
|
|
||||||
|
jsondoc = self._request(url, data)
|
||||||
|
users = jsondoc['users']
|
||||||
|
|
||||||
|
if len(users) == 1000:
|
||||||
|
# Assume we have more to get
|
||||||
|
users.extend(self.flairlist(subreddit, jsondoc['next']))
|
||||||
|
return users
|
||||||
|
|
||||||
|
def clear_flair(self, subreddit, user):
|
||||||
|
"""
|
||||||
|
Clears a user's flair
|
||||||
|
"""
|
||||||
|
return self.set_flair(subreddit, user, '', '')
|
||||||
|
|
||||||
|
def set_flair(self, subreddit, user, text, css_class):
|
||||||
|
|
||||||
|
data = { 'r': subreddit, 'name': user, 'uh': self.modhash, 'text': text, 'css_class': css_class }
|
||||||
|
url = self._url(self.REDDIT_API_FLAIR)
|
||||||
|
jsondoc = self._request(url, data, method='POST')
|
||||||
|
|
||||||
|
if jsondoc:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|||||||
Reference in New Issue
Block a user